From 2b8200409c90ffd169db19aa13c53dc95062ed3f Mon Sep 17 00:00:00 2001 From: aymeric Date: Thu, 4 Sep 2008 15:47:34 +0000 Subject: [PATCH] Initial import git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@1 3f6dc0c8-ddfe-455d-9043-3cd528dc4637 --- linphone/.cvsignore | 24 + linphone/ABOUT-NLS | 1101 +++ linphone/AUTHORS | 57 + linphone/BUGS | 9 + linphone/COPYING | 340 + linphone/ChangeLog | 513 ++ linphone/INSTALL | 236 + linphone/Makefile.am | 42 + linphone/NEWS | 75 + linphone/README | 53 + linphone/README.CVS | 12 + linphone/README.M68k.txt | 93 + linphone/README.arm | 106 + linphone/TODO | 22 + linphone/autogen.sh | 26 + linphone/build.mk | 140 + linphone/config.rpath | 614 ++ linphone/configure.in | 378 + linphone/console/.cvsignore | 7 + linphone/console/Makefile.am | 37 + linphone/console/TODO | 20 + linphone/console/commands.c | 1236 ++++ linphone/console/example/linphonec | 51 + linphone/console/linphonec.c | 1114 +++ linphone/console/linphonec.h | 134 + linphone/console/sipomatic.c | 467 ++ linphone/console/sipomatic.h | 96 + linphone/console/wav2raw.c | 67 + linphone/coreapi/.cvsignore | 7 + linphone/coreapi/Makefile.am | 46 + linphone/coreapi/authentication.c | 273 + linphone/coreapi/chat.c | 109 + linphone/coreapi/enum.c | 172 + linphone/coreapi/enum.h | 35 + linphone/coreapi/exevents.c | 1012 +++ linphone/coreapi/exevents.h | 40 + linphone/coreapi/friend.c | 736 ++ linphone/coreapi/general_state.c | 101 + linphone/coreapi/linphonecore.c | 2261 ++++++ linphone/coreapi/linphonecore.h | 715 ++ linphone/coreapi/lpconfig.c | 354 + linphone/coreapi/lpconfig.h | 48 + linphone/coreapi/misc.c | 450 ++ linphone/coreapi/presence.c | 208 + linphone/coreapi/private.h | 121 + linphone/coreapi/proxy.c | 512 ++ linphone/coreapi/sdphandler.c | 682 ++ linphone/coreapi/sdphandler.h | 101 + linphone/debian/.cvsignore | 2 + linphone/debian/Makefile.am | 15 + linphone/debian/control | 14 + linphone/debian/copyright | 10 + linphone/debian/dirs | 2 + linphone/debian/docs | 3 + linphone/debian/manpage.1.ex | 60 + linphone/debian/manpage.sgml.ex | 152 + linphone/debian/menu | 3 + linphone/debian/rules | 107 + linphone/debian/watch.ex | 5 + linphone/developer-docs/.cvsignore | 2 + .../developer-docs/mediastreamer/.cvsignore | 2 + linphone/exosip/.cvsignore | 6 + linphone/exosip/Makefile.am | 16 + linphone/exosip/eXosip.c | 3192 +++++++++ linphone/exosip/eXosip.h | 752 ++ linphone/exosip/eXosip2.h | 510 ++ linphone/exosip/eXosip_cfg.h | 150 + linphone/exosip/eXutils.c | 278 + linphone/exosip/exosip.dev | 289 + linphone/exosip/jauth.c | 453 ++ linphone/exosip/jcall.c | 122 + linphone/exosip/jcallback.c | 1972 ++++++ linphone/exosip/jdialog.c | 209 + linphone/exosip/jevents.c | 949 +++ linphone/exosip/jfreinds.c | 311 + linphone/exosip/jidentity.c | 277 + linphone/exosip/jnotify.c | 528 ++ linphone/exosip/jpipe.c | 221 + linphone/exosip/jpipe.h | 111 + linphone/exosip/jpublish.c | 118 + linphone/exosip/jreg.c | 106 + linphone/exosip/jrequest.c | 1158 ++++ linphone/exosip/jresponse.c | 1264 ++++ linphone/exosip/jsubscribe.c | 231 + linphone/exosip/jsubscribers.c | 185 + linphone/exosip/misc.c | 436 ++ linphone/exosip/sdp_offans.c | 333 + linphone/exosip/udp.c | 2635 +++++++ linphone/gnome/.cvsignore | 8 + .../gnome/GNOME_LinphoneApplet.server.in.in | 32 + linphone/gnome/GNOME_LinphoneApplet.xml | 7 + linphone/gnome/Makefile.am | 80 + linphone/gnome/addressbook.c | 306 + linphone/gnome/addressbook.h | 28 + linphone/gnome/applet.c | 182 + linphone/gnome/callbacks.c | 695 ++ linphone/gnome/callbacks.h | 540 ++ linphone/gnome/friends.c | 127 + linphone/gnome/friends.h | 29 + linphone/gnome/gui_utils.c | 102 + linphone/gnome/gui_utils.h | 33 + linphone/gnome/interface.c | 2919 ++++++++ linphone/gnome/interface.h | 15 + linphone/gnome/linphone.c | 449 ++ linphone/gnome/linphone.h | 66 + linphone/gnome/main.c | 70 + linphone/gnome/presence.c | 150 + linphone/gnome/presence.h | 43 + linphone/gnome/propertybox.c | 1065 +++ linphone/gnome/propertybox.h | 96 + linphone/gnome/support.c | 115 + linphone/gnome/support.h | 49 + linphone/gsmlib/.cvsignore | 6 + linphone/gsmlib/COPYRIGHT | 16 + linphone/gsmlib/ChangeLog | 80 + linphone/gsmlib/ChangeLog.orig | 0 linphone/gsmlib/INSTALL | 99 + linphone/gsmlib/MACHINES | 11 + linphone/gsmlib/MANIFEST | 59 + linphone/gsmlib/Makefile.am | 26 + linphone/gsmlib/README | 37 + linphone/gsmlib/code.c | 99 + linphone/gsmlib/config.h | 37 + linphone/gsmlib/debug.c | 76 + linphone/gsmlib/decode.c | 63 + linphone/gsmlib/gsm.h | 96 + linphone/gsmlib/gsm_create.c | 45 + linphone/gsmlib/gsm_decode.c | 361 + linphone/gsmlib/gsm_destroy.c | 26 + linphone/gsmlib/gsm_encode.c | 451 ++ linphone/gsmlib/gsm_explode.c | 417 ++ linphone/gsmlib/gsm_implode.c | 515 ++ linphone/gsmlib/gsm_option.c | 69 + linphone/gsmlib/gsm_print.c | 167 + linphone/gsmlib/gsm_wrapper.c | 67 + linphone/gsmlib/gsm_wrapper.h | 28 + linphone/gsmlib/gsmadd.c | 235 + linphone/gsmlib/long_term.c | 949 +++ linphone/gsmlib/lpc.c | 341 + linphone/gsmlib/preprocess.c | 113 + linphone/gsmlib/private.h | 268 + linphone/gsmlib/proto.h | 65 + linphone/gsmlib/rpe.c | 488 ++ linphone/gsmlib/short_term.c | 429 ++ linphone/gsmlib/table.c | 63 + linphone/gsmlib/toast.h | 109 + linphone/gsmlib/unproto.h | 23 + linphone/gtk-glade/Makefile.am | 57 + linphone/gtk-glade/about.glade | 61 + linphone/gtk-glade/call_logs.glade | 66 + linphone/gtk-glade/calllogs.c | 68 + linphone/gtk-glade/chat.c | 108 + linphone/gtk-glade/chatroom.glade | 100 + linphone/gtk-glade/contact.glade | 179 + linphone/gtk-glade/friendlist.c | 454 ++ linphone/gtk-glade/gtk-linphone.glade | 2417 +++++++ linphone/gtk-glade/incoming_call.glade | 140 + linphone/gtk-glade/linphone.dev | 165 + linphone/gtk-glade/linphone.h | 53 + linphone/gtk-glade/linphone.iss | 69 + linphone/gtk-glade/linphone.png | Bin 0 -> 11971 bytes linphone/gtk-glade/linphone2.png | Bin 0 -> 5485 bytes linphone/gtk-glade/log.glade | 71 + linphone/gtk-glade/logging.c | 125 + linphone/gtk-glade/main.c | 725 ++ linphone/gtk-glade/main.glade | 804 +++ linphone/gtk-glade/parameters.glade | 1393 ++++ linphone/gtk-glade/password.glade | 89 + linphone/gtk-glade/propertybox.c | 648 ++ linphone/gtk-glade/sip_account.glade | 220 + linphone/gtk-glade/stock_people.png | Bin 0 -> 764 bytes linphone/gtk-glade/support.c | 103 + linphone/gtk/.cvsignore | 5 + .../gtk/GNOME_LinphoneApplet.server.in.in | 32 + linphone/gtk/GNOME_LinphoneApplet.xml | 7 + linphone/gtk/Makefile.am | 77 + linphone/gtk/addressbook.c | 306 + linphone/gtk/addressbook.h | 28 + linphone/gtk/applet.c | 185 + linphone/gtk/callbacks.c | 707 ++ linphone/gtk/callbacks.h | 545 ++ linphone/gtk/friends.c | 127 + linphone/gtk/friends.h | 29 + linphone/gtk/gui_utils.c | 102 + linphone/gtk/gui_utils.h | 33 + linphone/gtk/interface.c | 3045 ++++++++ linphone/gtk/interface.h | 16 + linphone/gtk/linphone.c | 482 ++ linphone/gtk/linphone.h | 68 + linphone/gtk/main.c | 74 + linphone/gtk/presence.c | 150 + linphone/gtk/presence.h | 43 + linphone/gtk/propertybox.c | 1107 +++ linphone/gtk/propertybox.h | 96 + linphone/gtk/support.c | 144 + linphone/gtk/support.h | 69 + linphone/intl/ChangeLog | 4 + linphone/intl/Makefile.in | 337 + linphone/intl/VERSION | 1 + linphone/intl/bindtextdom.c | 369 + linphone/intl/cat-compat.c | 262 + linphone/intl/dcgettext.c | 59 + linphone/intl/dgettext.c | 59 + linphone/intl/explodename.c | 192 + linphone/intl/finddomain.c | 198 + linphone/intl/gettext.c | 64 + linphone/intl/gettext.h | 102 + linphone/intl/gettextP.h | 242 + linphone/intl/hash-string.h | 59 + linphone/intl/intl-compat.c | 131 + linphone/intl/l10nflist.c | 453 ++ linphone/intl/libgettext.h | 49 + linphone/intl/linux-msg.sed | 100 + linphone/intl/loadinfo.h | 156 + linphone/intl/loadmsgcat.c | 1316 ++++ linphone/intl/localealias.c | 419 ++ linphone/intl/po2tbl.sed.in | 102 + linphone/intl/textdomain.c | 142 + linphone/intl/xopen-msg.sed | 104 + linphone/intltool-extract.in | 325 + linphone/intltool-merge.in | 657 ++ linphone/intltool-update.in | 634 ++ linphone/ipkg/.cvsignore | 3 + linphone/ipkg/Makefile.am | 1 + linphone/ipkg/glib.control | 8 + linphone/ipkg/ipaq-config.site | 89 + linphone/ipkg/libosip.control | 8 + linphone/ipkg/linphone.control.in | 8 + linphone/linphone.kdevprj | 2285 ++++++ linphone/linphone.spec.in | 258 + linphone/linphone2-gtk.glade | 3788 ++++++++++ linphone/linphone2.glade | 6127 +++++++++++++++++ linphone/lpc10-1.5/.cvsignore | 6 + linphone/lpc10-1.5/FAQ | 102 + linphone/lpc10-1.5/Makefile.am | 49 + linphone/lpc10-1.5/README | 81 + linphone/lpc10-1.5/README-1.0 | 47 + linphone/lpc10-1.5/README.new | 89 + linphone/lpc10-1.5/analys.c | 617 ++ linphone/lpc10-1.5/bitio.c | 20 + linphone/lpc10-1.5/bsynz.c | 423 ++ linphone/lpc10-1.5/chanwr.c | 225 + linphone/lpc10-1.5/dcbias.c | 95 + linphone/lpc10-1.5/decode.c | 589 ++ linphone/lpc10-1.5/deemp.c | 142 + linphone/lpc10-1.5/difmag.c | 121 + linphone/lpc10-1.5/dyptrk.c | 387 ++ linphone/lpc10-1.5/encode.c | 349 + linphone/lpc10-1.5/energy.c | 91 + linphone/lpc10-1.5/f2c.h | 260 + linphone/lpc10-1.5/f2clib.c | 82 + linphone/lpc10-1.5/ham84.c | 114 + linphone/lpc10-1.5/hp100.c | 157 + linphone/lpc10-1.5/invert.c | 175 + linphone/lpc10-1.5/irc2pc.c | 133 + linphone/lpc10-1.5/ivfilt.c | 118 + linphone/lpc10-1.5/lpc10.h | 228 + linphone/lpc10-1.5/lpc10_wrapper.c | 229 + linphone/lpc10-1.5/lpc10_wrapper.h | 34 + linphone/lpc10-1.5/lpcdec.c | 273 + linphone/lpc10-1.5/lpcenc.c | 163 + linphone/lpc10-1.5/lpcini.c | 399 ++ linphone/lpc10-1.5/lpfilt.c | 113 + linphone/lpc10-1.5/median.c | 77 + linphone/lpc10-1.5/mload.c | 151 + linphone/lpc10-1.5/onset.c | 306 + linphone/lpc10-1.5/pitsyn.c | 556 ++ linphone/lpc10-1.5/placea.c | 218 + linphone/lpc10-1.5/placev.c | 257 + linphone/lpc10-1.5/preemp.c | 132 + linphone/lpc10-1.5/prepro.c | 105 + linphone/lpc10-1.5/random.c | 113 + linphone/lpc10-1.5/rcchk.c | 107 + linphone/lpc10-1.5/synths.c | 392 ++ linphone/lpc10-1.5/tbdm.c | 176 + linphone/lpc10-1.5/voicin.c | 759 ++ linphone/lpc10-1.5/vparms.c | 243 + linphone/m4/.cvsignore | 2 + linphone/m4/Makefile.am | 2 + linphone/m4/codeset.m4 | 21 + linphone/m4/exosip.m4 | 32 + linphone/m4/gettext.m4 | 419 ++ linphone/m4/glibc2.m4 | 30 + linphone/m4/glibc21.m4 | 30 + linphone/m4/iconv.m4 | 101 + linphone/m4/ilbc.m4 | 33 + linphone/m4/intdiv0.m4 | 70 + linphone/m4/intl.m4 | 259 + linphone/m4/intldir.m4 | 19 + linphone/m4/intmax.m4 | 33 + linphone/m4/inttypes-pri.m4 | 36 + linphone/m4/inttypes.m4 | 25 + linphone/m4/inttypes_h.m4 | 26 + linphone/m4/isc-posix.m4 | 24 + linphone/m4/lcmessage.m4 | 30 + linphone/m4/lib-ld.m4 | 110 + linphone/m4/lib-link.m4 | 644 ++ linphone/m4/lib-prefix.m4 | 185 + linphone/m4/lock.m4 | 311 + linphone/m4/longdouble.m4 | 31 + linphone/m4/longlong.m4 | 48 + linphone/m4/nls.m4 | 31 + linphone/m4/ortp.m4 | 16 + linphone/m4/osip.m4 | 54 + linphone/m4/po.m4 | 428 ++ linphone/m4/printf-posix.m4 | 44 + linphone/m4/progtest.m4 | 92 + linphone/m4/readline.m4 | 37 + linphone/m4/signed.m4 | 17 + linphone/m4/size_max.m4 | 62 + linphone/m4/stdint_h.m4 | 26 + linphone/m4/uintmax_t.m4 | 30 + linphone/m4/ulonglong.m4 | 48 + linphone/m4/video.m4 | 89 + linphone/m4/visibility.m4 | 52 + linphone/m4/wchar_t.m4 | 20 + linphone/m4/wint_t.m4 | 20 + linphone/m4/xsize.m4 | 13 + linphone/make_exosip.sh | 22 + linphone/media_api/.cvsignore | 3 + linphone/media_api/DESIGN.txt | 135 + linphone/media_api/Makefile.am | 31 + linphone/media_api/apitest.c | 36 + linphone/media_api/apitest.h | 0 linphone/media_api/basiccall.c | 170 + linphone/media_api/basiccall.h | 51 + linphone/media_api/callmember.c | 153 + linphone/media_api/callmember.h | 59 + linphone/media_api/ccl | 1 + linphone/media_api/common.h | 31 + linphone/media_api/media_api.c | 69 + linphone/media_api/media_api.h | 69 + linphone/media_api/mediaflow.c | 179 + linphone/media_api/mediaflow.h | 68 + linphone/mediastreamer/.cvsignore | 16 + linphone/mediastreamer/Makefile.am | 174 + linphone/mediastreamer/Makefile.ms | 34 + linphone/mediastreamer/README | 3 + linphone/mediastreamer/affine.c | 144 + linphone/mediastreamer/affine.h | 43 + linphone/mediastreamer/alsacard.c | 653 ++ linphone/mediastreamer/alsacard.h | 50 + linphone/mediastreamer/audiostream.c | 340 + linphone/mediastreamer/g711common.h | 171 + linphone/mediastreamer/hpuxsndcard.c | 301 + linphone/mediastreamer/jackcard.c | 574 ++ linphone/mediastreamer/jackcard.h | 81 + linphone/mediastreamer/mediastream.c | 144 + linphone/mediastreamer/mediastream.h | 133 + linphone/mediastreamer/ms.c | 394 ++ linphone/mediastreamer/ms.h | 81 + linphone/mediastreamer/msAlawdec.c | 132 + linphone/mediastreamer/msAlawdec.h | 65 + linphone/mediastreamer/msAlawenc.c | 124 + linphone/mediastreamer/msAlawenc.h | 64 + linphone/mediastreamer/msGSMdecoder.c | 116 + linphone/mediastreamer/msGSMdecoder.h | 64 + linphone/mediastreamer/msGSMencoder.c | 98 + linphone/mediastreamer/msGSMencoder.h | 61 + linphone/mediastreamer/msLPC10decoder.c | 129 + linphone/mediastreamer/msLPC10decoder.h | 64 + linphone/mediastreamer/msLPC10encoder.c | 251 + linphone/mediastreamer/msLPC10encoder.h | 74 + linphone/mediastreamer/msMUlawdec.c | 130 + linphone/mediastreamer/msMUlawdec.h | 66 + linphone/mediastreamer/msMUlawenc.c | 99 + linphone/mediastreamer/msMUlawenc.h | 63 + linphone/mediastreamer/msavdecoder.c | 294 + linphone/mediastreamer/msavdecoder.h | 87 + linphone/mediastreamer/msavencoder.c | 258 + linphone/mediastreamer/msavencoder.h | 92 + linphone/mediastreamer/msbuffer.c | 91 + linphone/mediastreamer/msbuffer.h | 78 + linphone/mediastreamer/mscodec.c | 259 + linphone/mediastreamer/mscodec.h | 67 + linphone/mediastreamer/mscopy.c | 96 + linphone/mediastreamer/mscopy.h | 61 + linphone/mediastreamer/msfdispatcher.c | 94 + linphone/mediastreamer/msfdispatcher.h | 61 + linphone/mediastreamer/msfifo.c | 167 + linphone/mediastreamer/msfifo.h | 73 + linphone/mediastreamer/msfilter.c | 537 ++ linphone/mediastreamer/msfilter.h | 202 + linphone/mediastreamer/msnosync.c | 82 + linphone/mediastreamer/msnosync.h | 60 + linphone/mediastreamer/msossread.c | 150 + linphone/mediastreamer/msossread.h | 77 + linphone/mediastreamer/msosswrite.c | 249 + linphone/mediastreamer/msosswrite.h | 78 + linphone/mediastreamer/msqdispatcher.c | 91 + linphone/mediastreamer/msqdispatcher.h | 60 + linphone/mediastreamer/msqueue.c | 58 + linphone/mediastreamer/msqueue.h | 51 + linphone/mediastreamer/msread.c | 186 + linphone/mediastreamer/msread.h | 80 + linphone/mediastreamer/msringplayer.c | 255 + linphone/mediastreamer/msringplayer.h | 81 + linphone/mediastreamer/msrtprecv.c | 182 + linphone/mediastreamer/msrtprecv.h | 82 + linphone/mediastreamer/msrtpsend.c | 213 + linphone/mediastreamer/msrtpsend.h | 85 + linphone/mediastreamer/mssdlout.c | 303 + linphone/mediastreamer/mssdlout.h | 64 + linphone/mediastreamer/mssmpeg.c | 181 + linphone/mediastreamer/mssmpeg.h | 70 + linphone/mediastreamer/mssoundread.c | 38 + linphone/mediastreamer/mssoundread.h | 80 + linphone/mediastreamer/mssoundwrite.c | 38 + linphone/mediastreamer/mssoundwrite.h | 80 + linphone/mediastreamer/msspeexdec.c | 215 + linphone/mediastreamer/msspeexdec.h | 69 + linphone/mediastreamer/msspeexenc.c | 187 + linphone/mediastreamer/msspeexenc.h | 66 + linphone/mediastreamer/mssync.c | 194 + linphone/mediastreamer/mssync.h | 136 + linphone/mediastreamer/mstcpclient.c | 137 + linphone/mediastreamer/mstcpclient.h | 50 + linphone/mediastreamer/mstcpserv.c | 174 + linphone/mediastreamer/mstcpserv.h | 33 + linphone/mediastreamer/mstimer.c | 114 + linphone/mediastreamer/mstimer.h | 68 + linphone/mediastreamer/mstruespeechdecoder.c | 152 + linphone/mediastreamer/mstruespeechdecoder.h | 55 + linphone/mediastreamer/mstruespeechencoder.c | 161 + linphone/mediastreamer/mstruespeechencoder.h | 62 + linphone/mediastreamer/msutils.h | 61 + linphone/mediastreamer/msv4l.c | 522 ++ linphone/mediastreamer/msv4l.h | 92 + linphone/mediastreamer/msvideooutput.c | 495 ++ linphone/mediastreamer/msvideooutput.h | 86 + linphone/mediastreamer/msvideosource.c | 99 + linphone/mediastreamer/msvideosource.h | 74 + linphone/mediastreamer/mswrite.c | 129 + linphone/mediastreamer/mswrite.h | 63 + linphone/mediastreamer/msxine.c | 189 + linphone/mediastreamer/msxine.h | 69 + linphone/mediastreamer/osscard.c | 498 ++ linphone/mediastreamer/osscard.h | 47 + linphone/mediastreamer/rfc2429.h | 46 + linphone/mediastreamer/ring_test.c | 63 + linphone/mediastreamer/sndcard.c | 209 + linphone/mediastreamer/sndcard.h | 145 + linphone/mediastreamer/test.c | 91 + linphone/mediastreamer/test_alaw.c | 90 + linphone/mediastreamer/test_gsm.c | 85 + linphone/mediastreamer/test_lpc10.c | 89 + linphone/mediastreamer/test_mulaw.c | 87 + linphone/mediastreamer/test_rtprecv.c | 99 + linphone/mediastreamer/test_smpeg.c | 70 + linphone/mediastreamer/test_speex.c | 88 + linphone/mediastreamer/test_truespeech.c | 91 + linphone/mediastreamer/test_v4l.c | 32 + linphone/mediastreamer/test_videostream.c | 45 + linphone/mediastreamer/test_xine.c | 45 + linphone/mediastreamer/videoclient.c | 60 + linphone/mediastreamer/videoserver.c | 56 + linphone/mediastreamer/videostream.c | 346 + linphone/mediastreamer/waveheader.h | 111 + linphone/mediastreamer2/.cvsignore | 30 + linphone/mediastreamer2/.indent.pro | 4 + linphone/mediastreamer2/AUTHORS | 1 + linphone/mediastreamer2/COPYING | 340 + linphone/mediastreamer2/ChangeLog | 0 linphone/mediastreamer2/INSTALL | 236 + linphone/mediastreamer2/Makefile.am | 54 + linphone/mediastreamer2/Makefile.macosx | 76 + linphone/mediastreamer2/NEWS | 23 + linphone/mediastreamer2/README | 94 + linphone/mediastreamer2/acinclude.m4 | 121 + linphone/mediastreamer2/autogen.sh | 19 + linphone/mediastreamer2/build/.cvsignore | 2 + linphone/mediastreamer2/build/Makefile.am | 1 + .../build/win32-novideo/.cvsignore | 2 + .../build/win32-novideo/Makefile.am | 2 + .../build/win32-novideo/alldescs.h | 66 + .../build/win32-novideo/mediastream.dev | 59 + .../build/win32-novideo/mediastream.vcproj | 143 + .../build/win32-novideo/mediastreamer2.def | 70 + .../build/win32-novideo/mediastreamer2.dev | 419 ++ .../build/win32-novideo/mediastreamer2.vcproj | 371 + .../build/win32native/.cvsignore | 2 + .../build/win32native/Makefile.am | 2 + .../build/win32native/alldescs.h | 90 + .../build/win32native/mediastream.dev | 72 + .../build/win32native/mediastream.vcproj | 211 + .../build/win32native/mediastreamer2.def | 99 + .../build/win32native/mediastreamer2.dev | 603 ++ .../build/win32native/mediastreamer2.vcproj | 448 ++ .../build/win32native/videodisplay.vcproj | 199 + .../mediastreamer2/build/wince/.cvsignore | 2 + .../mediastreamer2/build/wince/Makefile.am | 2 + .../mediastreamer2/build/wince/alldescs.h | 62 + .../build/wince/mediastreamer2.def | 52 + .../build/wince/mediastreamer2.vcproj | 1017 +++ linphone/mediastreamer2/configure.ac | 482 ++ linphone/mediastreamer2/help/DoxyFile.in | 233 + linphone/mediastreamer2/help/Makefile.am | 4 + linphone/mediastreamer2/help/doxygen.dox.in | 187 + .../mediastreamer2/help/ht0-buildagraph.dox | 153 + linphone/mediastreamer2/include/.cvsignore | 2 + linphone/mediastreamer2/include/Makefile.am | 1 + .../include/mediastreamer2/.cvsignore | 2 + .../include/mediastreamer2/Makefile.am | 26 + .../include/mediastreamer2/allfilters.h | 88 + .../include/mediastreamer2/dtmfgen.h | 29 + .../include/mediastreamer2/ice.h | 74 + .../include/mediastreamer2/mediastream.h | 155 + .../include/mediastreamer2/mscommon.h | 210 + .../include/mediastreamer2/msfileplayer.h | 43 + .../include/mediastreamer2/msfilerec.h | 33 + .../include/mediastreamer2/msfilter.h | 405 ++ .../include/mediastreamer2/msqueue.h | 113 + .../include/mediastreamer2/msrtp.h | 48 + .../include/mediastreamer2/mssndcard.h | 357 + .../include/mediastreamer2/mstee.h | 30 + .../include/mediastreamer2/msticker.h | 145 + .../include/mediastreamer2/msv4l.h | 30 + .../include/mediastreamer2/msvideo.h | 117 + .../include/mediastreamer2/msvideoout.h | 93 + .../include/mediastreamer2/msvolume.h | 30 + .../include/mediastreamer2/mswebcam.h | 226 + .../include/mediastreamer2/rfc3984.h | 60 + .../include/mediastreamer2/waveheader.h | 90 + linphone/mediastreamer2/mediastreamer.pc.in | 11 + .../mediastreamer2/mediastreamer2.spec.in | 81 + linphone/mediastreamer2/pkg.list | 43 + linphone/mediastreamer2/plugins/.cvsignore | 3 + .../mediastreamer2/plugins/msilbc/AUTHORS | 0 .../mediastreamer2/plugins/msilbc/COPYING | 340 + .../mediastreamer2/plugins/msilbc/ChangeLog | 0 .../mediastreamer2/plugins/msilbc/INSTALL | 236 + .../mediastreamer2/plugins/msilbc/Makefile.am | 11 + linphone/mediastreamer2/plugins/msilbc/NEWS | 0 linphone/mediastreamer2/plugins/msilbc/README | 13 + .../plugins/msilbc/configure.ac | 152 + .../plugins/msilbc/ilbc-rfc3951.tar.gz | Bin 0 -> 330306 bytes linphone/mediastreamer2/plugins/msilbc/ilbc.c | 283 + .../mediastreamer2/plugins/msx264/AUTHORS | 1 + .../mediastreamer2/plugins/msx264/COPYING | 340 + .../mediastreamer2/plugins/msx264/ChangeLog | 0 .../mediastreamer2/plugins/msx264/INSTALL | 237 + .../mediastreamer2/plugins/msx264/Makefile.am | 3 + linphone/mediastreamer2/plugins/msx264/NEWS | 2 + linphone/mediastreamer2/plugins/msx264/README | 17 + .../mediastreamer2/plugins/msx264/autogen.sh | 20 + .../plugins/msx264/configure.ac | 143 + .../mediastreamer2/plugins/msx264/msx264.dev | 95 + .../mediastreamer2/plugins/msx264/msx264.iss | 35 + .../plugins/msx264/src/Makefile.am | 6 + .../plugins/msx264/src/msx264.c | 517 ++ linphone/mediastreamer2/src/.cvsignore | 8 + linphone/mediastreamer2/src/Makefile.am | 136 + linphone/mediastreamer2/src/alaw.c | 222 + linphone/mediastreamer2/src/alsa.c | 948 +++ linphone/mediastreamer2/src/arts.c | 205 + linphone/mediastreamer2/src/audiostream.c | 426 ++ linphone/mediastreamer2/src/dtmfgen.c | 204 + linphone/mediastreamer2/src/dxfilter.cpp | 880 +++ linphone/mediastreamer2/src/dxfilter.h | 231 + linphone/mediastreamer2/src/ffmpeg-priv.h | 48 + linphone/mediastreamer2/src/g711common.h | 171 + linphone/mediastreamer2/src/gsm.c | 165 + linphone/mediastreamer2/src/ice.c | 556 ++ linphone/mediastreamer2/src/macsnd.c | 702 ++ linphone/mediastreamer2/src/mire.c | 164 + linphone/mediastreamer2/src/mscommon.c | 593 ++ linphone/mediastreamer2/src/msconf.c | 590 ++ linphone/mediastreamer2/src/msfileplayer.c | 304 + .../mediastreamer2/src/msfileplayer_win.c | 369 + linphone/mediastreamer2/src/msfilerec.c | 200 + linphone/mediastreamer2/src/msfilerec_win.c | 237 + linphone/mediastreamer2/src/msfilter.c | 235 + linphone/mediastreamer2/src/msjoin.c | 72 + linphone/mediastreamer2/src/msqueue.c | 112 + linphone/mediastreamer2/src/msresample.c | 245 + linphone/mediastreamer2/src/msrtp.c | 441 ++ linphone/mediastreamer2/src/mssndcard.c | 168 + linphone/mediastreamer2/src/msspeex.c | 565 ++ linphone/mediastreamer2/src/msticker.c | 468 ++ linphone/mediastreamer2/src/msv4l.c | 1034 +++ linphone/mediastreamer2/src/msv4l2.c | 455 ++ linphone/mediastreamer2/src/msv4m.c | 508 ++ linphone/mediastreamer2/src/msvideo.c | 104 + linphone/mediastreamer2/src/msvolume.c | 96 + linphone/mediastreamer2/src/mswebcam.c | 116 + linphone/mediastreamer2/src/mtu.c | 236 + linphone/mediastreamer2/src/nowebcam.c | 217 + linphone/mediastreamer2/src/nowebcam.h | 28 + linphone/mediastreamer2/src/nowebcamCIF.jpg | Bin 0 -> 14247 bytes linphone/mediastreamer2/src/oss.c | 597 ++ linphone/mediastreamer2/src/pasnd.c | 594 ++ linphone/mediastreamer2/src/pixconv.c | 200 + linphone/mediastreamer2/src/rfc2429.h | 50 + linphone/mediastreamer2/src/rfc3984.c | 321 + linphone/mediastreamer2/src/sdlout.c | 375 + linphone/mediastreamer2/src/sizeconv.c | 235 + linphone/mediastreamer2/src/speexec.c | 249 + linphone/mediastreamer2/src/swscale.h | 146 + linphone/mediastreamer2/src/tee.c | 110 + linphone/mediastreamer2/src/theora.c | 582 ++ linphone/mediastreamer2/src/ulaw.c | 227 + linphone/mediastreamer2/src/vfw-missing.h | 264 + linphone/mediastreamer2/src/videodec.c | 464 ++ linphone/mediastreamer2/src/videoenc.c | 703 ++ linphone/mediastreamer2/src/videoout.c | 884 +++ linphone/mediastreamer2/src/videostream.c | 520 ++ linphone/mediastreamer2/src/wincevideods.c | 998 +++ linphone/mediastreamer2/src/winsnd.c | 970 +++ linphone/mediastreamer2/src/winsnd2.c | 852 +++ linphone/mediastreamer2/src/winsndds.cpp | 845 +++ linphone/mediastreamer2/src/winvideo.c | 637 ++ linphone/mediastreamer2/src/winvideods.c | 1048 +++ linphone/mediastreamer2/tests/.cvsignore | 8 + linphone/mediastreamer2/tests/Makefile.am | 32 + linphone/mediastreamer2/tests/echo.c | 74 + linphone/mediastreamer2/tests/mediastream.c | 266 + linphone/mediastreamer2/tests/mtudiscover.c | 33 + linphone/mediastreamer2/tests/ring.c | 52 + linphone/mediastreamer2/tests/videodisplay.c | 116 + linphone/oRTP/.cvsignore | 23 + linphone/oRTP/AUTHORS | 4 + linphone/oRTP/COPYING | 504 ++ linphone/oRTP/ChangeLog | 153 + linphone/oRTP/INSTALL | 229 + linphone/oRTP/Makefile.am | 88 + linphone/oRTP/NEWS | 43 + linphone/oRTP/README | 58 + linphone/oRTP/TODO | 2 + linphone/oRTP/autogen.sh | 18 + linphone/oRTP/build/.cvsignore | 2 + linphone/oRTP/build/Makefile.am | 1 + linphone/oRTP/build/win32/.cvsignore | 2 + linphone/oRTP/build/win32native/.cvsignore | 2 + linphone/oRTP/build/win32native/Makefile.am | 2 + linphone/oRTP/build/win32native/oRTP.vcproj | 381 + linphone/oRTP/build/win32native/ortp-dll.dev | 473 ++ .../oRTP/build/win32native/ortp-static.dev | 462 ++ linphone/oRTP/build/win32native/ortp.def | 174 + linphone/oRTP/build/win32native/ortp.dev | 449 ++ linphone/oRTP/build/wince/.cvsignore | 2 + linphone/oRTP/build/wince/Makefile.am | 2 + linphone/oRTP/build/wince/oRTP.vcproj | 1019 +++ linphone/oRTP/build/wince/ortp.def | 163 + linphone/oRTP/configure.ac | 331 + linphone/oRTP/docs/.cvsignore | 2 + linphone/oRTP/include/.cvsignore | 2 + linphone/oRTP/include/Makefile.am | 1 + linphone/oRTP/include/ortp/.cvsignore | 2 + linphone/oRTP/include/ortp/Makefile.am | 11 + linphone/oRTP/include/ortp/b64.h | 420 ++ linphone/oRTP/include/ortp/event.h | 85 + linphone/oRTP/include/ortp/ortp.h | 199 + linphone/oRTP/include/ortp/payloadtype.h | 208 + linphone/oRTP/include/ortp/port.h | 250 + linphone/oRTP/include/ortp/rtcp.h | 252 + linphone/oRTP/include/ortp/rtp.h | 115 + linphone/oRTP/include/ortp/rtpsession.h | 380 + linphone/oRTP/include/ortp/rtpsignaltable.h | 53 + linphone/oRTP/include/ortp/sessionset.h | 139 + linphone/oRTP/include/ortp/srtp.h | 44 + linphone/oRTP/include/ortp/str_utils.h | 131 + linphone/oRTP/include/ortp/stun.h | 406 ++ linphone/oRTP/include/ortp/stun_udp.h | 142 + linphone/oRTP/include/ortp/telephonyevents.h | 105 + linphone/oRTP/oRTP.prj | 193 + linphone/oRTP/oRTP.pws | 67 + linphone/oRTP/ortp.doxygen.in | 225 + linphone/oRTP/ortp.pc.in | 10 + linphone/oRTP/ortp.spec.in | 83 + linphone/oRTP/pkg.list | 38 + linphone/oRTP/src/.cvsignore | 15 + linphone/oRTP/src/Makefile.am | 41 + linphone/oRTP/src/avprofile.c | 483 ++ linphone/oRTP/src/b64.c | 606 ++ linphone/oRTP/src/dll_entry.c | 147 + linphone/oRTP/src/event.c | 116 + linphone/oRTP/src/jitterctl.c | 182 + linphone/oRTP/src/jitterctl.h | 41 + linphone/oRTP/src/master | 33 + linphone/oRTP/src/ortp-config-win32.h | 31 + linphone/oRTP/src/ortp.c | 372 + linphone/oRTP/src/payloadtype.c | 362 + linphone/oRTP/src/port.c | 336 + linphone/oRTP/src/posixtimer.c | 177 + linphone/oRTP/src/rtcp.c | 412 ++ linphone/oRTP/src/rtcpparse.c | 541 ++ linphone/oRTP/src/rtpparse.c | 213 + linphone/oRTP/src/rtpsession.c | 1596 +++++ linphone/oRTP/src/rtpsession_inet.c | 1028 +++ linphone/oRTP/src/rtpsession_priv.h | 54 + linphone/oRTP/src/rtpsignaltable.c | 98 + linphone/oRTP/src/rtptimer.c | 33 + linphone/oRTP/src/rtptimer.h | 52 + linphone/oRTP/src/scheduler.c | 212 + linphone/oRTP/src/scheduler.h | 69 + linphone/oRTP/src/sessionset.c | 148 + linphone/oRTP/src/srtp.c | 203 + linphone/oRTP/src/str_utils.c | 337 + linphone/oRTP/src/stun.c | 2641 +++++++ linphone/oRTP/src/stun_udp.c | 489 ++ linphone/oRTP/src/system | 15 + linphone/oRTP/src/telephonyevents.c | 421 ++ linphone/oRTP/src/tests/.cvsignore | 15 + linphone/oRTP/src/tests/Makefile.am | 28 + linphone/oRTP/src/tests/mrtprecv.c | 159 + linphone/oRTP/src/tests/mrtpsend.c | 175 + linphone/oRTP/src/tests/rtpmemtest.c | 152 + linphone/oRTP/src/tests/rtprecv.c | 180 + linphone/oRTP/src/tests/rtpsend.c | 128 + linphone/oRTP/src/tests/rtpsend_stupid.c | 126 + linphone/oRTP/src/tests/test_timer.c | 43 + linphone/oRTP/src/tests/tevmrtprecv.c | 175 + linphone/oRTP/src/tests/tevrtprecv.c | 108 + linphone/oRTP/src/tests/tevrtpsend.c | 99 + .../oRTP/src/tests/win_receiver/.cvsignore | 2 + .../oRTP/src/tests/win_receiver/Makefile.am | 2 + .../src/tests/win_receiver/RTPReceiver.cpp | 236 + .../src/tests/win_receiver/RTPReceiver.vcproj | 216 + .../src/tests/win_receiver/ortpreceiver.dev | 59 + linphone/oRTP/src/tests/win_sender/.cvsignore | 2 + .../oRTP/src/tests/win_sender/Makefile.am | 2 + .../oRTP/src/tests/win_sender/RTPSender.cpp | 265 + .../src/tests/win_sender/RTPSender.vcproj | 216 + .../oRTP/src/tests/win_sender/ortpsender.dev | 59 + linphone/oRTP/src/utils.c | 86 + linphone/oRTP/src/utils.h | 91 + linphone/pixmaps/.cvsignore | 2 + linphone/pixmaps/Makefile.am | 11 + linphone/pixmaps/linphone.png | Bin 0 -> 11971 bytes linphone/pixmaps/linphone2.png | Bin 0 -> 5485 bytes linphone/pixmaps/linphone2.xpm | 883 +++ linphone/pixmaps/sip-away.png | Bin 0 -> 1069 bytes linphone/pixmaps/sip-bifm.png | Bin 0 -> 1166 bytes linphone/pixmaps/sip-busy.png | Bin 0 -> 1195 bytes linphone/pixmaps/sip-closed.png | Bin 0 -> 1234 bytes linphone/pixmaps/sip-online.png | Bin 0 -> 1487 bytes linphone/pixmaps/sip-otl.png | Bin 0 -> 1020 bytes linphone/pixmaps/sip-otp.png | Bin 0 -> 1569 bytes linphone/pixmaps/sip-wfa.png | Bin 0 -> 1259 bytes linphone/po/.cvsignore | 6 + linphone/po/ChangeLog | 97 + linphone/po/Makefile.in.in | 403 ++ linphone/po/Makevars | 41 + linphone/po/Makevars.template | 41 + linphone/po/POTFILES.in | 18 + linphone/po/Rules-quot | 47 + linphone/po/boldquot.sed | 10 + linphone/po/cat-id-tbl.c | 0 linphone/po/cs.po | 1049 +++ linphone/po/de.po | 1245 ++++ linphone/po/en@boldquot.header | 25 + linphone/po/en@quot.header | 22 + linphone/po/es.po | 1283 ++++ linphone/po/fr.po | 1031 +++ linphone/po/hu.po | 986 +++ linphone/po/insert-header.sin | 23 + linphone/po/it.po | 1026 +++ linphone/po/ja.po | 1156 ++++ linphone/po/linphone.pot | 930 +++ linphone/po/nl.po | 1062 +++ linphone/po/pl.po | 1122 +++ linphone/po/pt_BR.po | 1012 +++ linphone/po/quot.sed | 6 + linphone/po/remove-potcdate.sin | 19 + linphone/po/sv.po | 1063 +++ linphone/reconfig-SuSE | 23 + linphone/share/.cvsignore | 4 + linphone/share/C/.cvsignore | 5 + linphone/share/C/Makefile.am | 8 + linphone/share/C/linphone.1 | 42 + linphone/share/C/linphonec.1 | 69 + linphone/share/C/manual.lyx | 654 ++ linphone/share/C/manual.sgml | 85 + linphone/share/C/manual/.cvsignore | 1 + linphone/share/C/sipomatic.1 | 70 + linphone/share/Makefile.am | 36 + linphone/share/Makefile.inc | 25 + linphone/share/cs/.cvsignore | 2 + linphone/share/cs/Makefile.am | 8 + linphone/share/cs/linphone.1 | 49 + linphone/share/cs/linphonec.1 | 76 + linphone/share/cs/sipomatic.1 | 82 + linphone/share/fr/.cvsignore | 5 + linphone/share/fr/Makefile.am | 3 + linphone/share/fr/manual.lyx | 745 ++ linphone/share/fr/manual.sgml | 488 ++ linphone/share/fr/manual/.cvsignore | 1 + linphone/share/hello16000.wav | Bin 0 -> 340012 bytes linphone/share/hello8000.wav | Bin 0 -> 180268 bytes linphone/share/it/.cvsignore | 5 + linphone/share/it/Makefile.am | 3 + linphone/share/it/manual.lyx | 741 ++ linphone/share/it/manual.sgml | 494 ++ linphone/share/it/manual/.cvsignore | 1 + linphone/share/ja/.cvsignore | 5 + linphone/share/ja/Makefile.am | 3 + linphone/share/ja/manual.lyx | 505 ++ linphone/share/ja/manual.sgml | 480 ++ linphone/share/ja/manual/.cvsignore | 1 + linphone/share/linphone.desktop | 10 + linphone/share/linphone.gnorba | 5 + linphone/share/linphone.pc.in | 11 + linphone/share/linphone_applet.desktop | 9 + linphone/share/ringback.wav | Bin 0 -> 24620 bytes linphone/share/rings/bigben.wav | Bin 0 -> 962604 bytes linphone/share/rings/oldphone.wav | Bin 0 -> 312300 bytes linphone/share/rings/orig.wav | Bin 0 -> 17092 bytes linphone/share/rings/rock.wav | Bin 0 -> 1298680 bytes linphone/share/rings/sweet.wav | Bin 0 -> 745158 bytes linphone/share/rings/synth.wav | Bin 0 -> 882732 bytes linphone/share/rings/tapping.wav | Bin 0 -> 771208 bytes linphone/share/rings/toy.wav | Bin 0 -> 954872 bytes linphone/stamp-h.in | 1 + linphone/support/.cvsignore | 6 + linphone/win32/config.h | 7 + linphone/win32/liblinphone.dev | 242 + linphone/win32acm/CODECS | 59 + linphone/win32acm/CREDITS | 34 + linphone/win32acm/Makefile | 55 + linphone/win32acm/README | 128 + linphone/win32acm/TODO | 29 + linphone/win32acm/afl.c | 753 ++ linphone/win32acm/com.h | 84 + linphone/win32acm/config.h | 51 + linphone/win32acm/config.h.bak | 465 ++ linphone/win32acm/cpudetect.c | 506 ++ linphone/win32acm/cpudetect.h | 31 + linphone/win32acm/cputable.h | 474 ++ linphone/win32acm/driver.c | 178 + linphone/win32acm/driver.h | 22 + linphone/win32acm/elfdll.c | 292 + linphone/win32acm/ext.c | 606 ++ linphone/win32acm/ext.h | 14 + linphone/win32acm/ldt_keeper.c | 259 + linphone/win32acm/ldt_keeper.h | 22 + linphone/win32acm/loader.h | 35 + linphone/win32acm/loader_objfix.sh | 11 + linphone/win32acm/module.c | 993 +++ linphone/win32acm/mp_msg.c | 174 + linphone/win32acm/mp_msg.h | 131 + linphone/win32acm/pcmin.raw | Bin 0 -> 128000 bytes linphone/win32acm/pe_image.c | 964 +++ linphone/win32acm/pe_resource.c | 392 ++ linphone/win32acm/registry.c | 526 ++ linphone/win32acm/registry.h | 40 + linphone/win32acm/resource.c | 482 ++ linphone/win32acm/stubs.s | 35 + linphone/win32acm/test_truespeech.c | 438 ++ linphone/win32acm/win32.c | 5184 ++++++++++++++ linphone/win32acm/win32.h | 40 + linphone/win32acm/win32codec.c | 256 + linphone/win32acm/win32codec.h | 92 + linphone/win32acm/wine/basetsd.h | 145 + linphone/win32acm/wine/debugtools.h | 93 + linphone/win32acm/wine/driver.h | 112 + linphone/win32acm/wine/elfdll.h | 14 + linphone/win32acm/wine/heap.h | 56 + linphone/win32acm/wine/ldt.h | 98 + linphone/win32acm/wine/mmreg.h | 242 + linphone/win32acm/wine/module.h | 149 + linphone/win32acm/wine/msacm.h | 943 +++ linphone/win32acm/wine/msacmdrv.h | 203 + linphone/win32acm/wine/ntdef.h | 101 + linphone/win32acm/wine/pe_image.h | 81 + linphone/win32acm/wine/poppack.h | 15 + linphone/win32acm/wine/pshpack1.h | 13 + linphone/win32acm/wine/pshpack2.h | 12 + linphone/win32acm/wine/pshpack4.h | 15 + linphone/win32acm/wine/pshpack8.h | 12 + linphone/win32acm/wine/vfw.h | 668 ++ linphone/win32acm/wine/winbase.h | 1791 +++++ linphone/win32acm/wine/windef.h | 666 ++ linphone/win32acm/wine/windows.h | 38 + linphone/win32acm/wine/winerror.h | 1658 +++++ linphone/win32acm/wine/winestring.h | 13 + linphone/win32acm/wine/winnt.h | 2668 +++++++ linphone/win32acm/wine/winreg.h | 57 + linphone/win32acm/wine/winuser.h | 2929 ++++++++ linphone/win32acm/wineacm.h | 72 + linphone/win32acm/wrapper.S | 83 + linphone/win32acm/wrapper.h | 20 + p2pproxy/.classpath | 17 + p2pproxy/.cvsignore | 5 + p2pproxy/.gcjbuilder | 21 + p2pproxy/.project | 17 + p2pproxy/bin/p2pproxy-cmd.bat | 2 + p2pproxy/bin/p2pproxy-cmd.sh | 2 + p2pproxy/bin/p2pproxy.bat | 2 + p2pproxy/bin/p2pproxy.sh | 9 + p2pproxy/build.xml | 182 + .../javawi/jstun/attribute/ChangeRequest.java | 81 + .../jstun/attribute/ChangedAddress.java | 30 + .../de/javawi/jstun/attribute/Data.java | 20 + .../de/javawi/jstun/attribute/Dummy.java | 42 + .../de/javawi/jstun/attribute/ErrorCode.java | 104 + .../javawi/jstun/attribute/MappedAddress.java | 29 + ...onseChangedSourceAddressReflectedFrom.java | 107 + .../jstun/attribute/MessageAttribute.java | 135 + .../attribute/MessageAttributeException.java | 20 + .../attribute/MessageAttributeInterface.java | 68 + .../MessageAttributeParsingException.java | 20 + .../jstun/attribute/MessageIntegrity.java | 27 + .../de/javawi/jstun/attribute/Password.java | 64 + .../javawi/jstun/attribute/ReflectedFrom.java | 31 + .../jstun/attribute/ResponseAddress.java | 29 + .../javawi/jstun/attribute/SourceAddress.java | 29 + .../jstun/attribute/UnknownAttribute.java | 82 + .../UnknownMessageAttributeException.java | 18 + .../de/javawi/jstun/attribute/Username.java | 64 + .../de/javawi/jstun/header/MessageHeader.java | 202 + .../jstun/header/MessageHeaderException.java | 20 + .../jstun/header/MessageHeaderInterface.java | 61 + .../header/MessageHeaderParsingException.java | 20 + .../jstun/test/BindingLifetimeTest.java | 192 + .../de/javawi/jstun/test/DiscoveryInfo.java | 153 + .../de/javawi/jstun/test/DiscoveryTest.java | 351 + .../test/demo/BindingLifetimeTestDemo.java | 47 + .../jstun/test/demo/DiscoveryTestDemo.java | 75 + .../de/javawi/jstun/test/demo/StunServer.java | 263 + .../javawi/jstun/test/demo/ice/Candidate.java | 115 + .../jstun/test/demo/ice/ICENegociator.java | 146 + .../de/javawi/jstun/util/Address.java | 102 + .../de/javawi/jstun/util/Utility.java | 68 + .../javawi/jstun/util/UtilityException.java | 21 + .../dependencies-src/jxse-src-2.5/api/pom.xml | 15 + .../api/src/net/jxta/Version.java | 149 + .../src/net/jxta/access/AccessService.java | 146 + .../api/src/net/jxta/access/package.html | 23 + .../api/src/net/jxta/codat/Codat.java | 168 + .../api/src/net/jxta/codat/CodatID.java | 128 + .../api/src/net/jxta/codat/Metadata.java | 105 + .../api/src/net/jxta/codat/package.html | 15 + .../credential/AuthenticationCredential.java | 386 ++ .../src/net/jxta/credential/Credential.java | 166 + .../jxta/credential/CredentialPCLSupport.java | 112 + .../jxta/credential/CredentialValidator.java | 71 + .../jxta/credential/PrivilegedOperation.java | 81 + .../api/src/net/jxta/credential/package.html | 13 + .../net/jxta/discovery/DiscoveryEvent.java | 123 + .../net/jxta/discovery/DiscoveryListener.java | 112 + .../net/jxta/discovery/DiscoveryService.java | 506 ++ .../api/src/net/jxta/discovery/package.html | 15 + .../src/net/jxta/document/Advertisement.java | 231 + .../jxta/document/AdvertisementFactory.java | 401 ++ .../src/net/jxta/document/Attributable.java | 118 + .../api/src/net/jxta/document/Attribute.java | 189 + .../src/net/jxta/document/BinaryDocument.java | 153 + .../api/src/net/jxta/document/Document.java | 96 + .../jxta/document/DocumentByteArrayIO.java | 75 + .../jxta/document/DocumentByteBufferIO.java | 76 + .../net/jxta/document/DocumentStreamIO.java | 91 + .../api/src/net/jxta/document/Element.java | 142 + .../document/ExtendableAdvertisement.java | 197 + .../src/net/jxta/document/FileDocument.java | 166 + .../src/net/jxta/document/MimeMediaType.java | 835 +++ .../net/jxta/document/StructuredDocument.java | 93 + .../document/StructuredDocumentFactory.java | 582 ++ .../document/StructuredDocumentUtils.java | 228 + .../jxta/document/StructuredTextDocument.java | 89 + .../src/net/jxta/document/TextDocument.java | 71 + .../document/TextDocumentCharArrayIO.java | 80 + .../document/TextDocumentCharBufferIO.java | 80 + .../document/TextDocumentCharSequenceIO.java | 77 + .../jxta/document/TextDocumentReaderIO.java | 91 + .../src/net/jxta/document/TextElement.java | 111 + .../src/net/jxta/document/XMLDocument.java | 76 + .../api/src/net/jxta/document/XMLElement.java | 73 + .../api/src/net/jxta/document/package.html | 13 + .../net/jxta/endpoint/AbstractMessenger.java | 324 + .../jxta/endpoint/AsyncChannelMessenger.java | 665 ++ .../endpoint/ByteArrayMessageElement.java | 383 ++ .../net/jxta/endpoint/ChannelMessenger.java | 214 + .../net/jxta/endpoint/EndpointAddress.java | 637 ++ .../net/jxta/endpoint/EndpointListener.java | 79 + .../net/jxta/endpoint/EndpointService.java | 552 ++ .../endpoint/InputStreamMessageElement.java | 325 + .../net/jxta/endpoint/ListenerAdaptor.java | 481 ++ .../api/src/net/jxta/endpoint/Message.java | 1444 ++++ .../src/net/jxta/endpoint/MessageElement.java | 567 ++ .../jxta/endpoint/MessageFilterListener.java | 86 + .../net/jxta/endpoint/MessagePropagater.java | 100 + .../net/jxta/endpoint/MessageReceiver.java | 85 + .../src/net/jxta/endpoint/MessageSender.java | 150 + .../net/jxta/endpoint/MessageTransport.java | 105 + .../api/src/net/jxta/endpoint/Messenger.java | 696 ++ .../src/net/jxta/endpoint/MessengerEvent.java | 110 + .../jxta/endpoint/MessengerEventListener.java | 73 + .../src/net/jxta/endpoint/MessengerState.java | 443 ++ .../jxta/endpoint/OutgoingMessageEvent.java | 110 + .../OutgoingMessageEventListener.java | 95 + .../jxta/endpoint/StringMessageElement.java | 546 ++ .../endpoint/TextDocumentMessageElement.java | 358 + .../net/jxta/endpoint/TextMessageElement.java | 316 + .../net/jxta/endpoint/ThreadedMessenger.java | 800 +++ .../net/jxta/endpoint/WireFormatMessage.java | 87 + .../endpoint/WireFormatMessageFactory.java | 361 + .../api/src/net/jxta/endpoint/package.html | 12 + .../jxta/exception/ConfiguratorException.java | 237 + .../api/src/net/jxta/exception/JxtaError.java | 84 + .../src/net/jxta/exception/JxtaException.java | 108 + .../jxta/exception/PeerGroupException.java | 108 + .../ProtocolNotSupportedException.java | 108 + .../exception/ServiceNotFoundException.java | 106 + .../exception/UnknownServiceException.java | 108 + .../api/src/net/jxta/exception/package.html | 9 + .../jxse-src-2.5/api/src/net/jxta/id/ID.java | 325 + .../api/src/net/jxta/id/IDFactory.java | 1210 ++++ .../api/src/net/jxta/id/jxta/IDFormat.java | 107 + .../src/net/jxta/id/jxta/Instantiator.java | 320 + .../api/src/net/jxta/id/jxta/package.html | 29 + .../api/src/net/jxta/id/package.html | 12 + .../api/src/net/jxta/logging/Logging.java | 210 + .../api/src/net/jxta/logging/package.html | 39 + .../net/jxta/membership/Authenticator.java | 125 + .../membership/InteractiveAuthenticator.java | 81 + .../jxta/membership/MembershipService.java | 238 + .../membership/doc-files/memberAndAccess.png | Bin 0 -> 22731 bytes .../api/src/net/jxta/membership/package.html | 30 + .../api/src/net/jxta/meter/MonitorEvent.java | 203 + .../src/net/jxta/meter/MonitorException.java | 108 + .../api/src/net/jxta/meter/MonitorFilter.java | 242 + .../jxta/meter/MonitorFilterException.java | 113 + .../src/net/jxta/meter/MonitorListener.java | 85 + .../api/src/net/jxta/meter/MonitorReport.java | 241 + .../src/net/jxta/meter/MonitorResources.java | 548 ++ .../src/net/jxta/meter/PeerMonitorInfo.java | 212 + .../net/jxta/meter/PeerMonitorInfoEvent.java | 100 + .../jxta/meter/PeerMonitorInfoListener.java | 78 + .../api/src/net/jxta/meter/ServiceMetric.java | 96 + .../src/net/jxta/meter/ServiceMonitor.java | 155 + .../net/jxta/meter/ServiceMonitorFilter.java | 81 + .../api/src/net/jxta/meter/package.html | 10 + .../api/src/net/jxta/overview.html | 26 + .../api/src/net/jxta/peer/PeerID.java | 112 + .../api/src/net/jxta/peer/PeerInfoEvent.java | 112 + .../src/net/jxta/peer/PeerInfoListener.java | 93 + .../src/net/jxta/peer/PeerInfoService.java | 303 + .../api/src/net/jxta/peer/package.html | 18 + .../src/net/jxta/peergroup/Configurator.java | 127 + .../jxta/peergroup/LightWeightPeerGroup.java | 584 ++ .../jxta/peergroup/NetPeerGroupFactory.java | 581 ++ .../api/src/net/jxta/peergroup/PeerGroup.java | 1003 +++ .../net/jxta/peergroup/PeerGroupFactory.java | 577 ++ .../src/net/jxta/peergroup/PeerGroupID.java | 241 + .../jxta/peergroup/WorldPeerGroupFactory.java | 339 + .../api/src/net/jxta/peergroup/package.html | 79 + .../api/src/net/jxta/pipe/InputPipe.java | 138 + .../api/src/net/jxta/pipe/OutputPipe.java | 142 + .../src/net/jxta/pipe/OutputPipeEvent.java | 117 + .../src/net/jxta/pipe/OutputPipeListener.java | 94 + .../api/src/net/jxta/pipe/PipeID.java | 114 + .../api/src/net/jxta/pipe/PipeMsgEvent.java | 111 + .../src/net/jxta/pipe/PipeMsgListener.java | 93 + .../api/src/net/jxta/pipe/PipeService.java | 206 + .../api/src/net/jxta/pipe/package.html | 15 + .../src/net/jxta/platform/Application.java | 68 + .../api/src/net/jxta/platform/JxtaLoader.java | 151 + .../api/src/net/jxta/platform/Module.java | 212 + .../src/net/jxta/platform/ModuleClassID.java | 191 + .../src/net/jxta/platform/ModuleSpecID.java | 185 + .../jxta/platform/NetworkConfigurator.java | 1947 ++++++ .../src/net/jxta/platform/NetworkManager.java | 617 ++ .../api/src/net/jxta/platform/package.html | 14 + .../protocol/AccessPointAdvertisement.java | 387 ++ .../src/net/jxta/protocol/ConfigParams.java | 587 ++ .../net/jxta/protocol/DiscoveryQueryMsg.java | 220 + .../jxta/protocol/DiscoveryResponseMsg.java | 379 + .../protocol/ModuleClassAdvertisement.java | 231 + .../protocol/ModuleImplAdvertisement.java | 374 + .../protocol/ModuleSpecAdvertisement.java | 404 ++ .../net/jxta/protocol/PeerAdvertisement.java | 456 ++ .../jxta/protocol/PeerGroupAdvertisement.java | 397 ++ .../jxta/protocol/PeerInfoQueryMessage.java | 171 + .../protocol/PeerInfoResponseMessage.java | 224 + .../net/jxta/protocol/PipeAdvertisement.java | 324 + .../jxta/protocol/PipeResolverMessage.java | 269 + .../net/jxta/protocol/RdvAdvertisement.java | 256 + .../net/jxta/protocol/ResolverQueryMsg.java | 312 + .../jxta/protocol/ResolverResponseMsg.java | 199 + .../net/jxta/protocol/ResolverSrdiMsg.java | 163 + .../net/jxta/protocol/RouteAdvertisement.java | 859 +++ .../src/net/jxta/protocol/RouteQueryMsg.java | 184 + .../net/jxta/protocol/RouteResponseMsg.java | 147 + .../jxta/protocol/SignedAdvertisement.java | 127 + .../src/net/jxta/protocol/SrdiMessage.java | 323 + .../jxta/protocol/TransportAdvertisement.java | 142 + .../api/src/net/jxta/protocol/package.html | 17 + .../jxta/rendezvous/RendezVousService.java | 455 ++ .../net/jxta/rendezvous/RendezVousStatus.java | 100 + .../net/jxta/rendezvous/RendezvousEvent.java | 185 + .../jxta/rendezvous/RendezvousListener.java | 95 + .../api/src/net/jxta/rendezvous/package.html | 14 + .../net/jxta/resolver/GenericResolver.java | 64 + .../src/net/jxta/resolver/QueryHandler.java | 102 + .../net/jxta/resolver/ResolverService.java | 172 + .../src/net/jxta/resolver/SrdiHandler.java | 93 + .../api/src/net/jxta/resolver/package.html | 12 + .../api/src/net/jxta/service/Service.java | 106 + .../api/src/net/jxta/service/package.html | 14 + .../net/jxta/socket/JxtaMulticastSocket.java | 478 ++ .../src/net/jxta/socket/JxtaServerSocket.java | 700 ++ .../api/src/net/jxta/socket/JxtaSocket.java | 1804 +++++ .../net/jxta/socket/JxtaSocketAddress.java | 283 + .../jxta/socket/JxtaSocketInputStream.java | 317 + .../jxta/socket/JxtaSocketOutputStream.java | 190 + .../api/src/net/jxta/socket/package.html | 63 + .../api/src/net/jxta/user.properties | 22 + .../jxta/util/AbstractSimpleSelectable.java | 219 + .../net/jxta/util/AdvertisementUtilities.java | 608 ++ .../api/src/net/jxta/util/AwtUtils.java | 93 + .../api/src/net/jxta/util/ClassFactory.java | 367 + .../net/jxta/util/CountingInputStream.java | 153 + .../net/jxta/util/CountingOutputStream.java | 148 + .../api/src/net/jxta/util/CountingWriter.java | 149 + .../net/jxta/util/DevNullOutputStream.java | 113 + .../api/src/net/jxta/util/DevNullWriter.java | 117 + .../src/net/jxta/util/DocumentUtilities.java | 121 + .../util/IgnoreFlushFilterOutputStream.java | 78 + .../api/src/net/jxta/util/JxtaBiDiPipe.java | 1284 ++++ .../api/src/net/jxta/util/JxtaServerPipe.java | 549 ++ .../src/net/jxta/util/LimitInputStream.java | 381 + .../jxta/util/MarkProhibitedFilterStream.java | 110 + .../src/net/jxta/util/MessageUtilities.java | 160 + .../src/net/jxta/util/PipeEventListener.java | 92 + .../src/net/jxta/util/PipeStateListener.java | 108 + .../api/src/net/jxta/util/PipeUtilities.java | 116 + .../src/net/jxta/util/SimpleSelectable.java | 163 + .../api/src/net/jxta/util/SimpleSelector.java | 159 + .../src/net/jxta/util/WatchedInputStream.java | 247 + .../net/jxta/util/WatchedOutputStream.java | 239 + .../api/src/net/jxta/util/WatchedStream.java | 99 + .../DocumentSerializable.java | 68 + .../DocumentSerializableUtilities.java | 570 ++ .../DocumentSerializationException.java | 73 + .../api/src/net/jxta/util/package.html | 10 + .../src/sun/net/www/protocol/urn/Handler.java | 220 + .../services/net.jxta.document.Advertisement | 23 + .../net.jxta.document.StructuredDocument | 4 + .../net.jxta.endpoint.WireFormatMessage | 3 + .../impl/src/META-INF/services/net.jxta.id.ID | 4 + .../services/net.jxta.platform.Module | 31 + .../impl/src/net/jxta/impl/Version.java | 149 + .../src/net/jxta/impl/access/AccessList.java | 563 ++ .../access/always/AlwaysAccessService.java | 415 ++ .../net/jxta/impl/access/always/package.html | 14 + .../impl/access/pse/PSEAccessService.java | 495 ++ .../src/net/jxta/impl/access/pse/package.html | 19 + .../simpleACL/SimpleACLAccessService.java | 525 ++ .../jxta/impl/access/simpleACL/package.html | 13 + .../impl/src/net/jxta/impl/cm/Cm.java | 1209 ++++ .../impl/src/net/jxta/impl/cm/Indexer.java | 617 ++ .../impl/src/net/jxta/impl/cm/Srdi.java | 666 ++ .../impl/src/net/jxta/impl/cm/SrdiIndex.java | 987 +++ .../impl/src/net/jxta/impl/config.properties | 19 + .../impl/discovery/DiscoveryServiceImpl.java | 1718 +++++ .../discovery/DiscoveryServiceInterface.java | 258 + .../src/net/jxta/impl/discovery/package.html | 15 + .../jxta/impl/document/DOMXMLDocument.java | 490 ++ .../net/jxta/impl/document/DOMXMLElement.java | 383 ++ .../jxta/impl/document/LiteXMLDocument.java | 526 ++ .../jxta/impl/document/LiteXMLElement.java | 1729 +++++ .../jxta/impl/document/PlainTextDocument.java | 293 + .../jxta/impl/document/PlainTextElement.java | 353 + .../impl/document/TextDocumentCommon.java | 95 + .../jxta/impl/endpoint/BlockingMessenger.java | 881 +++ .../impl/endpoint/EndpointServiceImpl.java | 1961 ++++++ .../endpoint/EndpointServiceInterface.java | 494 ++ .../net/jxta/impl/endpoint/EndpointUtils.java | 129 + .../src/net/jxta/impl/endpoint/IPUtils.java | 511 ++ .../endpoint/JxtaMessageMessageElement.java | 260 + .../jxta/impl/endpoint/LoopbackMessenger.java | 213 + .../net/jxta/impl/endpoint/SocketFactory.java | 103 + .../endpoint/WireFormatMessageBinary.java | 1280 ++++ .../net/jxta/impl/endpoint/cbjx/CbJxDefs.java | 98 + .../impl/endpoint/cbjx/CbJxMessageInfo.java | 389 ++ .../impl/endpoint/cbjx/CbJxMessenger.java | 230 + .../impl/endpoint/cbjx/CbJxTransport.java | 692 ++ .../net/jxta/impl/endpoint/cbjx/package.html | 12 + ...ConditionalEndpointMeterBuildSettings.java | 80 + .../endpoint/endpointMeter/EndpointMeter.java | 188 + .../EndpointMeterBuildSettings.java | 67 + .../endpointMeter/EndpointMetric.java | 282 + .../endpointMeter/EndpointServiceMetric.java | 359 + .../endpointMeter/EndpointServiceMonitor.java | 219 + .../EndpointServiceMonitorFilter.java | 158 + .../endpoint/endpointMeter/InboundMeter.java | 154 + .../endpoint/endpointMeter/InboundMetric.java | 279 + .../IncomingMessageListenerMeter.java | 68 + .../endpointMeter/MessengerMeter.java | 69 + .../endpoint/endpointMeter/OutboundMeter.java | 145 + .../endpointMeter/OutboundMetric.java | 289 + .../endpointMeter/PropagationMeter.java | 124 + .../endpointMeter/PropagationMetric.java | 244 + .../impl/endpoint/mcast/McastTransport.java | 887 +++ .../net/jxta/impl/endpoint/mcast/package.html | 17 + .../msgframing/MessagePackageHeader.java | 605 ++ .../endpoint/msgframing/WelcomeMessage.java | 529 ++ .../src/net/jxta/impl/endpoint/package.html | 13 + .../jxta/impl/endpoint/relay/RelayClient.java | 1351 ++++ .../relay/RelayReferralSeedingManager.java | 203 + .../jxta/impl/endpoint/relay/RelayServer.java | 1498 ++++ .../endpoint/relay/RelayServerClient.java | 669 ++ .../impl/endpoint/relay/RelayTransport.java | 464 ++ .../net/jxta/impl/endpoint/relay/package.html | 20 + .../jxta/impl/endpoint/router/BadRoute.java | 190 + .../impl/endpoint/router/Destinations.java | 602 ++ .../impl/endpoint/router/EndpointRouter.java | 2715 ++++++++ .../router/EndpointRouterMessage.java | 512 ++ .../jxta/impl/endpoint/router/RouteCM.java | 595 ++ .../impl/endpoint/router/RouteControl.java | 502 ++ .../impl/endpoint/router/RouteResolver.java | 1432 ++++ .../impl/endpoint/router/RouterMessenger.java | 258 + .../jxta/impl/endpoint/router/package.html | 19 + .../servlethttp/HttpClientMessenger.java | 917 +++ .../servlethttp/HttpMessageReceiver.java | 404 ++ .../servlethttp/HttpMessageSender.java | 261 + .../servlethttp/HttpMessageServlet.java | 908 +++ .../servlethttp/HttpServletMessenger.java | 470 ++ .../servlethttp/ServletHttpTransport.java | 473 ++ .../impl/endpoint/servlethttp/package.html | 19 + .../endpoint/tcp/IncomingUnicastServer.java | 468 ++ .../jxta/impl/endpoint/tcp/TcpMessenger.java | 1128 +++ .../jxta/impl/endpoint/tcp/TcpTransport.java | 1236 ++++ .../net/jxta/impl/endpoint/tcp/package.html | 17 + .../net/jxta/impl/endpoint/tls/JTlsDefs.java | 80 + .../impl/endpoint/tls/JTlsInputStream.java | 590 ++ .../impl/endpoint/tls/JTlsOutputStream.java | 964 +++ .../net/jxta/impl/endpoint/tls/TlsConn.java | 741 ++ .../jxta/impl/endpoint/tls/TlsManager.java | 612 ++ .../jxta/impl/endpoint/tls/TlsMessenger.java | 207 + .../net/jxta/impl/endpoint/tls/TlsSocket.java | 170 + .../jxta/impl/endpoint/tls/TlsTransport.java | 772 +++ .../net/jxta/impl/endpoint/tls/package.html | 15 + ...onditionalTransportMeterBuildSettings.java | 80 + .../transportMeter/TransportBindingMeter.java | 242 + .../TransportBindingMetric.java | 1135 +++ .../transportMeter/TransportMeter.java | 167 + .../TransportMeterBuildSettings.java | 67 + .../transportMeter/TransportMetric.java | 183 + .../TransportServiceMetric.java | 260 + .../TransportServiceMonitor.java | 178 + .../TransportServiceMonitorFilter.java | 155 + .../src/net/jxta/impl/id/CBID/CodatID.java | 200 + .../src/net/jxta/impl/id/CBID/IDFormat.java | 151 + .../net/jxta/impl/id/CBID/Instantiator.java | 445 ++ .../net/jxta/impl/id/CBID/ModuleClassID.java | 146 + .../net/jxta/impl/id/CBID/ModuleSpecID.java | 128 + .../net/jxta/impl/id/CBID/PeerGroupID.java | 191 + .../src/net/jxta/impl/id/CBID/PeerID.java | 183 + .../src/net/jxta/impl/id/CBID/PipeID.java | 181 + .../src/net/jxta/impl/id/CBID/package.html | 17 + .../src/net/jxta/impl/id/UUID/CodatID.java | 293 + .../src/net/jxta/impl/id/UUID/IDBytes.java | 249 + .../src/net/jxta/impl/id/UUID/IDFormat.java | 218 + .../net/jxta/impl/id/UUID/Instantiator.java | 451 ++ .../net/jxta/impl/id/UUID/ModuleClassID.java | 237 + .../net/jxta/impl/id/UUID/ModuleSpecID.java | 216 + .../net/jxta/impl/id/UUID/PeerGroupID.java | 242 + .../src/net/jxta/impl/id/UUID/PeerID.java | 195 + .../src/net/jxta/impl/id/UUID/PipeID.java | 201 + .../impl/src/net/jxta/impl/id/UUID/UUID.java | 300 + .../net/jxta/impl/id/UUID/UUIDFactory.java | 292 + .../src/net/jxta/impl/id/UUID/package.html | 16 + .../net/jxta/impl/id/binaryID/BinaryID.java | 319 + .../impl/id/binaryID/BinaryIDFactory.java | 79 + .../jxta/impl/id/binaryID/CodatBinaryID.java | 274 + .../net/jxta/impl/id/binaryID/DigestTool.java | 417 ++ .../net/jxta/impl/id/binaryID/IDFormat.java | 162 + .../jxta/impl/id/binaryID/Instantiator.java | 395 ++ .../impl/id/binaryID/ModuleClassBinaryID.java | 326 + .../impl/id/binaryID/ModuleSpecBinaryID.java | 283 + .../jxta/impl/id/binaryID/PeerBinaryID.java | 212 + .../impl/id/binaryID/PeerGroupBinaryID.java | 244 + .../jxta/impl/id/binaryID/PipeBinaryID.java | 210 + .../net/jxta/impl/id/binaryID/package.html | 49 + .../impl/src/net/jxta/impl/id/unknown/ID.java | 178 + .../net/jxta/impl/id/unknown/IDFormat.java | 81 + .../jxta/impl/id/unknown/Instantiator.java | 272 + .../src/net/jxta/impl/id/unknown/package.html | 13 + .../net/jxta/impl/loader/RefJxtaLoader.java | 386 ++ .../src/net/jxta/impl/loader/package.html | 10 + .../membership/PasswdMembershipService.java | 180 + .../none/NoneMembershipService.java | 700 ++ .../none/NoneMembershipServiceBeanInfo.java | 121 + .../jxta/impl/membership/none/package.html | 17 + .../src/net/jxta/impl/membership/package.html | 14 + .../passwd/PasswdMembershipService.java | 909 +++ .../PasswdMembershipServiceBeanInfo.java | 121 + .../jxta/impl/membership/passwd/package.html | 17 + .../membership/pse/CMKeyStoreManager.java | 315 + .../membership/pse/DialogAuthenticator.java | 492 ++ .../membership/pse/EngineAuthenticator.java | 365 + .../membership/pse/FileKeyStoreManager.java | 293 + .../impl/membership/pse/KeyStoreManager.java | 139 + .../pse/PSEAuthenticatorEngine.java | 89 + .../pse/PSEAuthenticatorEngineFactory.java | 114 + .../jxta/impl/membership/pse/PSEConfig.java | 648 ++ .../impl/membership/pse/PSECredential.java | 861 +++ .../pse/PSECrendentialBeanInfo.java | 134 + .../pse/PSEKeyStoreManagerFactory.java | 163 + .../membership/pse/PSEMembershipService.java | 797 +++ .../pse/PSEMembershipServiceBeanInfo.java | 125 + .../membership/pse/PSEPeerSecurityEngine.java | 114 + .../pse/PSESecurityEngineFactory.java | 209 + .../jxta/impl/membership/pse/PSEUtils.java | 874 +++ .../membership/pse/StringAuthenticator.java | 356 + .../membership/pse/URIKeyStoreManager.java | 313 + .../net/jxta/impl/membership/pse/package.html | 11 + .../meter/ConditionalMeterBuildSettings.java | 80 + .../impl/meter/GenericServiceMonitor.java | 223 + .../jxta/impl/meter/MeterBuildSettings.java | 67 + .../net/jxta/impl/meter/MetricUtilities.java | 100 + .../net/jxta/impl/meter/MonitorManager.java | 834 +++ .../jxta/impl/meter/ServiceMonitorImpl.java | 71 + .../impl/meter/ServiceMonitorPulseInfo.java | 195 + .../impl/meter/ServiceMonitorResource.java | 68 + .../impl/src/net/jxta/impl/monitor.properties | 64 + .../impl/src/net/jxta/impl/overview.html | 26 + .../net/jxta/impl/peer/PeerInfoHandler.java | 70 + .../net/jxta/impl/peer/PeerInfoMessenger.java | 68 + .../jxta/impl/peer/PeerInfoServiceImpl.java | 560 ++ .../impl/peer/PeerInfoServiceInterface.java | 203 + .../peer/RemoteMonitorPeerInfoHandler.java | 638 ++ .../jxta/impl/peer/RemoteMonitorQuery.java | 227 + .../jxta/impl/peer/RemoteMonitorResponse.java | 334 + .../impl/src/net/jxta/impl/peer/package.html | 11 + .../impl/peergroup/AutomaticConfigurator.java | 511 ++ .../src/net/jxta/impl/peergroup/Boot.java | 169 + .../impl/peergroup/CompatibilityEquater.java | 70 + .../net/jxta/impl/peergroup/ConfigDialog.java | 2022 ++++++ .../impl/peergroup/DefaultConfigurator.java | 270 + .../jxta/impl/peergroup/GenericPeerGroup.java | 1720 +++++ .../IncompleteConfigurationException.java | 66 + .../jxta/impl/peergroup/NullConfigurator.java | 304 + .../impl/peergroup/PeerGroupInterface.java | 447 ++ .../src/net/jxta/impl/peergroup/Platform.java | 257 + .../impl/peergroup/PlatformConfigurator.java | 108 + .../peergroup/RefCountPeerGroupInterface.java | 267 + .../jxta/impl/peergroup/ShadowPeerGroup.java | 186 + .../net/jxta/impl/peergroup/StdPeerGroup.java | 986 +++ .../impl/peergroup/StdPeerGroupParamAdv.java | 517 ++ .../src/net/jxta/impl/peergroup/package.html | 13 + .../impl/pipe/BlockingWireOutputPipe.java | 260 + .../src/net/jxta/impl/pipe/InputPipeImpl.java | 280 + .../jxta/impl/pipe/NonBlockingOutputPipe.java | 768 +++ .../impl/pipe/NonBlockingWireOutputPipe.java | 221 + .../src/net/jxta/impl/pipe/PipeRegistrar.java | 81 + .../src/net/jxta/impl/pipe/PipeResolver.java | 1218 ++++ .../net/jxta/impl/pipe/PipeServiceImpl.java | 748 ++ .../jxta/impl/pipe/PipeServiceInterface.java | 197 + .../jxta/impl/pipe/SecureInputPipeImpl.java | 117 + .../net/jxta/impl/pipe/SecureOutputPipe.java | 124 + .../src/net/jxta/impl/pipe/WireHeader.java | 271 + .../impl/src/net/jxta/impl/pipe/WirePipe.java | 557 ++ .../src/net/jxta/impl/pipe/WirePipeImpl.java | 345 + .../impl/src/net/jxta/impl/pipe/package.html | 18 + .../jxta/impl/protocol/AccessPointAdv.java | 319 + .../net/jxta/impl/protocol/Certificate.java | 268 + .../protocol/CertificateSigningRequest.java | 201 + .../impl/protocol/DiscoveryConfigAdv.java | 347 + .../jxta/impl/protocol/DiscoveryQuery.java | 327 + .../jxta/impl/protocol/DiscoveryResponse.java | 347 + .../net/jxta/impl/protocol/GroupConfig.java | 214 + .../src/net/jxta/impl/protocol/HTTPAdv.java | 561 ++ .../jxta/impl/protocol/LeaseRequestMsg.java | 463 ++ .../jxta/impl/protocol/LeaseResponseMsg.java | 626 ++ .../impl/protocol/LimitedRangeRdvMsg.java | 473 ++ .../jxta/impl/protocol/ModuleClassAdv.java | 263 + .../net/jxta/impl/protocol/ModuleImplAdv.java | 344 + .../net/jxta/impl/protocol/ModuleSpecAdv.java | 376 + .../net/jxta/impl/protocol/PSEConfigAdv.java | 766 +++ .../src/net/jxta/impl/protocol/PeerAdv.java | 364 + .../net/jxta/impl/protocol/PeerGroupAdv.java | 334 + .../impl/protocol/PeerGroupConfigAdv.java | 443 ++ .../jxta/impl/protocol/PeerInfoQueryMsg.java | 179 + .../impl/protocol/PeerInfoResponseMsg.java | 219 + .../src/net/jxta/impl/protocol/PipeAdv.java | 303 + .../jxta/impl/protocol/PipeResolverMsg.java | 341 + .../jxta/impl/protocol/PlatformConfig.java | 441 ++ .../src/net/jxta/impl/protocol/RdvAdv.java | 325 + .../net/jxta/impl/protocol/RdvConfigAdv.java | 948 +++ .../jxta/impl/protocol/RelayConfigAdv.java | 997 +++ .../net/jxta/impl/protocol/ResolverQuery.java | 401 ++ .../jxta/impl/protocol/ResolverResponse.java | 248 + .../impl/protocol/ResolverSrdiMsgImpl.java | 219 + .../src/net/jxta/impl/protocol/RouteAdv.java | 332 + .../net/jxta/impl/protocol/RouteQuery.java | 227 + .../net/jxta/impl/protocol/RouteResponse.java | 234 + .../src/net/jxta/impl/protocol/SignedAdv.java | 384 ++ .../jxta/impl/protocol/SrdiMessageImpl.java | 355 + .../src/net/jxta/impl/protocol/TCPAdv.java | 827 +++ .../src/net/jxta/impl/protocol/package.html | 19 + .../src/net/jxta/impl/proxy/ProxyService.java | 1191 ++++ .../src/net/jxta/impl/proxy/Requestor.java | 325 + .../jxta/impl/rendezvous/PeerConnection.java | 370 + .../net/jxta/impl/rendezvous/RdvGreeter.java | 84 + .../src/net/jxta/impl/rendezvous/RdvWalk.java | 168 + .../net/jxta/impl/rendezvous/RdvWalker.java | 93 + .../RendezVousPropagateMessage.java | 332 + .../rendezvous/RendezVousServiceImpl.java | 945 +++ .../RendezVousServiceInterface.java | 377 + .../rendezvous/RendezVousServiceProvider.java | 788 +++ .../impl/rendezvous/StdRendezVousService.java | 520 ++ .../rendezvous/adhoc/AdhocPeerRdvService.java | 401 ++ .../rendezvous/edge/EdgePeerRdvService.java | 866 +++ .../impl/rendezvous/edge/RdvConnection.java | 157 + .../limited/LimitedRangeGreeter.java | 191 + .../rendezvous/limited/LimitedRangeWalk.java | 219 + .../limited/LimitedRangeWalker.java | 255 + .../src/net/jxta/impl/rendezvous/package.html | 14 + .../impl/rendezvous/rdv/ClientConnection.java | 104 + .../rendezvous/rdv/RdvPeerRdvService.java | 869 +++ .../ClientConnectionMeter.java | 162 + .../ClientConnectionMetric.java | 399 ++ ...nditionalRendezvousMeterBuildSettings.java | 80 + .../RendezvousConnectionMeter.java | 165 + .../RendezvousConnectionMetric.java | 422 ++ .../rendezvousMeter/RendezvousMeter.java | 279 + .../RendezvousMeterBuildSettings.java | 67 + .../rendezvousMeter/RendezvousMetric.java | 666 ++ .../RendezvousServiceMetric.java | 358 + .../RendezvousServiceMonitor.java | 272 + .../RendezvousServiceMonitorFilter.java | 130 + .../jxta/impl/rendezvous/rpv/PeerView.java | 2067 ++++++ .../rendezvous/rpv/PeerViewDestination.java | 126 + .../impl/rendezvous/rpv/PeerViewElement.java | 391 ++ .../impl/rendezvous/rpv/PeerViewEvent.java | 123 + .../impl/rendezvous/rpv/PeerViewListener.java | 71 + .../rpv/PeerViewRandomStrategy.java | 107 + .../PeerViewRandomWithReplaceStrategy.java | 102 + .../rpv/PeerViewSequentialStrategy.java | 132 + .../impl/rendezvous/rpv/PeerViewStrategy.java | 77 + .../rpv/PeerviewSeedingManager.java | 380 + .../impl/resolver/InternalQueryHandler.java | 109 + .../impl/resolver/ResolverServiceImpl.java | 1293 ++++ .../resolver/ResolverServiceInterface.java | 185 + .../src/net/jxta/impl/resolver/package.html | 13 + ...ConditionalResolverMeterBuildSettings.java | 80 + .../resolverMeter/QueryDestinationMeter.java | 164 + .../resolverMeter/QueryDestinationMetric.java | 256 + .../resolverMeter/QueryHandlerMeter.java | 522 ++ .../resolverMeter/QueryHandlerMetric.java | 582 ++ .../resolver/resolverMeter/ResolverMeter.java | 222 + .../ResolverMeterBuildSettings.java | 67 + .../resolverMeter/ResolverMetric.java | 194 + .../resolverMeter/ResolverServiceMetric.java | 327 + .../resolverMeter/ResolverServiceMonitor.java | 249 + .../ResolverServiceMonitorFilter.java | 132 + .../resolverMeter/SrdiDestinationMeter.java | 140 + .../resolverMeter/SrdiDestinationMetric.java | 191 + .../resolverMeter/SrdiHandlerMeter.java | 239 + .../resolverMeter/SrdiHandlerMetric.java | 299 + .../net/jxta/impl/util/ACLSeedingManager.java | 193 + .../src/net/jxta/impl/util/AdvCooker.java | 513 ++ .../net/jxta/impl/util/BASE64InputStream.java | 252 + .../jxta/impl/util/BASE64OutputStream.java | 241 + .../impl/src/net/jxta/impl/util/Base64.java | 284 + .../impl/src/net/jxta/impl/util/Cache.java | 351 + .../src/net/jxta/impl/util/CacheEntry.java | 71 + .../jxta/impl/util/CacheEntryListener.java | 71 + .../jxta/impl/util/ConsumerBiasedQueue.java | 248 + .../impl/src/net/jxta/impl/util/Dlink.java | 130 + .../impl/src/net/jxta/impl/util/Dlist.java | 130 + .../jxta/impl/util/DynamicEnumeration.java | 171 + .../impl/util/EndpointServiceStatsFilter.java | 193 + .../src/net/jxta/impl/util/GenerateID.java | 115 + .../impl/src/net/jxta/impl/util/JxtaHash.java | 219 + .../impl/src/net/jxta/impl/util/LRUCache.java | 216 + .../src/net/jxta/impl/util/ModuleManager.java | 655 ++ .../jxta/impl/util/ProducerBiasedQueue.java | 244 + .../jxta/impl/util/RdvAdvSeedingManager.java | 230 + .../net/jxta/impl/util/ResourceAccount.java | 198 + .../jxta/impl/util/ResourceDispatcher.java | 722 ++ .../net/jxta/impl/util/SeedingManager.java | 186 + .../net/jxta/impl/util/SequenceIterator.java | 141 + .../src/net/jxta/impl/util/TimeUtils.java | 439 ++ .../net/jxta/impl/util/TimerThreadNamer.java | 117 + .../net/jxta/impl/util/URISeedingManager.java | 554 ++ .../src/net/jxta/impl/util/UnbiasedQueue.java | 875 +++ .../src/net/jxta/impl/util/cm/DumpCm.java | 272 + .../impl/src/net/jxta/impl/util/package.html | 11 + .../pipe/reliable/AdaptiveFlowControl.java | 360 + .../jxta/impl/util/pipe/reliable/Defs.java | 84 + .../util/pipe/reliable/FixedFlowControl.java | 100 + .../impl/util/pipe/reliable/FlowControl.java | 110 + .../impl/util/pipe/reliable/Incoming.java | 78 + .../pipe/reliable/IncomingPipeAdaptor.java | 113 + .../impl/util/pipe/reliable/Outgoing.java | 125 + .../pipe/reliable/OutgoingMsgrAdaptor.java | 192 + .../pipe/reliable/OutgoingPipeAdaptor.java | 164 + .../reliable/OutgoingPipeAdaptorSync.java | 205 + .../pipe/reliable/ReliableInputStream.java | 779 +++ .../pipe/reliable/ReliableOutputStream.java | 1277 ++++ .../impl/src/net/jxta/impl/xindice/Debug.java | 125 + .../jxta/impl/xindice/core/DBException.java | 86 + .../net/jxta/impl/xindice/core/DBObject.java | 127 + .../jxta/impl/xindice/core/FaultCodes.java | 555 ++ .../net/jxta/impl/xindice/core/data/Key.java | 125 + .../jxta/impl/xindice/core/data/Record.java | 151 + .../impl/xindice/core/data/RecordSet.java | 103 + .../jxta/impl/xindice/core/data/Value.java | 278 + .../jxta/impl/xindice/core/filer/BTree.java | 1194 ++++ .../xindice/core/filer/BTreeCallback.java | 76 + .../core/filer/BTreeCorruptException.java | 74 + .../xindice/core/filer/BTreeException.java | 75 + .../impl/xindice/core/filer/BTreeFiler.java | 491 ++ .../core/filer/BTreeNotFoundException.java | 73 + .../jxta/impl/xindice/core/filer/Filer.java | 137 + .../xindice/core/filer/FilerException.java | 77 + .../impl/xindice/core/filer/MemFiler.java | 226 + .../jxta/impl/xindice/core/filer/Paged.java | 1501 ++++ .../impl/xindice/core/filer/Streamable.java | 84 + .../impl/xindice/core/indexer/IndexQuery.java | 275 + .../impl/xindice/core/indexer/Indexer.java | 99 + .../xindice/core/indexer/NameIndexer.java | 113 + .../src/net/jxta/impl/xindice/util/Named.java | 75 + .../impl/xindice/util/XindiceException.java | 86 + .../xindice/util/XindiceRuntimeException.java | 78 + p2pproxy/dependencies/MJSIP.COPYRIGHT.txt | 22 + p2pproxy/dependencies/bcprov-jdk14.jar | Bin 0 -> 1601132 bytes .../dependencies/bouncycastle-LICENSE.txt | 22 + p2pproxy/dependencies/javax.servlet.jar | Bin 0 -> 73373 bytes p2pproxy/dependencies/jstun-0.7.0.jar | Bin 0 -> 69133 bytes p2pproxy/dependencies/junit-4.3.1.jar | Bin 0 -> 106547 bytes p2pproxy/dependencies/jxta_license.html | 248 + p2pproxy/dependencies/log4j.LICENSE | 202 + p2pproxy/dependencies/log4j.jar | Bin 0 -> 358180 bytes p2pproxy/dependencies/org.mortbay.jetty.jar | Bin 0 -> 576379 bytes p2pproxy/dependencies/sip.jar | Bin 0 -> 201058 bytes p2pproxy/log4j.properties | 80 + .../p2pproxy/api/P2pProxyException.java | 45 + .../p2pproxy/api/P2pProxyInstance.java | 76 + .../p2pproxy/api/P2pProxyManagement.java | 33 + .../p2pproxy/api/P2pProxyNetworkProbe.java | 48 + .../api/P2pProxyRtpRelayManagement.java | 15 + .../P2pProxyUserAlreadyExistException.java | 58 + .../api/P2pProxyUserNotFoundException.java | 55 + .../linphone/p2pproxy/core/Configurator.java | 68 + .../p2pproxy/core/EdgePeerServiceManager.java | 61 + .../p2pproxy/core/GenericService.java | 150 + .../p2pproxy/core/GenericServiceClient.java | 121 + .../p2pproxy/core/GenericUdpSession.java | 79 + .../p2pproxy/core/JxtaNetworkManager.java | 362 + .../p2pproxy/core/MessageDispatcher.java | 53 + .../p2pproxy/core/NetworkResources.java | 91 + .../core/P2pProxyAccountManagement.java | 120 + .../core/P2pProxyAccountManagementMBean.java | 49 + ...2pProxyAdvertisementNotFoundException.java | 57 + .../p2pproxy/core/P2pProxyInstanceImpl.java | 273 + .../linphone/p2pproxy/core/P2pProxyMain.java | 353 + .../p2pproxy/core/P2pProxyMainMBean.java | 35 + .../p2pproxy/core/P2pProxyManagementImpl.java | 79 + .../core/P2pUserProfileAdvertisement.java | 251 + .../linphone/p2pproxy/core/SdpProcessor.java | 39 + .../core/SeedingPeerServiceManager.java | 59 + .../p2pproxy/core/ServiceProvider.java | 16 + .../p2pproxy/core/SipProxyRegistrar.java | 478 ++ .../p2pproxy/core/SipProxyRegistrarMBean.java | 34 + .../core/SuperPeerServiceManager.java | 47 + .../core/jxtaext/EndpointRegistry.java | 63 + .../core/jxtaext/NatedEndPointAddress.java | 52 + .../core/media/jxtaudpproxy/RtpSession.java | 9 + .../media/jxtaudpproxy/RtpSessionImpl.java | 81 + .../media/jxtaudpproxy/SdpProcessorImpl.java | 190 + .../core/media/jxtaudpproxy/UdpSession.java | 90 + .../core/media/rtprelay/AddressRequest.java | 32 + .../core/media/rtprelay/AddressResponse.java | 47 + .../media/rtprelay/IceSdpProcessorImpl.java | 222 + .../core/media/rtprelay/MediaType.java | 38 + .../core/media/rtprelay/RouteAddRequest.java | 57 + .../core/media/rtprelay/RouteAddResponse.java | 50 + .../core/media/rtprelay/RoutingTable.java | 60 + .../core/media/rtprelay/RtpRelayServer.java | 326 + .../media/rtprelay/RtpRelayServerConfig.java | 28 + .../core/media/rtprelay/RtpRelayService.java | 134 + .../media/rtprelay/RtpRelayServiceClient.java | 53 + .../core/media/rtprelay/RtpRoutingRules.java | 48 + .../core/media/rtprelay/SdpProcessorImpl.java | 222 + .../media/rtprelay/SingleAddressResponse.java | 43 + .../core/rdvautoconfig/AutoConfigService.java | 146 + .../rdvautoconfig/P2pproxyRdvListener.java | 33 + .../core/rdvautoconfig/PeerInfoProvider.java | 33 + .../PeerInfoProviderService.java | 233 + .../rdvautoconfig/PeerInfoServiceClient.java | 150 + .../rdvautoconfig/PublicIpAddressRequest.java | 41 + .../PublicIpAddressResponse.java | 58 + .../rdvautoconfig/SocketProbeRequest.java | 55 + .../p2pproxy/core/turnserver/TurnServer.java | 279 + .../core/utils/AccountManagerCli.java | 129 + .../p2pproxy/core/utils/DumpLocalCache.java | 45 + .../core/utils/PeerGroupIdGenerator.java | 74 + .../p2pproxy/test/P2pAutoConfigTester.java | 110 + .../test/P2pProxyAccountManagementTester.java | 86 + .../test/P2pProxyNatedNetworkTester.java | 48 + .../test/P2pProxyNetworkingTester.java | 148 + .../p2pproxy/test/P2pProxyTester.java | 441 ++ .../p2pproxy/test/RtpRelayServerTester.java | 182 + .../p2pproxy/test/TurnServerTester.java | 421 ++ .../p2pproxy/test/UdpRelayTester.java | 125 + .../test/utils/DefaultCallListener.java | 75 + .../p2pproxy/test/utils/P2pNetwork.java | 224 + .../p2pproxy/test/utils/SipClient.java | 196 + 1602 files changed, 411919 insertions(+) create mode 100644 linphone/.cvsignore create mode 100644 linphone/ABOUT-NLS create mode 100644 linphone/AUTHORS create mode 100644 linphone/BUGS create mode 100644 linphone/COPYING create mode 100644 linphone/ChangeLog create mode 100644 linphone/INSTALL create mode 100644 linphone/Makefile.am create mode 100644 linphone/NEWS create mode 100644 linphone/README create mode 100644 linphone/README.CVS create mode 100644 linphone/README.M68k.txt create mode 100644 linphone/README.arm create mode 100644 linphone/TODO create mode 100755 linphone/autogen.sh create mode 100755 linphone/build.mk create mode 100755 linphone/config.rpath create mode 100644 linphone/configure.in create mode 100644 linphone/console/.cvsignore create mode 100644 linphone/console/Makefile.am create mode 100644 linphone/console/TODO create mode 100644 linphone/console/commands.c create mode 100644 linphone/console/example/linphonec create mode 100644 linphone/console/linphonec.c create mode 100644 linphone/console/linphonec.h create mode 100644 linphone/console/sipomatic.c create mode 100644 linphone/console/sipomatic.h create mode 100644 linphone/console/wav2raw.c create mode 100644 linphone/coreapi/.cvsignore create mode 100644 linphone/coreapi/Makefile.am create mode 100644 linphone/coreapi/authentication.c create mode 100644 linphone/coreapi/chat.c create mode 100644 linphone/coreapi/enum.c create mode 100644 linphone/coreapi/enum.h create mode 100644 linphone/coreapi/exevents.c create mode 100644 linphone/coreapi/exevents.h create mode 100644 linphone/coreapi/friend.c create mode 100644 linphone/coreapi/general_state.c create mode 100644 linphone/coreapi/linphonecore.c create mode 100644 linphone/coreapi/linphonecore.h create mode 100644 linphone/coreapi/lpconfig.c create mode 100644 linphone/coreapi/lpconfig.h create mode 100644 linphone/coreapi/misc.c create mode 100644 linphone/coreapi/presence.c create mode 100644 linphone/coreapi/private.h create mode 100644 linphone/coreapi/proxy.c create mode 100644 linphone/coreapi/sdphandler.c create mode 100644 linphone/coreapi/sdphandler.h create mode 100644 linphone/debian/.cvsignore create mode 100644 linphone/debian/Makefile.am create mode 100644 linphone/debian/control create mode 100644 linphone/debian/copyright create mode 100644 linphone/debian/dirs create mode 100644 linphone/debian/docs create mode 100644 linphone/debian/manpage.1.ex create mode 100644 linphone/debian/manpage.sgml.ex create mode 100644 linphone/debian/menu create mode 100755 linphone/debian/rules create mode 100644 linphone/debian/watch.ex create mode 100644 linphone/developer-docs/.cvsignore create mode 100644 linphone/developer-docs/mediastreamer/.cvsignore create mode 100644 linphone/exosip/.cvsignore create mode 100644 linphone/exosip/Makefile.am create mode 100644 linphone/exosip/eXosip.c create mode 100644 linphone/exosip/eXosip.h create mode 100644 linphone/exosip/eXosip2.h create mode 100644 linphone/exosip/eXosip_cfg.h create mode 100644 linphone/exosip/eXutils.c create mode 100755 linphone/exosip/exosip.dev create mode 100644 linphone/exosip/jauth.c create mode 100644 linphone/exosip/jcall.c create mode 100644 linphone/exosip/jcallback.c create mode 100644 linphone/exosip/jdialog.c create mode 100644 linphone/exosip/jevents.c create mode 100644 linphone/exosip/jfreinds.c create mode 100644 linphone/exosip/jidentity.c create mode 100644 linphone/exosip/jnotify.c create mode 100644 linphone/exosip/jpipe.c create mode 100644 linphone/exosip/jpipe.h create mode 100644 linphone/exosip/jpublish.c create mode 100644 linphone/exosip/jreg.c create mode 100644 linphone/exosip/jrequest.c create mode 100644 linphone/exosip/jresponse.c create mode 100644 linphone/exosip/jsubscribe.c create mode 100644 linphone/exosip/jsubscribers.c create mode 100644 linphone/exosip/misc.c create mode 100644 linphone/exosip/sdp_offans.c create mode 100644 linphone/exosip/udp.c create mode 100644 linphone/gnome/.cvsignore create mode 100644 linphone/gnome/GNOME_LinphoneApplet.server.in.in create mode 100644 linphone/gnome/GNOME_LinphoneApplet.xml create mode 100644 linphone/gnome/Makefile.am create mode 100644 linphone/gnome/addressbook.c create mode 100644 linphone/gnome/addressbook.h create mode 100644 linphone/gnome/applet.c create mode 100644 linphone/gnome/callbacks.c create mode 100644 linphone/gnome/callbacks.h create mode 100644 linphone/gnome/friends.c create mode 100644 linphone/gnome/friends.h create mode 100644 linphone/gnome/gui_utils.c create mode 100644 linphone/gnome/gui_utils.h create mode 100644 linphone/gnome/interface.c create mode 100644 linphone/gnome/interface.h create mode 100644 linphone/gnome/linphone.c create mode 100644 linphone/gnome/linphone.h create mode 100644 linphone/gnome/main.c create mode 100644 linphone/gnome/presence.c create mode 100644 linphone/gnome/presence.h create mode 100644 linphone/gnome/propertybox.c create mode 100644 linphone/gnome/propertybox.h create mode 100644 linphone/gnome/support.c create mode 100644 linphone/gnome/support.h create mode 100644 linphone/gsmlib/.cvsignore create mode 100644 linphone/gsmlib/COPYRIGHT create mode 100644 linphone/gsmlib/ChangeLog create mode 100644 linphone/gsmlib/ChangeLog.orig create mode 100644 linphone/gsmlib/INSTALL create mode 100644 linphone/gsmlib/MACHINES create mode 100644 linphone/gsmlib/MANIFEST create mode 100644 linphone/gsmlib/Makefile.am create mode 100644 linphone/gsmlib/README create mode 100644 linphone/gsmlib/code.c create mode 100644 linphone/gsmlib/config.h create mode 100644 linphone/gsmlib/debug.c create mode 100644 linphone/gsmlib/decode.c create mode 100644 linphone/gsmlib/gsm.h create mode 100644 linphone/gsmlib/gsm_create.c create mode 100644 linphone/gsmlib/gsm_decode.c create mode 100644 linphone/gsmlib/gsm_destroy.c create mode 100644 linphone/gsmlib/gsm_encode.c create mode 100644 linphone/gsmlib/gsm_explode.c create mode 100644 linphone/gsmlib/gsm_implode.c create mode 100644 linphone/gsmlib/gsm_option.c create mode 100644 linphone/gsmlib/gsm_print.c create mode 100644 linphone/gsmlib/gsm_wrapper.c create mode 100644 linphone/gsmlib/gsm_wrapper.h create mode 100644 linphone/gsmlib/gsmadd.c create mode 100644 linphone/gsmlib/long_term.c create mode 100644 linphone/gsmlib/lpc.c create mode 100644 linphone/gsmlib/preprocess.c create mode 100644 linphone/gsmlib/private.h create mode 100644 linphone/gsmlib/proto.h create mode 100644 linphone/gsmlib/rpe.c create mode 100644 linphone/gsmlib/short_term.c create mode 100644 linphone/gsmlib/table.c create mode 100644 linphone/gsmlib/toast.h create mode 100644 linphone/gsmlib/unproto.h create mode 100644 linphone/gtk-glade/Makefile.am create mode 100644 linphone/gtk-glade/about.glade create mode 100644 linphone/gtk-glade/call_logs.glade create mode 100644 linphone/gtk-glade/calllogs.c create mode 100644 linphone/gtk-glade/chat.c create mode 100644 linphone/gtk-glade/chatroom.glade create mode 100644 linphone/gtk-glade/contact.glade create mode 100644 linphone/gtk-glade/friendlist.c create mode 100644 linphone/gtk-glade/gtk-linphone.glade create mode 100644 linphone/gtk-glade/incoming_call.glade create mode 100755 linphone/gtk-glade/linphone.dev create mode 100644 linphone/gtk-glade/linphone.h create mode 100755 linphone/gtk-glade/linphone.iss create mode 100644 linphone/gtk-glade/linphone.png create mode 100644 linphone/gtk-glade/linphone2.png create mode 100644 linphone/gtk-glade/log.glade create mode 100644 linphone/gtk-glade/logging.c create mode 100644 linphone/gtk-glade/main.c create mode 100644 linphone/gtk-glade/main.glade create mode 100644 linphone/gtk-glade/parameters.glade create mode 100644 linphone/gtk-glade/password.glade create mode 100644 linphone/gtk-glade/propertybox.c create mode 100644 linphone/gtk-glade/sip_account.glade create mode 100644 linphone/gtk-glade/stock_people.png create mode 100644 linphone/gtk-glade/support.c create mode 100644 linphone/gtk/.cvsignore create mode 100644 linphone/gtk/GNOME_LinphoneApplet.server.in.in create mode 100644 linphone/gtk/GNOME_LinphoneApplet.xml create mode 100644 linphone/gtk/Makefile.am create mode 100644 linphone/gtk/addressbook.c create mode 100644 linphone/gtk/addressbook.h create mode 100644 linphone/gtk/applet.c create mode 100644 linphone/gtk/callbacks.c create mode 100644 linphone/gtk/callbacks.h create mode 100644 linphone/gtk/friends.c create mode 100644 linphone/gtk/friends.h create mode 100644 linphone/gtk/gui_utils.c create mode 100644 linphone/gtk/gui_utils.h create mode 100644 linphone/gtk/interface.c create mode 100644 linphone/gtk/interface.h create mode 100644 linphone/gtk/linphone.c create mode 100644 linphone/gtk/linphone.h create mode 100644 linphone/gtk/main.c create mode 100644 linphone/gtk/presence.c create mode 100644 linphone/gtk/presence.h create mode 100644 linphone/gtk/propertybox.c create mode 100644 linphone/gtk/propertybox.h create mode 100644 linphone/gtk/support.c create mode 100644 linphone/gtk/support.h create mode 100644 linphone/intl/ChangeLog create mode 100644 linphone/intl/Makefile.in create mode 100644 linphone/intl/VERSION create mode 100644 linphone/intl/bindtextdom.c create mode 100644 linphone/intl/cat-compat.c create mode 100644 linphone/intl/dcgettext.c create mode 100644 linphone/intl/dgettext.c create mode 100644 linphone/intl/explodename.c create mode 100644 linphone/intl/finddomain.c create mode 100644 linphone/intl/gettext.c create mode 100644 linphone/intl/gettext.h create mode 100644 linphone/intl/gettextP.h create mode 100644 linphone/intl/hash-string.h create mode 100644 linphone/intl/intl-compat.c create mode 100644 linphone/intl/l10nflist.c create mode 100644 linphone/intl/libgettext.h create mode 100644 linphone/intl/linux-msg.sed create mode 100644 linphone/intl/loadinfo.h create mode 100644 linphone/intl/loadmsgcat.c create mode 100644 linphone/intl/localealias.c create mode 100644 linphone/intl/po2tbl.sed.in create mode 100644 linphone/intl/textdomain.c create mode 100644 linphone/intl/xopen-msg.sed create mode 100644 linphone/intltool-extract.in create mode 100644 linphone/intltool-merge.in create mode 100644 linphone/intltool-update.in create mode 100644 linphone/ipkg/.cvsignore create mode 100644 linphone/ipkg/Makefile.am create mode 100644 linphone/ipkg/glib.control create mode 100644 linphone/ipkg/ipaq-config.site create mode 100644 linphone/ipkg/libosip.control create mode 100644 linphone/ipkg/linphone.control.in create mode 100644 linphone/linphone.kdevprj create mode 100644 linphone/linphone.spec.in create mode 100644 linphone/linphone2-gtk.glade create mode 100644 linphone/linphone2.glade create mode 100644 linphone/lpc10-1.5/.cvsignore create mode 100644 linphone/lpc10-1.5/FAQ create mode 100644 linphone/lpc10-1.5/Makefile.am create mode 100644 linphone/lpc10-1.5/README create mode 100644 linphone/lpc10-1.5/README-1.0 create mode 100644 linphone/lpc10-1.5/README.new create mode 100644 linphone/lpc10-1.5/analys.c create mode 100644 linphone/lpc10-1.5/bitio.c create mode 100644 linphone/lpc10-1.5/bsynz.c create mode 100644 linphone/lpc10-1.5/chanwr.c create mode 100644 linphone/lpc10-1.5/dcbias.c create mode 100644 linphone/lpc10-1.5/decode.c create mode 100644 linphone/lpc10-1.5/deemp.c create mode 100644 linphone/lpc10-1.5/difmag.c create mode 100644 linphone/lpc10-1.5/dyptrk.c create mode 100644 linphone/lpc10-1.5/encode.c create mode 100644 linphone/lpc10-1.5/energy.c create mode 100644 linphone/lpc10-1.5/f2c.h create mode 100644 linphone/lpc10-1.5/f2clib.c create mode 100644 linphone/lpc10-1.5/ham84.c create mode 100644 linphone/lpc10-1.5/hp100.c create mode 100644 linphone/lpc10-1.5/invert.c create mode 100644 linphone/lpc10-1.5/irc2pc.c create mode 100644 linphone/lpc10-1.5/ivfilt.c create mode 100644 linphone/lpc10-1.5/lpc10.h create mode 100644 linphone/lpc10-1.5/lpc10_wrapper.c create mode 100644 linphone/lpc10-1.5/lpc10_wrapper.h create mode 100644 linphone/lpc10-1.5/lpcdec.c create mode 100644 linphone/lpc10-1.5/lpcenc.c create mode 100644 linphone/lpc10-1.5/lpcini.c create mode 100644 linphone/lpc10-1.5/lpfilt.c create mode 100644 linphone/lpc10-1.5/median.c create mode 100644 linphone/lpc10-1.5/mload.c create mode 100644 linphone/lpc10-1.5/onset.c create mode 100644 linphone/lpc10-1.5/pitsyn.c create mode 100644 linphone/lpc10-1.5/placea.c create mode 100644 linphone/lpc10-1.5/placev.c create mode 100644 linphone/lpc10-1.5/preemp.c create mode 100644 linphone/lpc10-1.5/prepro.c create mode 100644 linphone/lpc10-1.5/random.c create mode 100644 linphone/lpc10-1.5/rcchk.c create mode 100644 linphone/lpc10-1.5/synths.c create mode 100644 linphone/lpc10-1.5/tbdm.c create mode 100644 linphone/lpc10-1.5/voicin.c create mode 100644 linphone/lpc10-1.5/vparms.c create mode 100644 linphone/m4/.cvsignore create mode 100644 linphone/m4/Makefile.am create mode 100644 linphone/m4/codeset.m4 create mode 100644 linphone/m4/exosip.m4 create mode 100644 linphone/m4/gettext.m4 create mode 100644 linphone/m4/glibc2.m4 create mode 100644 linphone/m4/glibc21.m4 create mode 100644 linphone/m4/iconv.m4 create mode 100644 linphone/m4/ilbc.m4 create mode 100644 linphone/m4/intdiv0.m4 create mode 100644 linphone/m4/intl.m4 create mode 100644 linphone/m4/intldir.m4 create mode 100644 linphone/m4/intmax.m4 create mode 100644 linphone/m4/inttypes-pri.m4 create mode 100644 linphone/m4/inttypes.m4 create mode 100644 linphone/m4/inttypes_h.m4 create mode 100644 linphone/m4/isc-posix.m4 create mode 100644 linphone/m4/lcmessage.m4 create mode 100644 linphone/m4/lib-ld.m4 create mode 100644 linphone/m4/lib-link.m4 create mode 100644 linphone/m4/lib-prefix.m4 create mode 100644 linphone/m4/lock.m4 create mode 100644 linphone/m4/longdouble.m4 create mode 100644 linphone/m4/longlong.m4 create mode 100644 linphone/m4/nls.m4 create mode 100644 linphone/m4/ortp.m4 create mode 100644 linphone/m4/osip.m4 create mode 100644 linphone/m4/po.m4 create mode 100644 linphone/m4/printf-posix.m4 create mode 100644 linphone/m4/progtest.m4 create mode 100644 linphone/m4/readline.m4 create mode 100644 linphone/m4/signed.m4 create mode 100644 linphone/m4/size_max.m4 create mode 100644 linphone/m4/stdint_h.m4 create mode 100644 linphone/m4/uintmax_t.m4 create mode 100644 linphone/m4/ulonglong.m4 create mode 100644 linphone/m4/video.m4 create mode 100644 linphone/m4/visibility.m4 create mode 100644 linphone/m4/wchar_t.m4 create mode 100644 linphone/m4/wint_t.m4 create mode 100644 linphone/m4/xsize.m4 create mode 100755 linphone/make_exosip.sh create mode 100644 linphone/media_api/.cvsignore create mode 100644 linphone/media_api/DESIGN.txt create mode 100644 linphone/media_api/Makefile.am create mode 100644 linphone/media_api/apitest.c create mode 100644 linphone/media_api/apitest.h create mode 100644 linphone/media_api/basiccall.c create mode 100644 linphone/media_api/basiccall.h create mode 100644 linphone/media_api/callmember.c create mode 100644 linphone/media_api/callmember.h create mode 100644 linphone/media_api/ccl create mode 100644 linphone/media_api/common.h create mode 100644 linphone/media_api/media_api.c create mode 100644 linphone/media_api/media_api.h create mode 100644 linphone/media_api/mediaflow.c create mode 100644 linphone/media_api/mediaflow.h create mode 100644 linphone/mediastreamer/.cvsignore create mode 100644 linphone/mediastreamer/Makefile.am create mode 100644 linphone/mediastreamer/Makefile.ms create mode 100644 linphone/mediastreamer/README create mode 100644 linphone/mediastreamer/affine.c create mode 100644 linphone/mediastreamer/affine.h create mode 100644 linphone/mediastreamer/alsacard.c create mode 100644 linphone/mediastreamer/alsacard.h create mode 100644 linphone/mediastreamer/audiostream.c create mode 100644 linphone/mediastreamer/g711common.h create mode 100644 linphone/mediastreamer/hpuxsndcard.c create mode 100644 linphone/mediastreamer/jackcard.c create mode 100644 linphone/mediastreamer/jackcard.h create mode 100644 linphone/mediastreamer/mediastream.c create mode 100644 linphone/mediastreamer/mediastream.h create mode 100644 linphone/mediastreamer/ms.c create mode 100644 linphone/mediastreamer/ms.h create mode 100644 linphone/mediastreamer/msAlawdec.c create mode 100644 linphone/mediastreamer/msAlawdec.h create mode 100644 linphone/mediastreamer/msAlawenc.c create mode 100644 linphone/mediastreamer/msAlawenc.h create mode 100644 linphone/mediastreamer/msGSMdecoder.c create mode 100644 linphone/mediastreamer/msGSMdecoder.h create mode 100644 linphone/mediastreamer/msGSMencoder.c create mode 100644 linphone/mediastreamer/msGSMencoder.h create mode 100644 linphone/mediastreamer/msLPC10decoder.c create mode 100644 linphone/mediastreamer/msLPC10decoder.h create mode 100644 linphone/mediastreamer/msLPC10encoder.c create mode 100644 linphone/mediastreamer/msLPC10encoder.h create mode 100644 linphone/mediastreamer/msMUlawdec.c create mode 100644 linphone/mediastreamer/msMUlawdec.h create mode 100644 linphone/mediastreamer/msMUlawenc.c create mode 100644 linphone/mediastreamer/msMUlawenc.h create mode 100644 linphone/mediastreamer/msavdecoder.c create mode 100644 linphone/mediastreamer/msavdecoder.h create mode 100644 linphone/mediastreamer/msavencoder.c create mode 100644 linphone/mediastreamer/msavencoder.h create mode 100644 linphone/mediastreamer/msbuffer.c create mode 100644 linphone/mediastreamer/msbuffer.h create mode 100644 linphone/mediastreamer/mscodec.c create mode 100644 linphone/mediastreamer/mscodec.h create mode 100644 linphone/mediastreamer/mscopy.c create mode 100644 linphone/mediastreamer/mscopy.h create mode 100644 linphone/mediastreamer/msfdispatcher.c create mode 100644 linphone/mediastreamer/msfdispatcher.h create mode 100644 linphone/mediastreamer/msfifo.c create mode 100644 linphone/mediastreamer/msfifo.h create mode 100644 linphone/mediastreamer/msfilter.c create mode 100644 linphone/mediastreamer/msfilter.h create mode 100644 linphone/mediastreamer/msnosync.c create mode 100644 linphone/mediastreamer/msnosync.h create mode 100644 linphone/mediastreamer/msossread.c create mode 100644 linphone/mediastreamer/msossread.h create mode 100644 linphone/mediastreamer/msosswrite.c create mode 100644 linphone/mediastreamer/msosswrite.h create mode 100644 linphone/mediastreamer/msqdispatcher.c create mode 100644 linphone/mediastreamer/msqdispatcher.h create mode 100644 linphone/mediastreamer/msqueue.c create mode 100644 linphone/mediastreamer/msqueue.h create mode 100644 linphone/mediastreamer/msread.c create mode 100644 linphone/mediastreamer/msread.h create mode 100644 linphone/mediastreamer/msringplayer.c create mode 100644 linphone/mediastreamer/msringplayer.h create mode 100644 linphone/mediastreamer/msrtprecv.c create mode 100644 linphone/mediastreamer/msrtprecv.h create mode 100644 linphone/mediastreamer/msrtpsend.c create mode 100644 linphone/mediastreamer/msrtpsend.h create mode 100644 linphone/mediastreamer/mssdlout.c create mode 100644 linphone/mediastreamer/mssdlout.h create mode 100644 linphone/mediastreamer/mssmpeg.c create mode 100644 linphone/mediastreamer/mssmpeg.h create mode 100644 linphone/mediastreamer/mssoundread.c create mode 100644 linphone/mediastreamer/mssoundread.h create mode 100644 linphone/mediastreamer/mssoundwrite.c create mode 100644 linphone/mediastreamer/mssoundwrite.h create mode 100644 linphone/mediastreamer/msspeexdec.c create mode 100644 linphone/mediastreamer/msspeexdec.h create mode 100644 linphone/mediastreamer/msspeexenc.c create mode 100644 linphone/mediastreamer/msspeexenc.h create mode 100644 linphone/mediastreamer/mssync.c create mode 100644 linphone/mediastreamer/mssync.h create mode 100644 linphone/mediastreamer/mstcpclient.c create mode 100644 linphone/mediastreamer/mstcpclient.h create mode 100644 linphone/mediastreamer/mstcpserv.c create mode 100644 linphone/mediastreamer/mstcpserv.h create mode 100644 linphone/mediastreamer/mstimer.c create mode 100644 linphone/mediastreamer/mstimer.h create mode 100644 linphone/mediastreamer/mstruespeechdecoder.c create mode 100644 linphone/mediastreamer/mstruespeechdecoder.h create mode 100644 linphone/mediastreamer/mstruespeechencoder.c create mode 100644 linphone/mediastreamer/mstruespeechencoder.h create mode 100644 linphone/mediastreamer/msutils.h create mode 100644 linphone/mediastreamer/msv4l.c create mode 100644 linphone/mediastreamer/msv4l.h create mode 100644 linphone/mediastreamer/msvideooutput.c create mode 100644 linphone/mediastreamer/msvideooutput.h create mode 100644 linphone/mediastreamer/msvideosource.c create mode 100644 linphone/mediastreamer/msvideosource.h create mode 100644 linphone/mediastreamer/mswrite.c create mode 100644 linphone/mediastreamer/mswrite.h create mode 100644 linphone/mediastreamer/msxine.c create mode 100644 linphone/mediastreamer/msxine.h create mode 100644 linphone/mediastreamer/osscard.c create mode 100644 linphone/mediastreamer/osscard.h create mode 100644 linphone/mediastreamer/rfc2429.h create mode 100644 linphone/mediastreamer/ring_test.c create mode 100644 linphone/mediastreamer/sndcard.c create mode 100644 linphone/mediastreamer/sndcard.h create mode 100644 linphone/mediastreamer/test.c create mode 100644 linphone/mediastreamer/test_alaw.c create mode 100644 linphone/mediastreamer/test_gsm.c create mode 100644 linphone/mediastreamer/test_lpc10.c create mode 100644 linphone/mediastreamer/test_mulaw.c create mode 100644 linphone/mediastreamer/test_rtprecv.c create mode 100644 linphone/mediastreamer/test_smpeg.c create mode 100644 linphone/mediastreamer/test_speex.c create mode 100644 linphone/mediastreamer/test_truespeech.c create mode 100644 linphone/mediastreamer/test_v4l.c create mode 100644 linphone/mediastreamer/test_videostream.c create mode 100644 linphone/mediastreamer/test_xine.c create mode 100644 linphone/mediastreamer/videoclient.c create mode 100644 linphone/mediastreamer/videoserver.c create mode 100644 linphone/mediastreamer/videostream.c create mode 100644 linphone/mediastreamer/waveheader.h create mode 100644 linphone/mediastreamer2/.cvsignore create mode 100644 linphone/mediastreamer2/.indent.pro create mode 100644 linphone/mediastreamer2/AUTHORS create mode 100644 linphone/mediastreamer2/COPYING create mode 100644 linphone/mediastreamer2/ChangeLog create mode 100644 linphone/mediastreamer2/INSTALL create mode 100644 linphone/mediastreamer2/Makefile.am create mode 100644 linphone/mediastreamer2/Makefile.macosx create mode 100644 linphone/mediastreamer2/NEWS create mode 100644 linphone/mediastreamer2/README create mode 100644 linphone/mediastreamer2/acinclude.m4 create mode 100755 linphone/mediastreamer2/autogen.sh create mode 100644 linphone/mediastreamer2/build/.cvsignore create mode 100755 linphone/mediastreamer2/build/Makefile.am create mode 100644 linphone/mediastreamer2/build/win32-novideo/.cvsignore create mode 100755 linphone/mediastreamer2/build/win32-novideo/Makefile.am create mode 100755 linphone/mediastreamer2/build/win32-novideo/alldescs.h create mode 100755 linphone/mediastreamer2/build/win32-novideo/mediastream.dev create mode 100755 linphone/mediastreamer2/build/win32-novideo/mediastream.vcproj create mode 100755 linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def create mode 100755 linphone/mediastreamer2/build/win32-novideo/mediastreamer2.dev create mode 100755 linphone/mediastreamer2/build/win32-novideo/mediastreamer2.vcproj create mode 100644 linphone/mediastreamer2/build/win32native/.cvsignore create mode 100755 linphone/mediastreamer2/build/win32native/Makefile.am create mode 100755 linphone/mediastreamer2/build/win32native/alldescs.h create mode 100755 linphone/mediastreamer2/build/win32native/mediastream.dev create mode 100755 linphone/mediastreamer2/build/win32native/mediastream.vcproj create mode 100755 linphone/mediastreamer2/build/win32native/mediastreamer2.def create mode 100755 linphone/mediastreamer2/build/win32native/mediastreamer2.dev create mode 100755 linphone/mediastreamer2/build/win32native/mediastreamer2.vcproj create mode 100755 linphone/mediastreamer2/build/win32native/videodisplay.vcproj create mode 100644 linphone/mediastreamer2/build/wince/.cvsignore create mode 100755 linphone/mediastreamer2/build/wince/Makefile.am create mode 100644 linphone/mediastreamer2/build/wince/alldescs.h create mode 100644 linphone/mediastreamer2/build/wince/mediastreamer2.def create mode 100644 linphone/mediastreamer2/build/wince/mediastreamer2.vcproj create mode 100644 linphone/mediastreamer2/configure.ac create mode 100644 linphone/mediastreamer2/help/DoxyFile.in create mode 100644 linphone/mediastreamer2/help/Makefile.am create mode 100644 linphone/mediastreamer2/help/doxygen.dox.in create mode 100644 linphone/mediastreamer2/help/ht0-buildagraph.dox create mode 100644 linphone/mediastreamer2/include/.cvsignore create mode 100644 linphone/mediastreamer2/include/Makefile.am create mode 100644 linphone/mediastreamer2/include/mediastreamer2/.cvsignore create mode 100644 linphone/mediastreamer2/include/mediastreamer2/Makefile.am create mode 100644 linphone/mediastreamer2/include/mediastreamer2/allfilters.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/dtmfgen.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/ice.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/mediastream.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/mscommon.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msfileplayer.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msfilerec.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msfilter.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msqueue.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msrtp.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/mssndcard.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/mstee.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msticker.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msv4l.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msvideo.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msvideoout.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/msvolume.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/mswebcam.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/rfc3984.h create mode 100644 linphone/mediastreamer2/include/mediastreamer2/waveheader.h create mode 100644 linphone/mediastreamer2/mediastreamer.pc.in create mode 100644 linphone/mediastreamer2/mediastreamer2.spec.in create mode 100644 linphone/mediastreamer2/pkg.list create mode 100644 linphone/mediastreamer2/plugins/.cvsignore create mode 100644 linphone/mediastreamer2/plugins/msilbc/AUTHORS create mode 100644 linphone/mediastreamer2/plugins/msilbc/COPYING create mode 100644 linphone/mediastreamer2/plugins/msilbc/ChangeLog create mode 100644 linphone/mediastreamer2/plugins/msilbc/INSTALL create mode 100644 linphone/mediastreamer2/plugins/msilbc/Makefile.am create mode 100644 linphone/mediastreamer2/plugins/msilbc/NEWS create mode 100644 linphone/mediastreamer2/plugins/msilbc/README create mode 100644 linphone/mediastreamer2/plugins/msilbc/configure.ac create mode 100644 linphone/mediastreamer2/plugins/msilbc/ilbc-rfc3951.tar.gz create mode 100644 linphone/mediastreamer2/plugins/msilbc/ilbc.c create mode 100644 linphone/mediastreamer2/plugins/msx264/AUTHORS create mode 100644 linphone/mediastreamer2/plugins/msx264/COPYING create mode 100644 linphone/mediastreamer2/plugins/msx264/ChangeLog create mode 100644 linphone/mediastreamer2/plugins/msx264/INSTALL create mode 100644 linphone/mediastreamer2/plugins/msx264/Makefile.am create mode 100644 linphone/mediastreamer2/plugins/msx264/NEWS create mode 100644 linphone/mediastreamer2/plugins/msx264/README create mode 100755 linphone/mediastreamer2/plugins/msx264/autogen.sh create mode 100644 linphone/mediastreamer2/plugins/msx264/configure.ac create mode 100755 linphone/mediastreamer2/plugins/msx264/msx264.dev create mode 100755 linphone/mediastreamer2/plugins/msx264/msx264.iss create mode 100644 linphone/mediastreamer2/plugins/msx264/src/Makefile.am create mode 100644 linphone/mediastreamer2/plugins/msx264/src/msx264.c create mode 100644 linphone/mediastreamer2/src/.cvsignore create mode 100644 linphone/mediastreamer2/src/Makefile.am create mode 100644 linphone/mediastreamer2/src/alaw.c create mode 100644 linphone/mediastreamer2/src/alsa.c create mode 100644 linphone/mediastreamer2/src/arts.c create mode 100644 linphone/mediastreamer2/src/audiostream.c create mode 100644 linphone/mediastreamer2/src/dtmfgen.c create mode 100644 linphone/mediastreamer2/src/dxfilter.cpp create mode 100644 linphone/mediastreamer2/src/dxfilter.h create mode 100644 linphone/mediastreamer2/src/ffmpeg-priv.h create mode 100644 linphone/mediastreamer2/src/g711common.h create mode 100644 linphone/mediastreamer2/src/gsm.c create mode 100644 linphone/mediastreamer2/src/ice.c create mode 100644 linphone/mediastreamer2/src/macsnd.c create mode 100644 linphone/mediastreamer2/src/mire.c create mode 100644 linphone/mediastreamer2/src/mscommon.c create mode 100644 linphone/mediastreamer2/src/msconf.c create mode 100644 linphone/mediastreamer2/src/msfileplayer.c create mode 100644 linphone/mediastreamer2/src/msfileplayer_win.c create mode 100644 linphone/mediastreamer2/src/msfilerec.c create mode 100644 linphone/mediastreamer2/src/msfilerec_win.c create mode 100644 linphone/mediastreamer2/src/msfilter.c create mode 100644 linphone/mediastreamer2/src/msjoin.c create mode 100644 linphone/mediastreamer2/src/msqueue.c create mode 100644 linphone/mediastreamer2/src/msresample.c create mode 100644 linphone/mediastreamer2/src/msrtp.c create mode 100644 linphone/mediastreamer2/src/mssndcard.c create mode 100644 linphone/mediastreamer2/src/msspeex.c create mode 100644 linphone/mediastreamer2/src/msticker.c create mode 100644 linphone/mediastreamer2/src/msv4l.c create mode 100644 linphone/mediastreamer2/src/msv4l2.c create mode 100644 linphone/mediastreamer2/src/msv4m.c create mode 100644 linphone/mediastreamer2/src/msvideo.c create mode 100644 linphone/mediastreamer2/src/msvolume.c create mode 100644 linphone/mediastreamer2/src/mswebcam.c create mode 100644 linphone/mediastreamer2/src/mtu.c create mode 100644 linphone/mediastreamer2/src/nowebcam.c create mode 100644 linphone/mediastreamer2/src/nowebcam.h create mode 100644 linphone/mediastreamer2/src/nowebcamCIF.jpg create mode 100644 linphone/mediastreamer2/src/oss.c create mode 100644 linphone/mediastreamer2/src/pasnd.c create mode 100644 linphone/mediastreamer2/src/pixconv.c create mode 100644 linphone/mediastreamer2/src/rfc2429.h create mode 100644 linphone/mediastreamer2/src/rfc3984.c create mode 100644 linphone/mediastreamer2/src/sdlout.c create mode 100644 linphone/mediastreamer2/src/sizeconv.c create mode 100644 linphone/mediastreamer2/src/speexec.c create mode 100644 linphone/mediastreamer2/src/swscale.h create mode 100644 linphone/mediastreamer2/src/tee.c create mode 100644 linphone/mediastreamer2/src/theora.c create mode 100644 linphone/mediastreamer2/src/ulaw.c create mode 100755 linphone/mediastreamer2/src/vfw-missing.h create mode 100644 linphone/mediastreamer2/src/videodec.c create mode 100644 linphone/mediastreamer2/src/videoenc.c create mode 100644 linphone/mediastreamer2/src/videoout.c create mode 100644 linphone/mediastreamer2/src/videostream.c create mode 100644 linphone/mediastreamer2/src/wincevideods.c create mode 100644 linphone/mediastreamer2/src/winsnd.c create mode 100755 linphone/mediastreamer2/src/winsnd2.c create mode 100644 linphone/mediastreamer2/src/winsndds.cpp create mode 100644 linphone/mediastreamer2/src/winvideo.c create mode 100644 linphone/mediastreamer2/src/winvideods.c create mode 100644 linphone/mediastreamer2/tests/.cvsignore create mode 100644 linphone/mediastreamer2/tests/Makefile.am create mode 100644 linphone/mediastreamer2/tests/echo.c create mode 100644 linphone/mediastreamer2/tests/mediastream.c create mode 100644 linphone/mediastreamer2/tests/mtudiscover.c create mode 100644 linphone/mediastreamer2/tests/ring.c create mode 100644 linphone/mediastreamer2/tests/videodisplay.c create mode 100644 linphone/oRTP/.cvsignore create mode 100644 linphone/oRTP/AUTHORS create mode 100644 linphone/oRTP/COPYING create mode 100644 linphone/oRTP/ChangeLog create mode 100644 linphone/oRTP/INSTALL create mode 100644 linphone/oRTP/Makefile.am create mode 100644 linphone/oRTP/NEWS create mode 100644 linphone/oRTP/README create mode 100644 linphone/oRTP/TODO create mode 100755 linphone/oRTP/autogen.sh create mode 100644 linphone/oRTP/build/.cvsignore create mode 100644 linphone/oRTP/build/Makefile.am create mode 100644 linphone/oRTP/build/win32/.cvsignore create mode 100644 linphone/oRTP/build/win32native/.cvsignore create mode 100644 linphone/oRTP/build/win32native/Makefile.am create mode 100644 linphone/oRTP/build/win32native/oRTP.vcproj create mode 100755 linphone/oRTP/build/win32native/ortp-dll.dev create mode 100755 linphone/oRTP/build/win32native/ortp-static.dev create mode 100755 linphone/oRTP/build/win32native/ortp.def create mode 100755 linphone/oRTP/build/win32native/ortp.dev create mode 100644 linphone/oRTP/build/wince/.cvsignore create mode 100644 linphone/oRTP/build/wince/Makefile.am create mode 100644 linphone/oRTP/build/wince/oRTP.vcproj create mode 100644 linphone/oRTP/build/wince/ortp.def create mode 100644 linphone/oRTP/configure.ac create mode 100644 linphone/oRTP/docs/.cvsignore create mode 100644 linphone/oRTP/include/.cvsignore create mode 100644 linphone/oRTP/include/Makefile.am create mode 100644 linphone/oRTP/include/ortp/.cvsignore create mode 100644 linphone/oRTP/include/ortp/Makefile.am create mode 100644 linphone/oRTP/include/ortp/b64.h create mode 100644 linphone/oRTP/include/ortp/event.h create mode 100644 linphone/oRTP/include/ortp/ortp.h create mode 100644 linphone/oRTP/include/ortp/payloadtype.h create mode 100644 linphone/oRTP/include/ortp/port.h create mode 100644 linphone/oRTP/include/ortp/rtcp.h create mode 100644 linphone/oRTP/include/ortp/rtp.h create mode 100644 linphone/oRTP/include/ortp/rtpsession.h create mode 100644 linphone/oRTP/include/ortp/rtpsignaltable.h create mode 100644 linphone/oRTP/include/ortp/sessionset.h create mode 100644 linphone/oRTP/include/ortp/srtp.h create mode 100644 linphone/oRTP/include/ortp/str_utils.h create mode 100644 linphone/oRTP/include/ortp/stun.h create mode 100644 linphone/oRTP/include/ortp/stun_udp.h create mode 100644 linphone/oRTP/include/ortp/telephonyevents.h create mode 100644 linphone/oRTP/oRTP.prj create mode 100644 linphone/oRTP/oRTP.pws create mode 100644 linphone/oRTP/ortp.doxygen.in create mode 100644 linphone/oRTP/ortp.pc.in create mode 100644 linphone/oRTP/ortp.spec.in create mode 100644 linphone/oRTP/pkg.list create mode 100644 linphone/oRTP/src/.cvsignore create mode 100644 linphone/oRTP/src/Makefile.am create mode 100644 linphone/oRTP/src/avprofile.c create mode 100644 linphone/oRTP/src/b64.c create mode 100644 linphone/oRTP/src/dll_entry.c create mode 100644 linphone/oRTP/src/event.c create mode 100644 linphone/oRTP/src/jitterctl.c create mode 100644 linphone/oRTP/src/jitterctl.h create mode 100644 linphone/oRTP/src/master create mode 100644 linphone/oRTP/src/ortp-config-win32.h create mode 100644 linphone/oRTP/src/ortp.c create mode 100644 linphone/oRTP/src/payloadtype.c create mode 100644 linphone/oRTP/src/port.c create mode 100644 linphone/oRTP/src/posixtimer.c create mode 100644 linphone/oRTP/src/rtcp.c create mode 100644 linphone/oRTP/src/rtcpparse.c create mode 100644 linphone/oRTP/src/rtpparse.c create mode 100644 linphone/oRTP/src/rtpsession.c create mode 100644 linphone/oRTP/src/rtpsession_inet.c create mode 100644 linphone/oRTP/src/rtpsession_priv.h create mode 100644 linphone/oRTP/src/rtpsignaltable.c create mode 100644 linphone/oRTP/src/rtptimer.c create mode 100644 linphone/oRTP/src/rtptimer.h create mode 100644 linphone/oRTP/src/scheduler.c create mode 100644 linphone/oRTP/src/scheduler.h create mode 100644 linphone/oRTP/src/sessionset.c create mode 100644 linphone/oRTP/src/srtp.c create mode 100644 linphone/oRTP/src/str_utils.c create mode 100644 linphone/oRTP/src/stun.c create mode 100644 linphone/oRTP/src/stun_udp.c create mode 100644 linphone/oRTP/src/system create mode 100644 linphone/oRTP/src/telephonyevents.c create mode 100644 linphone/oRTP/src/tests/.cvsignore create mode 100644 linphone/oRTP/src/tests/Makefile.am create mode 100644 linphone/oRTP/src/tests/mrtprecv.c create mode 100644 linphone/oRTP/src/tests/mrtpsend.c create mode 100644 linphone/oRTP/src/tests/rtpmemtest.c create mode 100644 linphone/oRTP/src/tests/rtprecv.c create mode 100644 linphone/oRTP/src/tests/rtpsend.c create mode 100644 linphone/oRTP/src/tests/rtpsend_stupid.c create mode 100644 linphone/oRTP/src/tests/test_timer.c create mode 100644 linphone/oRTP/src/tests/tevmrtprecv.c create mode 100644 linphone/oRTP/src/tests/tevrtprecv.c create mode 100644 linphone/oRTP/src/tests/tevrtpsend.c create mode 100644 linphone/oRTP/src/tests/win_receiver/.cvsignore create mode 100644 linphone/oRTP/src/tests/win_receiver/Makefile.am create mode 100644 linphone/oRTP/src/tests/win_receiver/RTPReceiver.cpp create mode 100644 linphone/oRTP/src/tests/win_receiver/RTPReceiver.vcproj create mode 100755 linphone/oRTP/src/tests/win_receiver/ortpreceiver.dev create mode 100644 linphone/oRTP/src/tests/win_sender/.cvsignore create mode 100644 linphone/oRTP/src/tests/win_sender/Makefile.am create mode 100644 linphone/oRTP/src/tests/win_sender/RTPSender.cpp create mode 100644 linphone/oRTP/src/tests/win_sender/RTPSender.vcproj create mode 100755 linphone/oRTP/src/tests/win_sender/ortpsender.dev create mode 100644 linphone/oRTP/src/utils.c create mode 100644 linphone/oRTP/src/utils.h create mode 100644 linphone/pixmaps/.cvsignore create mode 100644 linphone/pixmaps/Makefile.am create mode 100644 linphone/pixmaps/linphone.png create mode 100644 linphone/pixmaps/linphone2.png create mode 100644 linphone/pixmaps/linphone2.xpm create mode 100644 linphone/pixmaps/sip-away.png create mode 100644 linphone/pixmaps/sip-bifm.png create mode 100644 linphone/pixmaps/sip-busy.png create mode 100644 linphone/pixmaps/sip-closed.png create mode 100644 linphone/pixmaps/sip-online.png create mode 100644 linphone/pixmaps/sip-otl.png create mode 100644 linphone/pixmaps/sip-otp.png create mode 100644 linphone/pixmaps/sip-wfa.png create mode 100644 linphone/po/.cvsignore create mode 100644 linphone/po/ChangeLog create mode 100644 linphone/po/Makefile.in.in create mode 100644 linphone/po/Makevars create mode 100644 linphone/po/Makevars.template create mode 100644 linphone/po/POTFILES.in create mode 100644 linphone/po/Rules-quot create mode 100644 linphone/po/boldquot.sed create mode 100644 linphone/po/cat-id-tbl.c create mode 100644 linphone/po/cs.po create mode 100644 linphone/po/de.po create mode 100644 linphone/po/en@boldquot.header create mode 100644 linphone/po/en@quot.header create mode 100644 linphone/po/es.po create mode 100644 linphone/po/fr.po create mode 100644 linphone/po/hu.po create mode 100644 linphone/po/insert-header.sin create mode 100644 linphone/po/it.po create mode 100644 linphone/po/ja.po create mode 100644 linphone/po/linphone.pot create mode 100644 linphone/po/nl.po create mode 100644 linphone/po/pl.po create mode 100644 linphone/po/pt_BR.po create mode 100644 linphone/po/quot.sed create mode 100644 linphone/po/remove-potcdate.sin create mode 100644 linphone/po/sv.po create mode 100755 linphone/reconfig-SuSE create mode 100644 linphone/share/.cvsignore create mode 100644 linphone/share/C/.cvsignore create mode 100644 linphone/share/C/Makefile.am create mode 100644 linphone/share/C/linphone.1 create mode 100644 linphone/share/C/linphonec.1 create mode 100644 linphone/share/C/manual.lyx create mode 100644 linphone/share/C/manual.sgml create mode 100644 linphone/share/C/manual/.cvsignore create mode 100644 linphone/share/C/sipomatic.1 create mode 100644 linphone/share/Makefile.am create mode 100644 linphone/share/Makefile.inc create mode 100644 linphone/share/cs/.cvsignore create mode 100644 linphone/share/cs/Makefile.am create mode 100644 linphone/share/cs/linphone.1 create mode 100644 linphone/share/cs/linphonec.1 create mode 100644 linphone/share/cs/sipomatic.1 create mode 100644 linphone/share/fr/.cvsignore create mode 100644 linphone/share/fr/Makefile.am create mode 100644 linphone/share/fr/manual.lyx create mode 100644 linphone/share/fr/manual.sgml create mode 100644 linphone/share/fr/manual/.cvsignore create mode 100644 linphone/share/hello16000.wav create mode 100644 linphone/share/hello8000.wav create mode 100644 linphone/share/it/.cvsignore create mode 100644 linphone/share/it/Makefile.am create mode 100644 linphone/share/it/manual.lyx create mode 100644 linphone/share/it/manual.sgml create mode 100644 linphone/share/it/manual/.cvsignore create mode 100644 linphone/share/ja/.cvsignore create mode 100644 linphone/share/ja/Makefile.am create mode 100644 linphone/share/ja/manual.lyx create mode 100644 linphone/share/ja/manual.sgml create mode 100644 linphone/share/ja/manual/.cvsignore create mode 100644 linphone/share/linphone.desktop create mode 100644 linphone/share/linphone.gnorba create mode 100644 linphone/share/linphone.pc.in create mode 100644 linphone/share/linphone_applet.desktop create mode 100644 linphone/share/ringback.wav create mode 100644 linphone/share/rings/bigben.wav create mode 100644 linphone/share/rings/oldphone.wav create mode 100644 linphone/share/rings/orig.wav create mode 100644 linphone/share/rings/rock.wav create mode 100644 linphone/share/rings/sweet.wav create mode 100644 linphone/share/rings/synth.wav create mode 100644 linphone/share/rings/tapping.wav create mode 100644 linphone/share/rings/toy.wav create mode 100644 linphone/stamp-h.in create mode 100644 linphone/support/.cvsignore create mode 100755 linphone/win32/config.h create mode 100755 linphone/win32/liblinphone.dev create mode 100644 linphone/win32acm/CODECS create mode 100644 linphone/win32acm/CREDITS create mode 100644 linphone/win32acm/Makefile create mode 100644 linphone/win32acm/README create mode 100644 linphone/win32acm/TODO create mode 100644 linphone/win32acm/afl.c create mode 100644 linphone/win32acm/com.h create mode 100644 linphone/win32acm/config.h create mode 100644 linphone/win32acm/config.h.bak create mode 100644 linphone/win32acm/cpudetect.c create mode 100644 linphone/win32acm/cpudetect.h create mode 100644 linphone/win32acm/cputable.h create mode 100644 linphone/win32acm/driver.c create mode 100644 linphone/win32acm/driver.h create mode 100644 linphone/win32acm/elfdll.c create mode 100644 linphone/win32acm/ext.c create mode 100644 linphone/win32acm/ext.h create mode 100644 linphone/win32acm/ldt_keeper.c create mode 100644 linphone/win32acm/ldt_keeper.h create mode 100644 linphone/win32acm/loader.h create mode 100755 linphone/win32acm/loader_objfix.sh create mode 100644 linphone/win32acm/module.c create mode 100644 linphone/win32acm/mp_msg.c create mode 100644 linphone/win32acm/mp_msg.h create mode 100644 linphone/win32acm/pcmin.raw create mode 100644 linphone/win32acm/pe_image.c create mode 100644 linphone/win32acm/pe_resource.c create mode 100644 linphone/win32acm/registry.c create mode 100644 linphone/win32acm/registry.h create mode 100644 linphone/win32acm/resource.c create mode 100644 linphone/win32acm/stubs.s create mode 100644 linphone/win32acm/test_truespeech.c create mode 100644 linphone/win32acm/win32.c create mode 100644 linphone/win32acm/win32.h create mode 100644 linphone/win32acm/win32codec.c create mode 100644 linphone/win32acm/win32codec.h create mode 100644 linphone/win32acm/wine/basetsd.h create mode 100644 linphone/win32acm/wine/debugtools.h create mode 100644 linphone/win32acm/wine/driver.h create mode 100644 linphone/win32acm/wine/elfdll.h create mode 100644 linphone/win32acm/wine/heap.h create mode 100644 linphone/win32acm/wine/ldt.h create mode 100644 linphone/win32acm/wine/mmreg.h create mode 100644 linphone/win32acm/wine/module.h create mode 100644 linphone/win32acm/wine/msacm.h create mode 100644 linphone/win32acm/wine/msacmdrv.h create mode 100644 linphone/win32acm/wine/ntdef.h create mode 100644 linphone/win32acm/wine/pe_image.h create mode 100644 linphone/win32acm/wine/poppack.h create mode 100644 linphone/win32acm/wine/pshpack1.h create mode 100644 linphone/win32acm/wine/pshpack2.h create mode 100644 linphone/win32acm/wine/pshpack4.h create mode 100644 linphone/win32acm/wine/pshpack8.h create mode 100644 linphone/win32acm/wine/vfw.h create mode 100644 linphone/win32acm/wine/winbase.h create mode 100644 linphone/win32acm/wine/windef.h create mode 100644 linphone/win32acm/wine/windows.h create mode 100644 linphone/win32acm/wine/winerror.h create mode 100644 linphone/win32acm/wine/winestring.h create mode 100644 linphone/win32acm/wine/winnt.h create mode 100644 linphone/win32acm/wine/winreg.h create mode 100644 linphone/win32acm/wine/winuser.h create mode 100644 linphone/win32acm/wineacm.h create mode 100644 linphone/win32acm/wrapper.S create mode 100644 linphone/win32acm/wrapper.h create mode 100644 p2pproxy/.classpath create mode 100644 p2pproxy/.cvsignore create mode 100644 p2pproxy/.gcjbuilder create mode 100644 p2pproxy/.project create mode 100644 p2pproxy/bin/p2pproxy-cmd.bat create mode 100644 p2pproxy/bin/p2pproxy-cmd.sh create mode 100644 p2pproxy/bin/p2pproxy.bat create mode 100644 p2pproxy/bin/p2pproxy.sh create mode 100644 p2pproxy/build.xml create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangeRequest.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangedAddress.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Data.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Dummy.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ErrorCode.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedAddress.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedResponseChangedSourceAddressReflectedFrom.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttribute.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeException.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeInterface.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeParsingException.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageIntegrity.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Password.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ReflectedFrom.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ResponseAddress.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/SourceAddress.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownAttribute.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownMessageAttributeException.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Username.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeader.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderException.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderInterface.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderParsingException.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/BindingLifetimeTest.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryInfo.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryTest.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/BindingLifetimeTestDemo.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/DiscoveryTestDemo.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/StunServer.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/Candidate.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/ICENegociator.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Address.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Utility.java create mode 100644 p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/UtilityException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/pom.xml create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/Version.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/AccessService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Codat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/CodatID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Metadata.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/AuthenticationCredential.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/Credential.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/CredentialPCLSupport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/CredentialValidator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/PrivilegedOperation.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/discovery/DiscoveryEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/discovery/DiscoveryListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/discovery/DiscoveryService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/discovery/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/Advertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/AdvertisementFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/Attributable.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/Attribute.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/BinaryDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/Document.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/DocumentByteArrayIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/DocumentByteBufferIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/DocumentStreamIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/Element.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/ExtendableAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/FileDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/MimeMediaType.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/StructuredDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/StructuredDocumentFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/StructuredDocumentUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/StructuredTextDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextDocumentCharArrayIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextDocumentCharBufferIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextDocumentCharSequenceIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextDocumentReaderIO.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/TextElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/XMLDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/XMLElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/document/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/AbstractMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/AsyncChannelMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/ByteArrayMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/ChannelMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/EndpointAddress.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/EndpointListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/EndpointService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/InputStreamMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/ListenerAdaptor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/Message.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessageFilterListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessagePropagater.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessageReceiver.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessageSender.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessageTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/Messenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessengerEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessengerEventListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/MessengerState.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/OutgoingMessageEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/OutgoingMessageEventListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/StringMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/TextDocumentMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/TextMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/ThreadedMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/WireFormatMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/WireFormatMessageFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/ConfiguratorException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/JxtaError.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/JxtaException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/PeerGroupException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/ProtocolNotSupportedException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/ServiceNotFoundException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/UnknownServiceException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/exception/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/ID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/IDFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/jxta/IDFormat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/jxta/Instantiator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/jxta/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/id/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/logging/Logging.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/logging/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/membership/Authenticator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/membership/InteractiveAuthenticator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/membership/MembershipService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/membership/doc-files/memberAndAccess.png create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/membership/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorFilterException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorReport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/MonitorResources.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/PeerMonitorInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/PeerMonitorInfoEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/PeerMonitorInfoListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/ServiceMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/ServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/ServiceMonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/meter/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/overview.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peer/PeerID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peer/PeerInfoEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peer/PeerInfoListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peer/PeerInfoService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peer/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/Configurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/LightWeightPeerGroup.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/NetPeerGroupFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/PeerGroup.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/PeerGroupFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/PeerGroupID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/WorldPeerGroupFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/peergroup/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/InputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/OutputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/OutputPipeEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/OutputPipeListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/PipeID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/PipeMsgEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/PipeMsgListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/PipeService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/pipe/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/Application.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/JxtaLoader.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/Module.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/ModuleClassID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/ModuleSpecID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/NetworkConfigurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/NetworkManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/platform/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/AccessPointAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ConfigParams.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/DiscoveryQueryMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/DiscoveryResponseMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ModuleClassAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ModuleImplAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ModuleSpecAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PeerAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PeerGroupAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PeerInfoQueryMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PeerInfoResponseMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PipeAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/PipeResolverMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/RdvAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ResolverQueryMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ResolverResponseMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/ResolverSrdiMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/RouteAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/RouteQueryMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/RouteResponseMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/SignedAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/SrdiMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/TransportAdvertisement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/protocol/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/rendezvous/RendezVousService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/rendezvous/RendezVousStatus.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/rendezvous/RendezvousEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/rendezvous/RendezvousListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/rendezvous/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/resolver/GenericResolver.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/resolver/QueryHandler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/resolver/ResolverService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/resolver/SrdiHandler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/resolver/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/service/Service.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/service/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaMulticastSocket.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaServerSocket.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaSocket.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaSocketAddress.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaSocketInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/JxtaSocketOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/socket/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/user.properties create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/AbstractSimpleSelectable.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/AdvertisementUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/AwtUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/ClassFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/CountingInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/CountingOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/CountingWriter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/DevNullOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/DevNullWriter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/DocumentUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/IgnoreFlushFilterOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/JxtaBiDiPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/JxtaServerPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/LimitInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/MarkProhibitedFilterStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/MessageUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/PipeEventListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/PipeStateListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/PipeUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/SimpleSelectable.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/SimpleSelector.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/WatchedInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/WatchedOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/WatchedStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/documentSerializable/DocumentSerializable.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/documentSerializable/DocumentSerializableUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/documentSerializable/DocumentSerializationException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/util/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/api/src/sun/net/www/protocol/urn/Handler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/META-INF/services/net.jxta.document.Advertisement create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/META-INF/services/net.jxta.document.StructuredDocument create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/META-INF/services/net.jxta.endpoint.WireFormatMessage create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/META-INF/services/net.jxta.id.ID create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/META-INF/services/net.jxta.platform.Module create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/Version.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/AccessList.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/always/AlwaysAccessService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/always/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/pse/PSEAccessService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/pse/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/simpleACL/SimpleACLAccessService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/simpleACL/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/cm/Cm.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/cm/Indexer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/cm/Srdi.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/cm/SrdiIndex.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/config.properties create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/discovery/DiscoveryServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/discovery/DiscoveryServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/discovery/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/DOMXMLDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/DOMXMLElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/LiteXMLDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/LiteXMLElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/PlainTextDocument.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/PlainTextElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/TextDocumentCommon.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/BlockingMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/EndpointServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/EndpointServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/EndpointUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/IPUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/JxtaMessageMessageElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/LoopbackMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/SocketFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/WireFormatMessageBinary.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/cbjx/CbJxDefs.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/cbjx/CbJxMessageInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/cbjx/CbJxMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/cbjx/CbJxTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/cbjx/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/ConditionalEndpointMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointServiceMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/EndpointServiceMonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/InboundMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/InboundMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/IncomingMessageListenerMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/MessengerMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/OutboundMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/OutboundMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/PropagationMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/endpointMeter/PropagationMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/mcast/McastTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/mcast/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/msgframing/MessagePackageHeader.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/msgframing/WelcomeMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/RelayClient.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/RelayReferralSeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/RelayServer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/RelayServerClient.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/RelayTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/relay/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/BadRoute.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/Destinations.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/EndpointRouter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/EndpointRouterMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/RouteCM.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/RouteControl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/RouteResolver.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/RouterMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/router/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/HttpClientMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/HttpMessageReceiver.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/HttpMessageSender.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/HttpMessageServlet.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/HttpServletMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/ServletHttpTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/servlethttp/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tcp/IncomingUnicastServer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tcp/TcpMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tcp/TcpTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tcp/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/JTlsDefs.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/JTlsInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/JTlsOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/TlsConn.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/TlsManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/TlsMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/TlsSocket.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/TlsTransport.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/tls/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/ConditionalTransportMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportBindingMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportBindingMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportServiceMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/endpoint/transportMeter/TransportServiceMonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/CodatID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/IDFormat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/Instantiator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/ModuleClassID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/ModuleSpecID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/PeerGroupID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/PeerID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/PipeID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/CBID/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/CodatID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/IDBytes.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/IDFormat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/Instantiator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/ModuleClassID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/ModuleSpecID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/PeerGroupID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/PeerID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/PipeID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/UUID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/UUIDFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/UUID/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/BinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/BinaryIDFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/CodatBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/DigestTool.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/IDFormat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/Instantiator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/ModuleClassBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/ModuleSpecBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/PeerBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/PeerGroupBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/PipeBinaryID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/binaryID/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/unknown/ID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/unknown/IDFormat.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/unknown/Instantiator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/id/unknown/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/loader/RefJxtaLoader.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/loader/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/PasswdMembershipService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/none/NoneMembershipService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/none/NoneMembershipServiceBeanInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/none/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/passwd/PasswdMembershipService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/passwd/PasswdMembershipServiceBeanInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/passwd/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/CMKeyStoreManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/DialogAuthenticator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/EngineAuthenticator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/FileKeyStoreManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/KeyStoreManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEAuthenticatorEngine.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEAuthenticatorEngineFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEConfig.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSECredential.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSECrendentialBeanInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEKeyStoreManagerFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEMembershipService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEMembershipServiceBeanInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEPeerSecurityEngine.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSESecurityEngineFactory.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/PSEUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/StringAuthenticator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/URIKeyStoreManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/membership/pse/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/ConditionalMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/GenericServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/MeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/MetricUtilities.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/MonitorManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/ServiceMonitorImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/ServiceMonitorPulseInfo.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/meter/ServiceMonitorResource.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/monitor.properties create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/overview.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/PeerInfoHandler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/PeerInfoMessenger.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/PeerInfoServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/PeerInfoServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/RemoteMonitorPeerInfoHandler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/RemoteMonitorQuery.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/RemoteMonitorResponse.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peer/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/AutomaticConfigurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/Boot.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/CompatibilityEquater.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/ConfigDialog.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/DefaultConfigurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/GenericPeerGroup.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/IncompleteConfigurationException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/NullConfigurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/PeerGroupInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/Platform.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/PlatformConfigurator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/RefCountPeerGroupInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/ShadowPeerGroup.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/StdPeerGroup.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/StdPeerGroupParamAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/BlockingWireOutputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/InputPipeImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/NonBlockingOutputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/NonBlockingWireOutputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/PipeRegistrar.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/PipeResolver.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/PipeServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/PipeServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/SecureInputPipeImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/SecureOutputPipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/WireHeader.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/WirePipe.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/WirePipeImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/pipe/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/AccessPointAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/Certificate.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/CertificateSigningRequest.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/DiscoveryConfigAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/DiscoveryQuery.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/DiscoveryResponse.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/GroupConfig.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/HTTPAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/LeaseRequestMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/LeaseResponseMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/LimitedRangeRdvMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ModuleClassAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ModuleImplAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ModuleSpecAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PSEConfigAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PeerAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PeerGroupAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PeerGroupConfigAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PeerInfoQueryMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PeerInfoResponseMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PipeAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PipeResolverMsg.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/PlatformConfig.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RdvAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RdvConfigAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RelayConfigAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ResolverQuery.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ResolverResponse.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/ResolverSrdiMsgImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RouteAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RouteQuery.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/RouteResponse.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/SignedAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/SrdiMessageImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/TCPAdv.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/proxy/ProxyService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/proxy/Requestor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/PeerConnection.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RdvGreeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RdvWalk.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RdvWalker.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RendezVousPropagateMessage.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RendezVousServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RendezVousServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/RendezVousServiceProvider.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/StdRendezVousService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/adhoc/AdhocPeerRdvService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/edge/EdgePeerRdvService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/edge/RdvConnection.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/limited/LimitedRangeGreeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/limited/LimitedRangeWalk.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/limited/LimitedRangeWalker.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rdv/ClientConnection.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rdv/RdvPeerRdvService.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/ClientConnectionMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/ClientConnectionMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/ConditionalRendezvousMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousConnectionMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousConnectionMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousServiceMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rendezvousMeter/RendezvousServiceMonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerView.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewDestination.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewElement.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewEvent.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewRandomStrategy.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewRandomWithReplaceStrategy.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewSequentialStrategy.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerViewStrategy.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/rpv/PeerviewSeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/InternalQueryHandler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/ResolverServiceImpl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/ResolverServiceInterface.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ConditionalResolverMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/QueryDestinationMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/QueryDestinationMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/QueryHandlerMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/QueryHandlerMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverMeterBuildSettings.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverServiceMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverServiceMonitor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/ResolverServiceMonitorFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/SrdiDestinationMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/SrdiDestinationMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/SrdiHandlerMeter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/resolver/resolverMeter/SrdiHandlerMetric.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ACLSeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/AdvCooker.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/BASE64InputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/BASE64OutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/Base64.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/Cache.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/CacheEntry.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/CacheEntryListener.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ConsumerBiasedQueue.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/Dlink.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/Dlist.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/DynamicEnumeration.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/EndpointServiceStatsFilter.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/GenerateID.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/JxtaHash.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/LRUCache.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ModuleManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ProducerBiasedQueue.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/RdvAdvSeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ResourceAccount.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/ResourceDispatcher.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/SeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/SequenceIterator.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/TimeUtils.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/TimerThreadNamer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/URISeedingManager.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/UnbiasedQueue.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/cm/DumpCm.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/package.html create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/AdaptiveFlowControl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/Defs.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/FixedFlowControl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/FlowControl.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/Incoming.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/IncomingPipeAdaptor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/Outgoing.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/OutgoingMsgrAdaptor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/OutgoingPipeAdaptor.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/OutgoingPipeAdaptorSync.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/ReliableInputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/util/pipe/reliable/ReliableOutputStream.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/Debug.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/DBException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/DBObject.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/FaultCodes.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/data/Key.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/data/Record.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/data/RecordSet.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/data/Value.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTree.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTreeCallback.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTreeCorruptException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTreeException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTreeFiler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/BTreeNotFoundException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/Filer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/FilerException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/MemFiler.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/Paged.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/filer/Streamable.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/indexer/IndexQuery.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/indexer/Indexer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/core/indexer/NameIndexer.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/util/Named.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/util/XindiceException.java create mode 100644 p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/xindice/util/XindiceRuntimeException.java create mode 100644 p2pproxy/dependencies/MJSIP.COPYRIGHT.txt create mode 100644 p2pproxy/dependencies/bcprov-jdk14.jar create mode 100644 p2pproxy/dependencies/bouncycastle-LICENSE.txt create mode 100644 p2pproxy/dependencies/javax.servlet.jar create mode 100644 p2pproxy/dependencies/jstun-0.7.0.jar create mode 100644 p2pproxy/dependencies/junit-4.3.1.jar create mode 100644 p2pproxy/dependencies/jxta_license.html create mode 100644 p2pproxy/dependencies/log4j.LICENSE create mode 100644 p2pproxy/dependencies/log4j.jar create mode 100644 p2pproxy/dependencies/org.mortbay.jetty.jar create mode 100644 p2pproxy/dependencies/sip.jar create mode 100644 p2pproxy/log4j.properties create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyException.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyInstance.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyManagement.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyNetworkProbe.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyRtpRelayManagement.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyUserAlreadyExistException.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/api/P2pProxyUserNotFoundException.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/Configurator.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/EdgePeerServiceManager.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/GenericService.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/GenericServiceClient.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/GenericUdpSession.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/JxtaNetworkManager.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/MessageDispatcher.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/NetworkResources.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyAccountManagement.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyAccountManagementMBean.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyAdvertisementNotFoundException.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyInstanceImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMainMBean.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyManagementImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/P2pUserProfileAdvertisement.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/SdpProcessor.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/SeedingPeerServiceManager.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/ServiceProvider.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/SipProxyRegistrar.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/SipProxyRegistrarMBean.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/SuperPeerServiceManager.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/jxtaext/EndpointRegistry.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/jxtaext/NatedEndPointAddress.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/jxtaudpproxy/RtpSession.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/jxtaudpproxy/RtpSessionImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/jxtaudpproxy/SdpProcessorImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/jxtaudpproxy/UdpSession.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/AddressRequest.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/AddressResponse.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/IceSdpProcessorImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/MediaType.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RouteAddRequest.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RouteAddResponse.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RoutingTable.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RtpRelayServer.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RtpRelayServerConfig.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RtpRelayService.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RtpRelayServiceClient.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/RtpRoutingRules.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/SdpProcessorImpl.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/media/rtprelay/SingleAddressResponse.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/AutoConfigService.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/P2pproxyRdvListener.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/PeerInfoProvider.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/PeerInfoProviderService.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/PeerInfoServiceClient.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/PublicIpAddressRequest.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/PublicIpAddressResponse.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/rdvautoconfig/SocketProbeRequest.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/turnserver/TurnServer.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/utils/AccountManagerCli.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/utils/DumpLocalCache.java create mode 100644 p2pproxy/src/org/linphone/p2pproxy/core/utils/PeerGroupIdGenerator.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/P2pAutoConfigTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/P2pProxyAccountManagementTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/P2pProxyNatedNetworkTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/P2pProxyNetworkingTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/P2pProxyTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/RtpRelayServerTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/TurnServerTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/UdpRelayTester.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/utils/DefaultCallListener.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/utils/P2pNetwork.java create mode 100644 p2pproxy/test-src/org/linphone/p2pproxy/test/utils/SipClient.java diff --git a/linphone/.cvsignore b/linphone/.cvsignore new file mode 100644 index 000000000..90955bc8d --- /dev/null +++ b/linphone/.cvsignore @@ -0,0 +1,24 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +install-sh +intltool-extract +intltool-merge +intltool-update +libtool +ltmain.sh +missing +mkinstalldirs +speex +stamp-h1 +linphone.spec diff --git a/linphone/ABOUT-NLS b/linphone/ABOUT-NLS new file mode 100644 index 000000000..ec20977e0 --- /dev/null +++ b/linphone/ABOUT-NLS @@ -0,0 +1,1101 @@ +1 Notes on the Free Translation Project +*************************************** + +Free software is going international! The Free Translation Project is +a way to get maintainers of free software, translators, and users all +together, so that free software will gradually become able to speak many +languages. A few packages already provide translations for their +messages. + + If you found this `ABOUT-NLS' file inside a distribution, you may +assume that the distributed package does use GNU `gettext' internally, +itself available at your nearest GNU archive site. But you do _not_ +need to install GNU `gettext' prior to configuring, installing or using +this package with messages translated. + + Installers will find here some useful hints. These notes also +explain how users should proceed for getting the programs to use the +available translations. They tell how people wanting to contribute and +work on translations can contact the appropriate team. + + When reporting bugs in the `intl/' directory or bugs which may be +related to internationalization, you should tell about the version of +`gettext' which is used. The information can be found in the +`intl/VERSION' file, in internationalized packages. + +1.1 Quick configuration advice +============================== + +If you want to exploit the full power of internationalization, you +should configure it using + + ./configure --with-included-gettext + +to force usage of internationalizing routines provided within this +package, despite the existence of internationalizing capabilities in the +operating system where this package is being installed. So far, only +the `gettext' implementation in the GNU C library version 2 provides as +many features (such as locale alias, message inheritance, automatic +charset conversion or plural form handling) as the implementation here. +It is also not possible to offer this additional functionality on top +of a `catgets' implementation. Future versions of GNU `gettext' will +very likely convey even more functionality. So it might be a good idea +to change to GNU `gettext' as soon as possible. + + So you need _not_ provide this option if you are using GNU libc 2 or +you have installed a recent copy of the GNU gettext package with the +included `libintl'. + +1.2 INSTALL Matters +=================== + +Some packages are "localizable" when properly installed; the programs +they contain can be made to speak your own native language. Most such +packages use GNU `gettext'. Other packages have their own ways to +internationalization, predating GNU `gettext'. + + By default, this package will be installed to allow translation of +messages. It will automatically detect whether the system already +provides the GNU `gettext' functions. If not, the included GNU +`gettext' library will be used. This library is wholly contained +within this package, usually in the `intl/' subdirectory, so prior +installation of the GNU `gettext' package is _not_ required. +Installers may use special options at configuration time for changing +the default behaviour. The commands: + + ./configure --with-included-gettext + ./configure --disable-nls + +will, respectively, bypass any pre-existing `gettext' to use the +internationalizing routines provided within this package, or else, +_totally_ disable translation of messages. + + When you already have GNU `gettext' installed on your system and run +configure without an option for your new package, `configure' will +probably detect the previously built and installed `libintl.a' file and +will decide to use this. This might not be desirable. You should use +the more recent version of the GNU `gettext' library. I.e. if the file +`intl/VERSION' shows that the library which comes with this package is +more recent, you should use + + ./configure --with-included-gettext + +to prevent auto-detection. + + The configuration process will not test for the `catgets' function +and therefore it will not be used. The reason is that even an +emulation of `gettext' on top of `catgets' could not provide all the +extensions of the GNU `gettext' library. + + Internationalized packages usually have many `po/LL.po' files, where +LL gives an ISO 639 two-letter code identifying the language. Unless +translations have been forbidden at `configure' time by using the +`--disable-nls' switch, all available translations are installed +together with the package. However, the environment variable `LINGUAS' +may be set, prior to configuration, to limit the installed set. +`LINGUAS' should then contain a space separated list of two-letter +codes, stating which languages are allowed. + +1.3 Using This Package +====================== + +As a user, if your language has been installed for this package, you +only have to set the `LANG' environment variable to the appropriate +`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, +and `CC' is an ISO 3166 two-letter country code. For example, let's +suppose that you speak German and live in Germany. At the shell +prompt, merely execute `setenv LANG de_DE' (in `csh'), +`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). +This can be done from your `.login' or `.profile' file, once and for +all. + + You might think that the country code specification is redundant. +But in fact, some languages have dialects in different countries. For +example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The +country code serves to distinguish the dialects. + + The locale naming convention of `LL_CC', with `LL' denoting the +language and `CC' denoting the country, is the one use on systems based +on GNU libc. On other systems, some variations of this scheme are +used, such as `LL' or `LL_CC.ENCODING'. You can get the list of +locales supported by your system for your language by running the +command `locale -a | grep '^LL''. + + Not all programs have translations for all languages. By default, an +English message is shown in place of a nonexistent translation. If you +understand other languages, you can set up a priority list of languages. +This is done through a different environment variable, called +`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' +for the purpose of message handling, but you still need to have `LANG' +set to the primary language; this is required by other parts of the +system libraries. For example, some Swedish users who would rather +read translations in German than English for when Swedish is not +available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. + + Special advice for Norwegian users: The language code for Norwegian +bokma*l changed from `no' to `nb' recently (in 2003). During the +transition period, while some message catalogs for this language are +installed under `nb' and some older ones under `no', it's recommended +for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and +older translations are used. + + In the `LANGUAGE' environment variable, but not in the `LANG' +environment variable, `LL_CC' combinations can be abbreviated as `LL' +to denote the language's main dialect. For example, `de' is equivalent +to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' +(Portuguese as spoken in Portugal) in this context. + +1.4 Translating Teams +===================== + +For the Free Translation Project to be a success, we need interested +people who like their own language and write it well, and who are also +able to synergize with other translators speaking the same language. +Each translation team has its own mailing list. The up-to-date list of +teams can be found at the Free Translation Project's homepage, +`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" +area. + + If you'd like to volunteer to _work_ at translating messages, you +should become a member of the translating team for your own language. +The subscribing address is _not_ the same as the list itself, it has +`-request' appended. For example, speakers of Swedish can send a +message to `sv-request@li.org', having this message body: + + subscribe + + Keep in mind that team members are expected to participate +_actively_ in translations, or at solving translational difficulties, +rather than merely lurking around. If your team does not exist yet and +you want to start one, or if you are unsure about what to do or how to +get started, please write to `translation@iro.umontreal.ca' to reach the +coordinator for all translator teams. + + The English team is special. It works at improving and uniformizing +the terminology in use. Proven linguistic skills are praised more than +programming skills, here. + +1.5 Available Packages +====================== + +Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of October +2006. The matrix shows, in regard of each package, for which languages +PO files have been submitted to translation coordination, with a +translation percentage of at least 50%. + + Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo + +----------------------------------------------------+ + GNUnet | [] | + a2ps | [] [] [] [] [] | + aegis | () | + ant-phone | () | + anubis | [] | + ap-utils | | + aspell | [] [] [] [] [] | + bash | [] [] [] | + batchelor | [] | + bfd | | + bibshelf | [] | + binutils | [] | + bison | [] [] | + bison-runtime | | + bluez-pin | [] [] [] [] [] | + cflow | [] | + clisp | [] [] | + console-tools | [] [] | + coreutils | [] [] [] | + cpio | | + cpplib | [] [] [] | + cryptonit | [] | + darkstat | [] () [] | + dialog | [] [] [] [] [] [] | + diffutils | [] [] [] [] [] [] | + doodle | [] | + e2fsprogs | [] [] | + enscript | [] [] [] [] | + error | [] [] [] [] | + fetchmail | [] [] () [] | + fileutils | [] [] | + findutils | [] [] [] | + flex | [] [] [] | + fslint | [] | + gas | | + gawk | [] [] [] | + gbiff | [] | + gcal | [] | + gcc | [] | + gettext-examples | [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] | + gettext-tools | [] [] | + gimp-print | [] [] [] [] | + gip | [] | + gliv | [] | + glunarclock | [] | + gmult | [] [] | + gnubiff | () | + gnucash | () () [] | + gnucash-glossary | [] () | + gnuedu | | + gnulib | [] [] [] [] [] [] | + gnunet-gtk | | + gnutls | | + gpe-aerial | [] [] | + gpe-beam | [] [] | + gpe-calendar | | + gpe-clock | [] [] | + gpe-conf | [] [] | + gpe-contacts | | + gpe-edit | [] | + gpe-filemanager | | + gpe-go | [] | + gpe-login | [] [] | + gpe-ownerinfo | [] [] | + gpe-package | | + gpe-sketchbook | [] [] | + gpe-su | [] [] | + gpe-taskmanager | [] [] | + gpe-timesheet | [] | + gpe-today | [] [] | + gpe-todo | | + gphoto2 | [] [] [] [] | + gprof | [] [] | + gpsdrive | () () | + gramadoir | [] [] | + grep | [] [] [] [] [] [] | + gretl | | + gsasl | | + gss | | + gst-plugins | [] [] [] [] | + gst-plugins-base | [] [] [] | + gst-plugins-good | [] [] [] [] [] [] [] | + gstreamer | [] [] [] [] [] [] [] | + gtick | () | + gtkam | [] [] [] | + gtkorphan | [] [] | + gtkspell | [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] | + id-utils | [] [] | + impost | | + indent | [] [] [] | + iso_3166 | [] [] | + iso_3166_2 | | + iso_4217 | [] | + iso_639 | [] [] | + jpilot | [] | + jtag | | + jwhois | | + kbd | [] [] [] [] | + keytouch | | + keytouch-editor | | + keytouch-keyboa... | | + latrine | () | + ld | [] | + leafpad | [] [] [] [] [] | + libc | [] [] [] [] [] | + libexif | [] | + libextractor | [] | + libgpewidget | [] [] [] | + libgpg-error | [] | + libgphoto2 | [] [] | + libgphoto2_port | [] [] | + libgsasl | | + libiconv | [] [] | + libidn | [] [] | + lifelines | [] () | + lilypond | [] | + lingoteach | | + lynx | [] [] [] [] | + m4 | [] [] [] [] | + mailutils | [] | + make | [] [] | + man-db | [] () [] [] | + minicom | [] [] [] | + mysecretdiary | [] [] | + nano | [] [] [] | + nano_1_0 | [] () [] [] | + opcodes | [] | + parted | | + pilot-qof | [] | + psmisc | [] | + pwdutils | | + python | | + qof | | + radius | [] | + recode | [] [] [] [] [] [] | + rpm | [] [] | + screem | | + scrollkeeper | [] [] [] [] [] [] [] [] | + sed | [] [] [] | + sh-utils | [] [] | + shared-mime-info | [] [] [] [] | + sharutils | [] [] [] [] [] [] | + shishi | | + silky | | + skencil | [] () | + sketch | [] () | + solfege | | + soundtracker | [] [] | + sp | [] | + stardict | [] | + system-tools-ba... | [] [] [] [] [] [] [] [] [] | + tar | [] | + texinfo | [] [] [] | + textutils | [] [] [] | + tin | () () | + tp-robot | [] | + tuxpaint | [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] [] | + vorbis-tools | [] [] [] [] | + wastesedge | () | + wdiff | [] [] [] [] | + wget | [] [] | + xchat | [] [] [] [] [] [] | + xkeyboard-config | | + xpad | [] [] | + +----------------------------------------------------+ + af am ar az be bg bs ca cs cy da de el en en_GB eo + 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16 + + es et eu fa fi fr ga gl gu he hi hr hu id is it + +--------------------------------------------------+ + GNUnet | | + a2ps | [] [] [] () | + aegis | | + ant-phone | [] | + anubis | [] | + ap-utils | [] [] | + aspell | [] [] [] | + bash | [] [] [] | + batchelor | [] [] | + bfd | [] | + bibshelf | [] [] [] | + binutils | [] [] [] | + bison | [] [] [] [] [] [] | + bison-runtime | [] [] [] [] [] | + bluez-pin | [] [] [] [] [] | + cflow | [] | + clisp | [] [] | + console-tools | | + coreutils | [] [] [] [] [] [] | + cpio | [] [] [] | + cpplib | [] [] | + cryptonit | [] | + darkstat | [] () [] [] [] | + dialog | [] [] [] [] [] [] [] [] | + diffutils | [] [] [] [] [] [] [] [] [] | + doodle | [] [] | + e2fsprogs | [] [] [] | + enscript | [] [] [] | + error | [] [] [] [] [] | + fetchmail | [] | + fileutils | [] [] [] [] [] [] | + findutils | [] [] [] [] | + flex | [] [] [] | + fslint | [] | + gas | [] [] | + gawk | [] [] [] [] | + gbiff | [] | + gcal | [] [] | + gcc | [] | + gettext-examples | [] [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] [] | + gettext-tools | [] [] [] | + gimp-print | [] [] | + gip | [] [] [] | + gliv | () | + glunarclock | [] [] [] | + gmult | [] [] [] | + gnubiff | () () | + gnucash | () () () | + gnucash-glossary | [] [] | + gnuedu | [] | + gnulib | [] [] [] [] [] [] [] [] | + gnunet-gtk | | + gnutls | | + gpe-aerial | [] [] | + gpe-beam | [] [] | + gpe-calendar | | + gpe-clock | [] [] [] [] | + gpe-conf | [] | + gpe-contacts | [] [] | + gpe-edit | [] [] [] [] | + gpe-filemanager | [] | + gpe-go | [] [] [] | + gpe-login | [] [] [] | + gpe-ownerinfo | [] [] [] [] [] | + gpe-package | [] | + gpe-sketchbook | [] [] | + gpe-su | [] [] [] [] | + gpe-taskmanager | [] [] [] | + gpe-timesheet | [] [] [] [] | + gpe-today | [] [] [] [] | + gpe-todo | [] | + gphoto2 | [] [] [] [] [] | + gprof | [] [] [] [] | + gpsdrive | () () [] () | + gramadoir | [] [] | + grep | [] [] [] [] [] [] [] [] [] [] [] [] | + gretl | [] [] [] | + gsasl | [] [] | + gss | [] | + gst-plugins | [] [] [] | + gst-plugins-base | [] [] | + gst-plugins-good | [] [] [] | + gstreamer | [] [] [] | + gtick | [] | + gtkam | [] [] [] [] | + gtkorphan | [] [] | + gtkspell | [] [] [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | + id-utils | [] [] [] [] [] | + impost | [] [] | + indent | [] [] [] [] [] [] [] [] [] [] | + iso_3166 | [] [] [] | + iso_3166_2 | [] | + iso_4217 | [] [] [] [] | + iso_639 | [] [] [] [] [] | + jpilot | [] [] | + jtag | [] | + jwhois | [] [] [] [] [] | + kbd | [] [] | + keytouch | [] | + keytouch-editor | [] | + keytouch-keyboa... | [] | + latrine | [] [] [] | + ld | [] [] | + leafpad | [] [] [] [] [] [] | + libc | [] [] [] [] [] | + libexif | [] | + libextractor | [] | + libgpewidget | [] [] [] [] [] | + libgpg-error | | + libgphoto2 | [] [] [] | + libgphoto2_port | [] [] | + libgsasl | [] [] | + libiconv | [] [] | + libidn | [] [] | + lifelines | () | + lilypond | [] | + lingoteach | [] [] [] | + lynx | [] [] [] | + m4 | [] [] [] [] | + mailutils | [] [] | + make | [] [] [] [] [] [] [] [] | + man-db | () | + minicom | [] [] [] [] | + mysecretdiary | [] [] [] | + nano | [] [] [] [] [] [] | + nano_1_0 | [] [] [] [] [] | + opcodes | [] [] [] [] | + parted | [] [] [] [] | + pilot-qof | | + psmisc | [] [] [] | + pwdutils | | + python | | + qof | [] | + radius | [] [] | + recode | [] [] [] [] [] [] [] [] | + rpm | [] [] | + screem | | + scrollkeeper | [] [] [] | + sed | [] [] [] [] [] | + sh-utils | [] [] [] [] [] [] [] | + shared-mime-info | [] [] [] [] [] [] | + sharutils | [] [] [] [] [] [] [] [] | + shishi | | + silky | [] | + skencil | [] [] | + sketch | [] [] | + solfege | [] | + soundtracker | [] [] [] | + sp | [] | + stardict | [] | + system-tools-ba... | [] [] [] [] [] [] [] [] | + tar | [] [] [] [] [] [] [] | + texinfo | [] [] | + textutils | [] [] [] [] [] | + tin | [] () | + tp-robot | [] [] [] [] | + tuxpaint | [] [] | + unicode-han-tra... | | + unicode-transla... | [] [] | + util-linux | [] [] [] [] [] [] [] | + vorbis-tools | [] [] | + wastesedge | () | + wdiff | [] [] [] [] [] [] [] [] | + wget | [] [] [] [] [] [] [] [] | + xchat | [] [] [] [] [] [] [] [] | + xkeyboard-config | [] [] [] [] | + xpad | [] [] [] | + +--------------------------------------------------+ + es et eu fa fi fr ga gl gu he hi hr hu id is it + 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52 + + ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no + +-------------------------------------------------+ + GNUnet | | + a2ps | () [] [] () | + aegis | () | + ant-phone | [] | + anubis | [] [] [] | + ap-utils | [] | + aspell | [] [] | + bash | [] | + batchelor | [] [] | + bfd | | + bibshelf | [] | + binutils | | + bison | [] [] [] | + bison-runtime | [] [] [] | + bluez-pin | [] [] [] | + cflow | | + clisp | [] | + console-tools | | + coreutils | [] | + cpio | | + cpplib | [] | + cryptonit | [] | + darkstat | [] [] | + dialog | [] [] | + diffutils | [] [] [] | + doodle | | + e2fsprogs | [] | + enscript | [] | + error | [] | + fetchmail | [] [] | + fileutils | [] [] | + findutils | [] | + flex | [] [] | + fslint | [] [] | + gas | | + gawk | [] [] | + gbiff | [] | + gcal | | + gcc | | + gettext-examples | [] [] | + gettext-runtime | [] [] [] | + gettext-tools | [] [] | + gimp-print | [] [] | + gip | [] [] | + gliv | [] | + glunarclock | [] [] | + gmult | [] [] | + gnubiff | | + gnucash | () () | + gnucash-glossary | [] | + gnuedu | | + gnulib | [] [] [] [] | + gnunet-gtk | | + gnutls | | + gpe-aerial | [] | + gpe-beam | [] | + gpe-calendar | [] | + gpe-clock | [] [] [] | + gpe-conf | [] [] | + gpe-contacts | [] | + gpe-edit | [] [] [] | + gpe-filemanager | [] [] | + gpe-go | [] [] [] | + gpe-login | [] [] [] | + gpe-ownerinfo | [] [] | + gpe-package | [] [] | + gpe-sketchbook | [] [] | + gpe-su | [] [] [] | + gpe-taskmanager | [] [] [] [] | + gpe-timesheet | [] | + gpe-today | [] [] | + gpe-todo | [] | + gphoto2 | [] [] | + gprof | | + gpsdrive | () () () | + gramadoir | () | + grep | [] [] [] [] | + gretl | | + gsasl | [] | + gss | | + gst-plugins | [] | + gst-plugins-base | | + gst-plugins-good | [] | + gstreamer | [] | + gtick | | + gtkam | [] | + gtkorphan | [] | + gtkspell | [] [] | + gutenprint | | + hello | [] [] [] [] [] [] | + id-utils | [] | + impost | | + indent | [] [] | + iso_3166 | [] | + iso_3166_2 | [] | + iso_4217 | [] [] [] | + iso_639 | [] [] | + jpilot | () () () | + jtag | | + jwhois | [] | + kbd | [] | + keytouch | [] | + keytouch-editor | | + keytouch-keyboa... | | + latrine | [] | + ld | | + leafpad | [] [] | + libc | [] [] [] [] [] | + libexif | | + libextractor | | + libgpewidget | [] | + libgpg-error | | + libgphoto2 | [] | + libgphoto2_port | [] | + libgsasl | [] | + libiconv | | + libidn | [] [] | + lifelines | [] | + lilypond | | + lingoteach | [] | + lynx | [] [] | + m4 | [] [] | + mailutils | | + make | [] [] [] | + man-db | () | + minicom | [] | + mysecretdiary | [] | + nano | [] [] [] | + nano_1_0 | [] [] [] | + opcodes | [] | + parted | [] [] | + pilot-qof | | + psmisc | [] [] [] | + pwdutils | | + python | | + qof | | + radius | | + recode | [] | + rpm | [] [] | + screem | [] | + scrollkeeper | [] [] [] [] | + sed | [] [] | + sh-utils | [] [] | + shared-mime-info | [] [] [] [] [] | + sharutils | [] [] | + shishi | | + silky | [] | + skencil | | + sketch | | + solfege | | + soundtracker | | + sp | () | + stardict | [] [] | + system-tools-ba... | [] [] [] [] | + tar | [] [] [] | + texinfo | [] [] [] | + textutils | [] [] [] | + tin | | + tp-robot | [] | + tuxpaint | [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] | + vorbis-tools | [] | + wastesedge | [] | + wdiff | [] [] | + wget | [] [] | + xchat | [] [] [] [] | + xkeyboard-config | [] | + xpad | [] [] [] | + +-------------------------------------------------+ + ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no + 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1 + + nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta + +------------------------------------------------------+ + GNUnet | | + a2ps | () [] [] [] [] [] [] | + aegis | () () | + ant-phone | [] [] | + anubis | [] [] [] | + ap-utils | () | + aspell | [] [] | + bash | [] [] [] | + batchelor | [] [] | + bfd | | + bibshelf | [] | + binutils | [] [] | + bison | [] [] [] [] [] | + bison-runtime | [] [] [] [] | + bluez-pin | [] [] [] [] [] [] [] [] [] | + cflow | [] | + clisp | [] | + console-tools | [] | + coreutils | [] [] [] [] | + cpio | [] [] [] | + cpplib | [] | + cryptonit | [] [] | + darkstat | [] [] [] [] [] [] | + dialog | [] [] [] [] [] [] [] [] [] | + diffutils | [] [] [] [] [] [] | + doodle | [] [] | + e2fsprogs | [] [] | + enscript | [] [] [] [] [] | + error | [] [] [] [] | + fetchmail | [] [] [] | + fileutils | [] [] [] [] [] | + findutils | [] [] [] [] [] [] | + flex | [] [] [] [] [] | + fslint | [] [] [] [] | + gas | | + gawk | [] [] [] [] | + gbiff | [] | + gcal | [] | + gcc | [] | + gettext-examples | [] [] [] [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] [] [] [] | + gettext-tools | [] [] [] [] [] [] [] | + gimp-print | [] [] | + gip | [] [] [] [] | + gliv | [] [] [] [] | + glunarclock | [] [] [] [] [] [] | + gmult | [] [] [] [] | + gnubiff | () | + gnucash | () [] | + gnucash-glossary | [] [] [] | + gnuedu | | + gnulib | [] [] [] [] [] | + gnunet-gtk | [] | + gnutls | [] [] | + gpe-aerial | [] [] [] [] [] [] [] | + gpe-beam | [] [] [] [] [] [] [] | + gpe-calendar | [] | + gpe-clock | [] [] [] [] [] [] [] [] | + gpe-conf | [] [] [] [] [] [] [] | + gpe-contacts | [] [] [] [] [] | + gpe-edit | [] [] [] [] [] [] [] [] | + gpe-filemanager | [] [] | + gpe-go | [] [] [] [] [] [] | + gpe-login | [] [] [] [] [] [] [] [] | + gpe-ownerinfo | [] [] [] [] [] [] [] [] | + gpe-package | [] [] | + gpe-sketchbook | [] [] [] [] [] [] [] [] | + gpe-su | [] [] [] [] [] [] [] [] | + gpe-taskmanager | [] [] [] [] [] [] [] [] | + gpe-timesheet | [] [] [] [] [] [] [] [] | + gpe-today | [] [] [] [] [] [] [] [] | + gpe-todo | [] [] [] [] | + gphoto2 | [] [] [] [] [] | + gprof | [] [] [] | + gpsdrive | [] [] [] | + gramadoir | [] [] | + grep | [] [] [] [] [] [] [] [] | + gretl | [] | + gsasl | [] [] [] | + gss | [] [] [] | + gst-plugins | [] [] [] [] | + gst-plugins-base | [] | + gst-plugins-good | [] [] [] [] | + gstreamer | [] [] [] | + gtick | [] | + gtkam | [] [] [] [] | + gtkorphan | [] | + gtkspell | [] [] [] [] [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] [] [] [] | + id-utils | [] [] [] [] | + impost | [] | + indent | [] [] [] [] [] [] | + iso_3166 | [] [] [] [] [] [] | + iso_3166_2 | | + iso_4217 | [] [] [] [] | + iso_639 | [] [] [] [] | + jpilot | | + jtag | [] | + jwhois | [] [] [] [] | + kbd | [] [] [] | + keytouch | [] | + keytouch-editor | [] | + keytouch-keyboa... | [] | + latrine | [] [] | + ld | [] | + leafpad | [] [] [] [] [] [] | + libc | [] [] [] [] [] | + libexif | [] | + libextractor | [] [] | + libgpewidget | [] [] [] [] [] [] [] | + libgpg-error | [] [] | + libgphoto2 | [] | + libgphoto2_port | [] [] [] | + libgsasl | [] [] [] [] | + libiconv | [] [] | + libidn | [] [] () | + lifelines | [] [] | + lilypond | | + lingoteach | [] | + lynx | [] [] [] | + m4 | [] [] [] [] [] | + mailutils | [] [] [] [] | + make | [] [] [] [] | + man-db | [] [] | + minicom | [] [] [] [] [] | + mysecretdiary | [] [] [] [] | + nano | [] [] [] | + nano_1_0 | [] [] [] [] | + opcodes | [] [] | + parted | [] | + pilot-qof | [] | + psmisc | [] [] | + pwdutils | [] [] | + python | | + qof | [] [] | + radius | [] [] | + recode | [] [] [] [] [] [] [] | + rpm | [] [] [] [] | + screem | | + scrollkeeper | [] [] [] [] [] [] [] | + sed | [] [] [] [] [] [] [] [] [] | + sh-utils | [] [] [] | + shared-mime-info | [] [] [] [] [] | + sharutils | [] [] [] [] | + shishi | [] | + silky | [] | + skencil | [] [] [] | + sketch | [] [] [] | + solfege | [] | + soundtracker | [] [] | + sp | | + stardict | [] [] [] | + system-tools-ba... | [] [] [] [] [] [] [] [] [] | + tar | [] [] [] [] [] | + texinfo | [] [] [] [] | + textutils | [] [] [] | + tin | () | + tp-robot | [] | + tuxpaint | [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] [] | + vorbis-tools | [] [] | + wastesedge | | + wdiff | [] [] [] [] [] [] | + wget | [] [] [] [] | + xchat | [] [] [] [] [] [] [] | + xkeyboard-config | [] [] | + xpad | [] [] [] | + +------------------------------------------------------+ + nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta + 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2 + + tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu + +---------------------------------------------------+ + GNUnet | [] | 2 + a2ps | [] [] [] | 19 + aegis | | 0 + ant-phone | [] [] | 6 + anubis | [] [] [] | 11 + ap-utils | () [] | 4 + aspell | [] [] [] | 15 + bash | [] | 11 + batchelor | [] [] | 9 + bfd | | 1 + bibshelf | [] | 7 + binutils | [] [] [] | 9 + bison | [] [] [] | 19 + bison-runtime | [] [] [] | 15 + bluez-pin | [] [] [] [] [] [] | 28 + cflow | [] [] | 5 + clisp | | 6 + console-tools | [] [] | 5 + coreutils | [] [] | 16 + cpio | [] [] [] | 9 + cpplib | [] [] [] [] | 11 + cryptonit | | 5 + darkstat | [] () () | 15 + dialog | [] [] [] [] [] | 30 + diffutils | [] [] [] [] | 28 + doodle | [] | 6 + e2fsprogs | [] [] | 10 + enscript | [] [] [] | 16 + error | [] [] [] [] | 18 + fetchmail | [] [] | 12 + fileutils | [] [] [] | 18 + findutils | [] [] [] | 17 + flex | [] [] | 15 + fslint | [] | 9 + gas | [] | 3 + gawk | [] [] | 15 + gbiff | [] | 5 + gcal | [] | 5 + gcc | [] [] [] | 6 + gettext-examples | [] [] [] [] [] [] | 27 + gettext-runtime | [] [] [] [] [] [] | 28 + gettext-tools | [] [] [] [] [] | 19 + gimp-print | [] [] | 12 + gip | [] [] | 12 + gliv | [] [] | 8 + glunarclock | [] [] [] | 15 + gmult | [] [] [] [] | 15 + gnubiff | [] | 1 + gnucash | () | 2 + gnucash-glossary | [] [] | 9 + gnuedu | [] | 2 + gnulib | [] [] [] [] [] | 28 + gnunet-gtk | | 1 + gnutls | | 2 + gpe-aerial | [] [] | 14 + gpe-beam | [] [] | 14 + gpe-calendar | [] | 3 + gpe-clock | [] [] [] [] | 21 + gpe-conf | [] [] | 14 + gpe-contacts | [] [] | 10 + gpe-edit | [] [] [] [] | 20 + gpe-filemanager | [] | 6 + gpe-go | [] [] | 15 + gpe-login | [] [] [] [] [] | 21 + gpe-ownerinfo | [] [] [] [] | 21 + gpe-package | [] | 6 + gpe-sketchbook | [] [] | 16 + gpe-su | [] [] [] | 20 + gpe-taskmanager | [] [] [] | 20 + gpe-timesheet | [] [] [] [] | 18 + gpe-today | [] [] [] [] [] | 21 + gpe-todo | [] | 7 + gphoto2 | [] [] [] [] | 20 + gprof | [] [] | 11 + gpsdrive | | 4 + gramadoir | [] | 7 + grep | [] [] [] [] | 34 + gretl | | 4 + gsasl | [] [] | 8 + gss | [] | 5 + gst-plugins | [] [] [] | 15 + gst-plugins-base | [] [] [] | 9 + gst-plugins-good | [] [] [] [] [] | 20 + gstreamer | [] [] [] | 17 + gtick | [] | 3 + gtkam | [] | 13 + gtkorphan | [] | 7 + gtkspell | [] [] [] [] [] [] | 26 + gutenprint | | 3 + hello | [] [] [] [] [] | 37 + id-utils | [] [] | 14 + impost | [] | 4 + indent | [] [] [] [] | 25 + iso_3166 | [] [] [] [] | 16 + iso_3166_2 | | 2 + iso_4217 | [] [] | 14 + iso_639 | [] | 14 + jpilot | [] [] [] [] | 7 + jtag | [] | 3 + jwhois | [] [] [] | 13 + kbd | [] [] | 12 + keytouch | [] | 4 + keytouch-editor | | 2 + keytouch-keyboa... | [] | 3 + latrine | [] [] | 8 + ld | [] [] [] [] | 8 + leafpad | [] [] [] [] | 23 + libc | [] [] [] | 23 + libexif | [] | 4 + libextractor | [] | 5 + libgpewidget | [] [] [] | 19 + libgpg-error | [] | 4 + libgphoto2 | [] | 8 + libgphoto2_port | [] [] [] | 11 + libgsasl | [] | 8 + libiconv | [] | 7 + libidn | [] [] | 10 + lifelines | | 4 + lilypond | | 2 + lingoteach | [] | 6 + lynx | [] [] [] | 15 + m4 | [] [] [] | 18 + mailutils | [] | 8 + make | [] [] [] | 20 + man-db | [] | 6 + minicom | [] | 14 + mysecretdiary | [] [] | 12 + nano | [] [] | 17 + nano_1_0 | [] [] [] | 18 + opcodes | [] [] | 10 + parted | [] [] [] | 10 + pilot-qof | [] | 3 + psmisc | [] | 10 + pwdutils | [] | 3 + python | | 0 + qof | [] | 4 + radius | [] | 6 + recode | [] [] [] | 25 + rpm | [] [] [] [] | 14 + screem | [] | 2 + scrollkeeper | [] [] [] [] | 26 + sed | [] [] [] | 22 + sh-utils | [] | 15 + shared-mime-info | [] [] [] [] | 24 + sharutils | [] [] [] | 23 + shishi | | 1 + silky | [] | 4 + skencil | [] | 7 + sketch | | 6 + solfege | | 2 + soundtracker | [] [] | 9 + sp | [] | 3 + stardict | [] [] [] [] | 11 + system-tools-ba... | [] [] [] [] [] [] [] | 37 + tar | [] [] [] [] | 20 + texinfo | [] [] [] | 15 + textutils | [] [] [] | 17 + tin | | 1 + tp-robot | [] [] [] | 10 + tuxpaint | [] [] [] | 16 + unicode-han-tra... | | 0 + unicode-transla... | | 2 + util-linux | [] [] [] | 20 + vorbis-tools | [] [] | 11 + wastesedge | | 1 + wdiff | [] [] | 22 + wget | [] [] [] | 19 + xchat | [] [] [] [] | 29 + xkeyboard-config | [] [] [] [] | 11 + xpad | [] [] [] | 14 + +---------------------------------------------------+ + 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu + 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028 + + Some counters in the preceding matrix are higher than the number of +visible blocks let us expect. This is because a few extra PO files are +used for implementing regional variants of languages, or language +dialects. + + For a PO file in the matrix above to be effective, the package to +which it applies should also have been internationalized and +distributed as such by its maintainer. There might be an observable +lag between the mere existence a PO file and its wide availability in a +distribution. + + If October 2006 seems to be old, you may fetch a more recent copy of +this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date +matrix with full percentage details can be found at +`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. + +1.6 Using `gettext' in new packages +=================================== + +If you are writing a freely available program and want to +internationalize it you are welcome to use GNU `gettext' in your +package. Of course you have to respect the GNU Library General Public +License which covers the use of the GNU `gettext' library. This means +in particular that even non-free programs can use `libintl' as a shared +library, whereas only free software can use `libintl' as a static +library or use modified versions of `libintl'. + + Once the sources are changed appropriately and the setup can handle +the use of `gettext' the only thing missing are the translations. The +Free Translation Project is also available for packages which are not +developed inside the GNU project. Therefore the information given above +applies also for every other Free Software Project. Contact +`translation@iro.umontreal.ca' to make the `.pot' files available to +the translation teams. + diff --git a/linphone/AUTHORS b/linphone/AUTHORS new file mode 100644 index 000000000..386427a4f --- /dev/null +++ b/linphone/AUTHORS @@ -0,0 +1,57 @@ +Simon MORLAT (simon dot morlat at linphone dot org) wrotes: + - main graphical program (gnome) + - RTP library (oRTP) + - SIP user-agent library (osipua) + - audio library (mediastreamer), for codec and i/o handling. + - sipomatic, the automatic sip replier, which is often used for testing. + +Florian Wintertein < f-win at gmx dot net > wrotes the console version of linphone (linphonec) +in console/ directory. + +Aymeric Moizard (jack at atosc dot org) wrotes: + - the oSIP SIP transactionnal stack (not part of linphone) + - some piece of code of the osip distribution have been reused in osipua + - presence information support in osipua + - and contributes to some parts of osipua (digest authentification) +For more information about oSIP, see http://osip.atosc.org + +Sharath Udupa is developing the media_api, a usefull library to manage audio and video streams +for basic calls as well as conference. + +Sandro Santilli < strk at keybit dot net > wrote enhancements in the +console interface (readline, new commands) and some bug fixes for +the core api. + +Bryan Ogawa ( bko at cisco dot com ) sent a patch that made the linphone-0.7.1 release. +This patch fixed several issues in the SIP part while working with proxies. + +Koichi KUNITAKE < kunitake at linux-ipv6 dot org > has contributed a patch bringing +full IPv6 support. + +The Speex codec is a project from Jean Marc Valin. See http://speex.sourceforge.net for more +information. + +The GSM library was written by : + Jutta Degener and Carsten Bormann,Technische Universitaet Berlin. + +The LPC10-1.5 library was written by: + Andy Fingerhut + Applied Research Laboratory <-- this line is optional if + Washington University, Campus Box 1045/Bryan 509 you have limited space + One Brookings Drive + Saint Louis, MO 63130-4899 + jaf@arl.wustl.edu + http://www.arl.wustl.edu/~jaf/ + + See text files in gsmlib and lpc10-1.5 directories for further information. + +G711 library has some code from the alsa-lib on http://www.alsa-project.org + +Icons by Pablo Marcelo Moia. + +Translations: +fr: Simon Morlat +en: Simon Morlat and Delphine Perreau +it: Alberto Zanoni +de: Jean-Jacques Sarton +es: Jesús Benítez diff --git a/linphone/BUGS b/linphone/BUGS new file mode 100644 index 000000000..1c45089e5 --- /dev/null +++ b/linphone/BUGS @@ -0,0 +1,9 @@ +linphone-1.0.0: + It seems ipv6 support is "broken". Some help is welcome. + +linphone-0.12.0 + When compiling with gcc-2.95.4 on debian, an assert fails and cause abort() + in libasound (alsa-lib). When compiling with gcc-3.2, it does not happen. + It seems that asoundlib and linphone must be compiled with the same compiler. + +Simon MORLAT diff --git a/linphone/COPYING b/linphone/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/linphone/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/linphone/ChangeLog b/linphone/ChangeLog new file mode 100644 index 000000000..140cdaea0 --- /dev/null +++ b/linphone/ChangeLog @@ -0,0 +1,513 @@ +2008-09-02 Francois-Xavier Kowalski + + * gtk/Makefile.am (INCLUDES): 1.6 + Deprecated automake directive INCLUDES does not work within a + conditionnal. + +2008-08-22 Francois-Xavier Kowalski + + * mediastreamer2/src/Makefile.am (libmediastreamer_la_SOURCES+): 1.27 + Deliver swscale.h in case ffmpeg does not come with libswscale + (in which case the swscale feature is included into + libavcodec). Also deliver ffmpeg-priv.h wrapper. + + * mediastreamer2/src/videoout.c: 1.39 + * mediastreamer2/src/videodec.c: 1.24 + * mediastreamer2/src/sizeconv.c: 1.14 + * mediastreamer2/src/pixconv.c: 1.13 + * mediastreamer2/src/nowebcam.c: 1.15 + Use ffmpeg-priv,h + + * mediastreamer2/mediastreamer-config.h.in: 1.13 + Remove from CVSm as it is generated by autoheader + + * mediastreamer2/configure.ac: 1.47 + Use pkg-config to check for arts + + * mediastreamer2/acinclude.m4: 1.12 + Remove -I/usr/include and -L/usr/lib(64) from CFLAGS and LIBS. + Check for ffmpeg swscale feature into libavcodec or into + libswscale + +2007-09-26 Francois-Xavier Kowalski + + * m4/exosip.m4: 1.3 + make Linphone buildable with the eXosip/osip version that ships + with Fedora. + + * oRTP/include/ortp/stun_udp.h: 1.9 + * mediastreamer2/include/mediastreamer2/msvideo.h: 1.7 + * mediastreamer2/include/mediastreamer2/msticker.h: 1.6 + * mediastreamer2/include/mediastreamer2/msqueue.h: 1.3 + Clean ANSI/C vs. ANSI/C++ differences + +2007-08-01 Sandro Santilli + + * console/commands.c: Clean up commands 'nat', 'stun' + and 'firewall' to be more intuitive. + +2007-02-03 Francois-Xavier Kowalski + + * m4/osip.m4 (OSIP_CFLAGS): 1.2 + * gnome/Makefile.am (linphone_applet_LDADD): 1.33 + * coreapi/Makefile.am (liblinphone_la_CFLAGS): 1.38 + * console/Makefile.am (sipomatic_LDADD): 1.45 + Cope with osip2-2.2.2 delivered as legacy on FC6. New option + "--with-osip-version" + +2007-01-18 Francois-Xavier Kowalski + + * oRTP/Makefile.am: 1.24 + * mediastreamer2/Makefile.am: 1.30 + * Makefile.am: 1.45 + Fix RPM package generattion to cope with + + +2007-01-17 gettextize + + * m4/gettext.m4: Upgrade to gettext-0.16.1. + * m4/lib-link.m4: Upgrade to gettext-0.16.1. + * m4/lib-prefix.m4: Upgrade to gettext-0.16.1. + * m4/nls.m4: Upgrade to gettext-0.16.1. + * m4/po.m4: Upgrade to gettext-0.16.1. + * m4/codeset.m4: Upgrade to gettext-0.16.1. + * m4/intl.m4: New file, from gettext-0.16.1. + * m4/intldir.m4: New file, from gettext-0.16.1. + * m4/intmax.m4: Upgrade to gettext-0.16.1. + * m4/inttypes_h.m4: Upgrade to gettext-0.16.1. + * m4/inttypes-pri.m4: Upgrade to gettext-0.16.1. + * m4/lock.m4: New file, from gettext-0.16.1. + * m4/longdouble.m4: Upgrade to gettext-0.16.1. + * m4/longlong.m4: Upgrade to gettext-0.16.1. + * m4/size_max.m4: Upgrade to gettext-0.16.1. + * m4/stdint_h.m4: Upgrade to gettext-0.16.1. + * m4/ulonglong.m4: Upgrade to gettext-0.16.1. + * m4/visibility.m4: New file, from gettext-0.16.1. + * m4/Makefile.am (EXTRA_DIST): Add the new files. + +2006-10-18 Sandro Santilli + + * console/Makefile.am: set osip includes last in the + search path. + +2006-09-19 Francois-Xavier Kowalski + + * linphone.spec.in (BuildRequires): 1.8 + Add RPM build-time dependency on gettext-devel to define + AM_GNU_GETTEXT. + +2006-07-26 Sandro Santilli + + * .cvsignore, developer-docs/mediastreamer/.cvsignore, + ipkg/.cvsignore, mediastreamer2/.cvsignore, + mediastreamer2/build/.cvsignore, + mediastreamer2/build/win32native/.cvsignore, + mediastreamer2/include/.cvsignore, + mediastreamer2/include/mediastreamer2/.cvsignore, + mediastreamer2/plugins/.cvsignore, + mediastreamer2/src/.cvsignore, + mediastreamer2/tests/.cvsignore, + oRTP/build/win32/.cvsignore, + oRTP/build/win32native/.cvsignore, + oRTP/src/tests/win_receiver/.cvsignore, + oRTP/src/tests/win_sender/.cvsignore, + po/.cvsignore, share/cs/.cvsignore: + Added-fixed .cvsignore files + +2006-07-20 gettextize + + * m4/codeset.m4: New file, from gettext-0.14.6. + * m4/gettext.m4: New file, from gettext-0.14.6. + * m4/glibc2.m4: New file, from gettext-0.14.6. + * m4/glibc21.m4: New file, from gettext-0.14.6. + * m4/iconv.m4: New file, from gettext-0.14.6. + * m4/intdiv0.m4: New file, from gettext-0.14.6. + * m4/intmax.m4: New file, from gettext-0.14.6. + * m4/inttypes.m4: New file, from gettext-0.14.6. + * m4/inttypes_h.m4: New file, from gettext-0.14.6. + * m4/inttypes-pri.m4: New file, from gettext-0.14.6. + * m4/isc-posix.m4: New file, from gettext-0.14.6. + * m4/lcmessage.m4: New file, from gettext-0.14.6. + * m4/lib-ld.m4: New file, from gettext-0.14.6. + * m4/lib-link.m4: New file, from gettext-0.14.6. + * m4/lib-prefix.m4: New file, from gettext-0.14.6. + * m4/longdouble.m4: New file, from gettext-0.14.6. + * m4/longlong.m4: New file, from gettext-0.14.6. + * m4/nls.m4: New file, from gettext-0.14.6. + * m4/po.m4: New file, from gettext-0.14.6. + * m4/printf-posix.m4: New file, from gettext-0.14.6. + * m4/progtest.m4: New file, from gettext-0.14.6. + * m4/signed.m4: New file, from gettext-0.14.6. + * m4/size_max.m4: New file, from gettext-0.14.6. + * m4/stdint_h.m4: New file, from gettext-0.14.6. + * m4/uintmax_t.m4: New file, from gettext-0.14.6. + * m4/ulonglong.m4: New file, from gettext-0.14.6. + * m4/wchar_t.m4: New file, from gettext-0.14.6. + * m4/wint_t.m4: New file, from gettext-0.14.6. + * m4/xsize.m4: New file, from gettext-0.14.6. + * m4/Makefile.am (EXTRA_DIST): Add the new files. + * Makefile.am (EXTRA_DIST): Add config.rpath. + +2006-07-07 Francois-Xavier Kowalski + + * linphone.spec.in (Version): 1.7 + Force build of gtk-doc, as the default choice that comes with + GTK_DOC_CHECK m4 macro is "no". + +2006-05-17 Francois-Xavier Kowalski + + * configure.in: 1.179 + * configure.in: 1.178 + Allow rpm users to use oRTP packages built from Linphone root. + +May 8 2006 : Sandro Santilli + + * configure.in: lowered libspeex requirement to 1.1.6 + +undefined yet: linphone-1.4.0 + - new audio/video streaming engine (mediastreamer2) that let the following improvements: + + split video frame to get them smaller than MTU + + less video latency + + video supported at CIF and QCIF resolution with variable framerate. + + arts sound input/output + + improved sound latency with alsa + + alsa support works with dmix/dsnoop + + old oss drivers that don't like select and non blocking mode should finally work + - lpc10-15 support removed (speex does better at 8kbit/s) + - jack support unported to mediastreamer2, sorry : volunteer needed + - video resolution and framerate set according to bandwidth constraints. + - linphonec new "soundcard" command to list and choose sound devices. + - new download and upload bandwidth parameters. + +March 31 2006: linphone-1.3.4 + - fix linphonec bug in auto-answer mode: was terminating call after a few seconds. + +March 28 2006: linphone-1.3.3 + - various FedoraCore 4 compile problem solved + - fix video bug ('could not mmap': happening on kernel>=2.6.15 with pwc driver) + - SIP register were not using route field (submitted patch) + +March 17 2006: linphone-1.3.2 + - fix early media call problem: ack for 200ok was never sent. + +March 10 2006: linphone-1.3.1 + - fix compile errors with gcc-2.95 (thanks Wolfram Gloger) + +March 8 2006 : linphone-1.3.0 (SUMMARY) + - a lots of improvements in linphonec (see strk 's Changelogs below) + - telephone event problem with sipomatic. + - updated cz translation. + - fix bugs around addressbook. + - video support with H263-1998/RFC2429 nearly clean. + - added timeout for incoming calls + +February 20 2006 : Sandro Santilli + + * console/commands.c: added filter support for + command 'friend list'. + +February 13 2006 : Sandro Santilli + + * console/linphonec.c: fixed unused variable warning. + +February 02 2006 : Sandro Santilli + Console: + - Padded vtable with missing callbacks + (fixing a segfault on friends subscription) + - Handled friends notify (bare version) + - Handled text messages receive (bare version) + - Printed message on subscription request (bare version) + - Added 'friend list' and 'friend call' commands + - Allowed for multiple DTMF send in a single line + - Added status-specific callback (bare version) + + +January 26 2006 : Sandro Santilli + - Core: fixed bug in linphone_core_set_nat_address refusing + to set address if use flag was off, added support + for NULL addr parameter to only change use flag. + - Support: added missing GFileTest enum values + - Console: 'nat' commands, cleanups + +January 25 2006 : Sandro Santilli + - Core: added request uri in proxy registration failure message + - Console: removed the -t switch + (terminate on close is default behaviour) + +January 20 2006 : Sandro Santilli + - Console: + linphonec_init() and linphonec_finish() functions. Handled + SIGINT and SIGTERM to invoke linphonec_finish(). Handling of + auto-termination (-t) moved to linphonec_finish(). Reworked main + (input read) loop to not rely on 'terminate' and 'run' variable + (dropped). configfile_name allocated on stack using PATH_MAX + limit. Changed print_usage signature to allow for an exit_status + specification. + +January 18 2006 : Sandro Santilli + - Console: + Command completion inhibited + in proxy addition and auth request prompts. Avoided use of + readline's internal filename completion. + +January 14 2006 : Sandro Santilli + - Console: + Reworked commands interface to use a table structure, used by + command line parser and help function. Implemented first + level of completion (commands). Added notification of + invalid "answer" and "terminate" commands (no incoming call, + no active call). Forbidden "call" intialization when a call is + already active. Cleaned up all commands, adding more feedback + and error checks. + +January 13 2006 : Sandro Santilli + - Console: + Added linphonec.h. Code layout change (added comments, forward + decl, globals on top, copyright notices and Logs). Handled + out-of-memory condition on history management. Removed + assumption on sizeof(char). Fixed bug in authentication + prompt (introduced by readline). Added support for multiple + authentication requests (up to MAX_PENDING_AUTH). + +January 12 2006 : Sandro Santilli + - Console: + Changed default configuration file to ~/.linphonerc, + automatically handling migration from old layout if not present + (use ~/.linphonec or ~/.gnome2/linphone). Added compile-time + define to show identity in prompt. Used EXIT_SUCCESS and + EXIT_FAILURE macros. + Made readline use ~/.linphonec_history file for + reading/writing. Fixed auto-call handling code. Fixed + OOB write of sscanf() in linphonec_parse_command_line(). + Simplified control flow in linphonec_main_loop(). + Put linphonec_{initialize,finish}_readline() calls out of + main_loop(). Removed redundant exit(0) at end of main(). + Fixed small leaks. + +December 14 2005 : linphone-1.2.0 + - various ipv6 bugfixes (again) + - fix po.pl file (was utf-8 but declared as iso8902) + - enum/automatic proxy conflict solved. use "sip:7887488478" for enums, just "382884824" to go through the default proxy. + - experimental video support progresses, compliance improved. + - remove ilbc from source tree: it is now available as a separete plugin. + - updated to work with lastest ffmpeg cvs + - fix bug when answering 'busy here'; active call was closed ! + - fix Ctrl+H bug in linphonec + - added bresilian translation + - added swedish translation + - uri bar improvements + - fix a DoS attack by setting a payload type number > 127 + +August 24 2005 : linphone-1.1.0 + - peer to peer text chat + - automatic sip url completion when using a default proxy: + when user types 'mymother' in the url bar, linphone calls sip:mymother@[default-proxy] + - ilbc 20 and 30 miliseconds frames support + - support for setting a soundcard for playback and another for record + - ipv6 bugfixes: works with ipv6 local loopback with sipomatic at least ! Needs to be tested in a real network. + - gtk interface bugfixes + - increase max supported sound devices (was 5). + - automatic incoming redirections + - experimental video support (needs special compilation procedure, see mailing lists) + + +March 27 2005 : linphone-1.0.1 + - patch for NAT traversal (SDP connection address in SDP answer) + - patch for writing correct port information when NAT is enabled + - patch for always using "rport" extension to traverse NAT with + signalling. + - patch for saving/restoring correct configuration of proxy: + "reg_register" -> "reg_sendregister" and fix for saving "expires" + +March 21 2005 : linphone-1.0.0 + - switch from osipua to eXosip/osip2 for improved sip functionnalities and compliance. + - support for presence (busy, online...) for everyone in the address book (uses SUBSCRIBE/NOTIFY) + - support for PUBLISH (presence information through sip servers) + - support for configuring multiple proxies. + - RTP adaptive jitter buffer ( provides lower latency ) + - RTCP coumpound messages sent periodically. + - on demand digest authentication for INVITE and REGISTER + - support for 183 with sdp answers. + - add support for jackd (contributed) + - call logging + - arm build improved + - cz and nl translations contributed. + + +January 2004 : linphone-0.12.2 + - add enum support (see RFC3241 and RFC3026) + Thanks to Rene Bartsch < ml at bartschnet dot de > for its usefull + and precious help. + - interactive presence box (no more need to click OK to confirm) + - update spanish translation + - alsa interface: the user can choose precisely the pcm device to be used + by setting the sound/alsadev parameter of the config file. + - use 1 RTP socket instead of 2: this makes linphone NAT-friendly. + +Thursday October 2 2003 : linphone-0.12.1 + - add support for personalizing rings. + - make glib dependency optionnal (but recommended). + - add polish translation. + - use of libartsc to suspend arts instead of killing him. + +Tuesday August 19 2003 : linphone-0.12.0 + - add support for speex/16000 + - re-enable alsa support (0.9.x) + - few improvements on gui. + - added spanish translation by Jesús Benítez + +Monday April 05 2003: linphone-0.11.0 + - merge ipv6 support patch, contributed by Koichi KUNITAKE + < kunitake at linux-ipv6 dot org > (thanks !) + - some improvements on graphical interface. + +Friday Feb 28 2003 : linphone-0.10.1 + - add firewall friendly capability + - compiles all well on arm-linux + - bugfixes. + +Friday Jan 24 2003 : linphone-0.10.0 + - Gnome interface ported to gnome-2 + - Unified core engine for both graphical and console interface. + - Many bug fix and improvements in the SIP stack. + - Japoneese translations and manual added, by Yamaguchi Yoshiya. + - updated for speex-1.0rc1 + - ported to FreeBSD thanks to Georg Shwarz + +Monday Oct 21 2002 : linphone-0.9.1 + - AMD: add support for the "received" and "rport" parameter in osipua. + +Monday Oct 21 2002 : linphone-0.9.1 + - integration of the patch of Lenaic Huard that adds the ability for linphone to send + dtmf tones through rtp (only reported to console interface). + - following this patch, a nice keypad has been added to the graphical interface to bring + the fonctionnality of the patch gui's users. + - integration of the patch of Aymeric Moizard, concerning compliance with RFC3261 (new + sip's RFC) using the new dialog_t api of libosip. + - updated for use of speex-beta1 (speex codec) + - osipua fix by jack@atosc.org + 1: reject calls with 603 + 2: establishement of 1 early dialog for incoming calls. + 3: update to libosip CVS and its new OSIP_TRACE MACROs. + 4: fix presence handling. + 5: fix expires header in REGISTER. + + +Monday Aug 26 2002: linphone-0.9.0 + - the sdp rtpmap string for alaw and mulaw codec was incorrect. + +Sunday Aug 4 2002: linphone-0.9.0pre3 + Non visible changes: + - Linphone's internal audio architecture is ported to the new mediastreamer architecture. + The mediastreamer library is already present in linphone since October 29 2001 but + was never used at this time by the core program. Now lots of work has be done inside the + mediastreamer so that it is ready to be used by the core program. As a consequence, the + old architecture defined by the audio/ directory and the codec.c io.c files is dropped. + The mediastreamer architecture provides a modular framework for audio and video + processing. It includes various audio and video codecs (or wrappers to third party + audio and video codecs). + Visible changes: + - The Speex codec (http://speex.sourceforge.net) is now availlable to linphone, since it has + its mediastreamer wrapper. This patent-free codec provides two bitrates, the lowest + being able to work with 56k dialup connections. This is a very important step, because + from now only the low quality LPC10 codec was availlable for such connections. + - Thanks to Florian Winsterstein (f-win at gmx.de), a console version of linphone called + "linphonec" is availlable. Linphonec can be compiled without gnome. + +Wednesday May 8 2002: linphone-0.8.0 + Visible changes: + - Updated to libosip-0.8.5, that reflects the lastest sip draft. + - Uses the SDP parser the libosip, and uses also a modified version of its SDP negociator. + The MediaDesc object is removed, now osipua users have to deal with BodyHandler's, as the + SdpHandler that deals with sdp message generation and negociation. + The SDP parser and negociator can use the a=rtpmap fields, so that compliance is improved. + - LPC10-1.5 codec has been assigned payload type 115 instead of 4 previously. This breaks + compatibility with older versions of linphone. + - oRTP (the new RTP library) is used in place of the old lprtplib. + - fix endianess problems in the audio part. + Non visible changes (changes on libraries not currently used by linphone but used later): + - mediastreamer has new working objects: webcam image capture, mpeg encoding and decoding + thanks to the libavcodec (ffmpeg) library, rtp wrapper thanks to oRTP. + +Tuesday April 15 2002: linphone-0.7.2 + - A crash in property box "apply" fixed. + - bugfix in osipua. + +Tuesday March 12 2002: linphone-0.7.1 + - Some bug fixes by Bryan Ogawa in osipua: route, record-route, tags. + +Friday March 1 2002: linphone-0.7.0 + - Digest authentification support added by Aymeric. + - Improvements in property box. + - Translations in German and Italian by J.J. Sarton and A. Zanoni + - Bugfix and improvements in the osipua stack. + - Better handling of the registration parameters (the user can set its own address of record). + + +Thu December 6 2001 + -osipua.c: Memory allocations. + fi call of from_tag_add(...,sgetcopy(ua->fromtag)); + -utils.c: Memory allocations. + -CallLegs are removed automatically by the osipua layer (eg: when a transaction timed out). + +Tue November 27 2001 + -Bugfix in osipua for proxy support: record-route and route header support, request-uri bug fixed. + -New choice "outbound proxy" in the property box. + -Fix compilation issues. + + +Mon October 29 2001 + -New unithreaded design of the osipua library, based on libosip-0.7.x series. + -Asynchronous name resolution in osipua. + -To and From tag support added. + -Proxy support added. The user can choose between registering for a redirect server, or + registering for a proxy server. When he choose proxy, then all requests are sent to the proxy. + -New good looking graphical interface. + -Mediastreamer is included, but still unused. It has a begin of gtkdoc dcocumentation. + +Wed September 26 2001 + -Add registration and redirection ability in gui and osipua. + -Critical bugs in osipua/osip fixed. + -Display all sip error strings in appbar. + -Documentation translated in French. + +Tue August 21 2001 + - Add address book functionnality + - Add ringback + - Minor bugfixes in configure.in, src/callbacks.c + - Work with libosip-0.6.1 + +Wed August 1 2001: + - Integration with osip sip stack. lpsiplib is no more used and abandonned. osipua provides the session level + on top of osip. + - added G711 codecs. + - configuration structures and api re-written for more clarity. + - new codec selection box + - new sytem for codec registration + - automatic selection of codecs regarding to network connection type. + - add resizing ability for icon applet. + + +June 2001: linphone-0.3.0 + -Nearly all code in linphone is object oriented. + -linphone can be run as a gnome applet, or as a silent dameon, or as a normal application. + -bugfixes in sip/sdp messages. + -addition of a test program called sipomatic that can automatically answers to call. (for test) + -add io_disk implementation of the audio lib. this can be used to replace the sond card by io on file system. + + + +Tue May 15 2001: linphone-0.2.1 + -Fix a stupid bug in the audio library. + +Fri May 11 2001: linphone-0.2.0 + -add many missing features of version 0.1.0 (for the property box) + -audio levels on the main window. + -Sip library modified: now it uses one thread, and should be able to handle several calls in the future. + -audio library is more performant. It is able to find itself the best blocksize (latency) by testing the driver. + -interactive help on the property box and user manual. + -add an icon. + +linphone-0.1.0 : + Released on april,19 2001 + Initial version. diff --git a/linphone/INSTALL b/linphone/INSTALL new file mode 100644 index 000000000..23e5f25d0 --- /dev/null +++ b/linphone/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/linphone/Makefile.am b/linphone/Makefile.am new file mode 100644 index 000000000..7a3c39db4 --- /dev/null +++ b/linphone/Makefile.am @@ -0,0 +1,42 @@ +## Process this file with automake to produce Makefile.in + +# let make re-run automake upon need +ACLOCAL_AMFLAGS = -I m4 + +if EXTERNAL_ORTP +ORTP_DIR = +else +ORTP_DIR = oRTP +endif + +SUBDIRS = m4 pixmaps po ipkg $(ORTP_DIR) mediastreamer2\ + media_api coreapi console gtk gtk-glade share + + +EXTRA_DIST = config.rpath linphone2.glade BUGS linphone.kdevprj \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + README.arm \ + autogen.sh \ + linphone.spec.in linphone.spec +ACLOCAL_FLAGS=-I$(top_srcdir)/m4 + +DISTCLEANFILES= intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache + +# `make rpm' + +all-local: linphone.spec +linphone.spec: linphone.spec.in + +.phony: rpm +rpm: + $(MAKE) dist +# Create "Specfile" at the same level as the tarball content + -rm -f $(PACKAGE)-$(VERSION).tar + gunzip $(PACKAGE)-$(VERSION).tar.gz + cp $(PACKAGE).spec Specfile + tar --append --file=$(PACKAGE)-$(VERSION).tar Specfile + gzip $(PACKAGE)-$(VERSION).tar +# + TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz diff --git a/linphone/NEWS b/linphone/NEWS new file mode 100644 index 000000000..ea93cc1c8 --- /dev/null +++ b/linphone/NEWS @@ -0,0 +1,75 @@ +linphone-2.1.1 -- February 13, 2008 + * fix interroperability bug with Asterisk about a BYE not sent by linphone. + * fix alsa support weakness (capture underruns not recovered) + +linphone-2.1.0 -- January 25, 2008 + * 4CIF support + * enable resizing of video output + * hu translation added + +linphone-2.0.1 -- November 30, 2007 + * fix interop issue with asterisk + * answer OPTIONS and other SIP messages + * allow usage of ALSA user pcm devices with the sound->alsadev config item. + +linphone-2.0.0 -- November 15, 2007 + * port to libeXosip2-3.0.x with libosip2-3.0.x + * implements early media + * implements incoming re-INVITE + * presence support improvements + * ipv6 working on windows + * implements SDP over 200ok/ACK + * add experimental snow codec support + * answers to VFU request in SIP-INFO by sending an I-frame. + * ffmpeg rate control enabled, improved mpeg4 quality for low bandwidths + * separate video grabbing and display in linphonec + +linphone-1.7.1 -- April 16, 2007 + * cz translation + * compilation bugfixes (when video support is disabled) + * fix IM icons path bug + +linphone-1.7.0 -- April 11, 2007 + * new splash screen when no webcam is detected + * new friend commands for linphonec + * gnome interface becomes gtk-only + * fix issue with codec bitrate settings when no bandwidth limits are given + * open rtp sockets before sending SDP offer or answer (so that we don't miss the + first I-frame) + +linphone-1.6.0 -- January 23, 2007 + * Video4Linux V2 support with mjpeg cameras + * use MPEG4 config string provided in the SDP (if any) + * fix bug when choosing an invalid ring sound file + * fix bug when using quickcam driver with CIF size + * reduce audio bandwidth usage for <128kbit/s connections with video + +linphone-1.5.1 -- November 14, 2006 + * fix translations + +linphone-1.5.0 -- October 11, 2006 + * compliant theora support (using Luca Barbato's draft) + * mpeg4 support (compliant with RFC3016) + * controls to display and modify video codec list (gnome interface) + * banwidth usage improvements + * splash screen when no webcam is detected + +linphone-1.4.1 -- September 18, 2006 + * fixes crash when attempting to make two simultaneous calls + * fixes crash when having no soundcard + * require theora>=1.0.0-alpha7 + * do not allow resizing of the gnome interface + * do not change mixer settings at startup + +linphone-1.4.0 -- September 11, 2006 + * no more glib dependency at all + * new mediastreamer2 framework for audio/video streaming + * stable video support with H.263-1998 + * echo cancelation + * experimental theora support + * jack support unported to mediastreamer2, sorry : volunteer needed + * video resolution and framerate set according to bandwidth constraints. + * linphonec new "soundcard" command to list and choose sound devices. + * new download and upload bandwidth parameters used to find suitable video/audio codec choice and parameters. + * new 'play' and 'record' functions to linphonec to play and record wav files + * arts sound backend diff --git a/linphone/README b/linphone/README new file mode 100644 index 000000000..27aafdbcd --- /dev/null +++ b/linphone/README @@ -0,0 +1,53 @@ +******************Building linphone *********************************** +- you need at least: + - libosip2>=3.0.3 + - libeXosip2>=3.0.3 + - speex>=1.1.6 + - libreadline + + gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional) + + if you want to gtk interface: + - gtk>=2.4.0 + + if you want video support: + - SDL>=1.2.10 + - libavcodec (ffmpeg) from a year 2007 or later cvs + +with their corresponding -dev or -devel package if you don't use source packages. + + + +************************************** user documentation ********************* +go to linphone's web site: http://www.linphone.org + + +******************************** DEVELOPER documentation ******************** + +Here is a short description of the content of the source tree. + +- oRTP/ is a poweful implementation of the RTP protocol. See the oRTP/README for more details. + It is used by the mediastreamer to send and receive streams to the network. + +- mediastreamer2/ is one of the important part of linphone. It is a framework library for audio + and video processing. It contains several objects for grabing audio and video and outputing + it (through rtp, to file). + It contains also codec objects to compress audio and video streams. + The mediastream.h files contain routines to easyly setup audio streams. + +- mediastreamer/ is deprecated. + +- media_api/ is going to be an easy to use library to handle audio and video session. It uses + the mediastreamer at the backend to do the processing. It is going to be the only interface + between the core application and the mediastreamer. At the moment this library is still in + early stages of development and is unused by the core application. + +- coreapi/ is the central point of linphone, which handles relationship between sip signalisation and media + streaming. It contains an easy to use api to create a sip phone. + +- gtk/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above. + +- console/ + * linphonec.c is the main file for the console version of linphone. + * sipomatic.c / sipomatic.h contains the code for sipomatic, the test program that auto-answer to linphone calls. If you want to understand + how linphone runs, this is a good start example. + +- share/ contains translation, documentation, rings and hello sound files. + diff --git a/linphone/README.CVS b/linphone/README.CVS new file mode 100644 index 000000000..53b782def --- /dev/null +++ b/linphone/README.CVS @@ -0,0 +1,12 @@ +In order to compile from CVS, you have to first install: +- pkg-config +- intltool (intltool-devel if rpm) +- install the mandatory and optional dependencies described in README file. + +Then: + ./autogen.sh #to generate the configure script + ./configure # with desired options + make + + +Simon MORLAT < simon dot morlat at linphone dot org > diff --git a/linphone/README.M68k.txt b/linphone/README.M68k.txt new file mode 100644 index 000000000..a3659f8ad --- /dev/null +++ b/linphone/README.M68k.txt @@ -0,0 +1,93 @@ + LINPHONE ON M68k-LINUX (by GIAN) + ******************************** + +The console version of linphone works on arm-linux, but also on m68k-linux? I’m trying to provide this: + +* I used the same toolchain specified in the LTIB menu configuration, that is, on my system: +/opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e + +* I have created within my home directory a ColdFire-install-environment/ directory, copied into it the fresh tarballs of libogg-1.1.3, libosip2-2.2.2, speex-1.1.12, linphone-1.4.0 readline-5.1 and ncurses-5.5 (readline needs ncurses) Uncompressed all these +tarballs. + +Very important things common to all packages being cross compiled: +****************************************************************** +* Copy the ipaq-config.site in the ipkg/ directory of linphone into some safe place, for example: +cp /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/linphone-1.4.0/ipkg/ipag-config.site /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/ +Edit the ipaq-config.site file and replace all the arm-linux strings with m68k-linux one. Add also the –mcfv4e flag to the CFLAGS, CXXFLAGS, and CPPFLAGS labels. +* You need a directory that we call M68K_INSTALL_TREE that will own files in the same way they will be installed on the target computer. + +mkdir /ColdFire-linphonec-1.4.0-mcfv4e +export M68K_INSTALL_TREE=/ColdFire-linphonec-1.4.0-mcfv4e +export CONFIG_SITE=/home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/ipaq-config.site +export PATH=$PATH:/opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/bin + + +Cross compiling ncurses for M68k: +******************************** +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --with-shared +make +make install DESTDIR=$M68K_INSTALL_TREE + + +Cross compiling readline for M68k: +********************************* +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static +make +make install DESTDIR=$M68K_INSTALL_TREE + + + +Cross compiling libosip for M68k: +******************************** +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static +make +make install DESTDIR=$M68K_INSTALL_TREE + + +Cross compiling libogg for M68k: +******************************** +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static –enable-fixed-point +make +make install DESTDIR=$M68K_INSTALL_TREE + + +Cross compiling speex for M68k: +******************************** +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static --enable-fixed-point --enable-m68k-asm --with-ogg=/ColdFire-linphonec-1.4.0-mcfv4e/usr --with-ogg-includes=/ColdFire-linphonec-1.4.0-mcfv4e/usr/include –with-ogg-libraries=/ColdFire-linphonec-1.4.0-mcfv4e/usr/lib --disable-oggtest +make +make install DESTDIR=$M68K_INSTALL_TREE + + +cp /home/gianluca/ColdFire-iinstall-environment/linphone-1.4.0-install/linphone-1.4.0/mediastreamer2/src/.libs/libquickstream.so.0.0.0 /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib +cd /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib +ln -s libquickstream.so.0.0.0 libquickstream.so.0 +ln -s libquickstream.so.0.0.0 libquickstream.so + +cp /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/linphone-1.4.0/mediastreamer2/src/.libs/libmediastreamer.so.0.0.0 /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib +cd /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib +ln -s libmediastreamer.so.0.0.0 libmediastreamer.so.0 +ln -s libmediastreamer.so.0.0.0 libmediastreamer.so + + +Cross compiling linphone for M68k: +******************************** +First you need to remove all .la files from the M68K_INSTALL_TREE because it confuses libtool and makes +the linker use your build machine binaries instead of the m68k-crosscompiled ones. +rm -f $M68K_INSTALL_TREE/usr/lib/*.la +#for some reason pkg-config doesn't like cross-compiling... +export PKG_CONFIG=/usr/bin/pkg-config +./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static --disable-strict --enable-gnome_ui=no --enable-alsa --disable-glib --disable-video --with-osip=$ARM_INSTALL_TREE/usr --with-osipparser=$ARM_INSTALL_TREE/usr --with-readline=$ARM_INSTALL_TREE/usr SPEEX_CFLAGS="-I$ARM_INSTALL_TREE/usr/include" SPEEX_LIBS="-L$ARM_INSTALL_TREE/usr/lib -lspeex" +make +make install DESTDIR=$M68K_INSTALL_TREE + + +Binaries can also be stripped with m68k-linux-strip to save more space. + + +Running linphone under the ColdFire board +******************************************** + +You just have to start linphone from a terminal by typing 'linphonec'. + +Gianluca Salvador + diff --git a/linphone/README.arm b/linphone/README.arm new file mode 100644 index 000000000..5020729f3 --- /dev/null +++ b/linphone/README.arm @@ -0,0 +1,106 @@ + LINPHONE ON ARM-LINUX (HANDHELD COMPUTERS) + ****************************************** + +The console version of linphone works on arm-linux and has been tested on ipaqs +under the familiar linux distribution (http://www.handhelds.org). +You can find .ipk binary packages on the linphone's download page. +If you want to build your own arm-linux packages, here are some instructions to +cross compile linphone and its dependencies: readline, speex and libosip. +This is my own experience on cross compiling software. As there is no precise +step by step documentation (as far as I know) on how to cross-compile on arm, +there is no guaranty that the following instructions are the best way to do it. +First, be aware that only the console version of linphone can compile on ARM. + + +* You need the lastest arm toolchain from http://www.handhelds.org. Uncompress it in / . + It contains all the cross-compilation tools. Be sure that the arm-linux-gcc binaries + are in your PATH (export PATH=$PATH:/usr/local/arm/3.4.1/bin/ , for example) +* create within your home directory a arm/ directory, copy into it the fresh + tarballs of libosip2>=2.2.x, speex>=1.1.6, linphone>=1.2.1 readline>=5.1 and ncurses>=5.5 (readline needs ncurses) + Uncompress all these + tarballs. + + +Very important things common to all packages being cross compiled: +****************************************************************** +* copy the ipaq-config.site in the ipkg/ directory of linphone into some safe place, +for example: ~/ipaq-config.site . +* You need a directory that we call ARM_INSTALL_TREE that will own files in the same way they will be installed on the target computer. +It is also used to build linphone over the arm binaries of its dependencies (speex,osip,ncurses,readline). + +For example: + +export CONFIG_SITE=~/ipaq-config.site +export ARM_INSTALL_TREE=/armbuild + + +Cross compiling ncurses for ARM: +******************************** +./configure --prefix=/usr --host=arm-linux --with-gnu-ld --with-shared +make +make install DESTDIR=$ARM_INSTALL_TREE +make install DESTDIR=`pwd`/armbuild + + +Cross compiling readline for ARM: +********************************* +./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static +make +make install DESTDIR=$ARM_INSTALL_TREE +make install DESTDIR=`pwd`/armbuild + + + +Cross compiling libosip for ARM: +******************************** +./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static +make +make install DESTDIR=$ARM_INSTALL_TREE +make install DESTDIR=`pwd`/armbuild + +Cross compiling speex for ARM: +******************************** +First you need to remove ogg headers from your build system to avoid a dirty conflict between +your build machine binaries and the arm binaries. They are usually in a libogg-dev package (rpm or deb). +Then: +./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static --enable-fixed-point --enable-arm-asm +make +make install DESTDIR=$ARM_INSTALL_TREE +make install DESTDIR='pwd'/armbuild + + +Cross compiling linphone for ARM +******************************** +First you need to remove all .la files from the ARM_INSTALL_TREE because it confuses libtool and makes +the linker use your build machine binaries instead of the arm-crosscompiled ones. +rm -f $ARM_INSTALL_TREE/usr/lib/*.la +#for some reason pkg-config doesn't like cross-compiling... +export PKG_CONFIG=/usr/bin/pkg-config +./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static \ + --disable-glib --with-osip=$ARM_INSTALL_TREE/usr \ + --with-readline=$ARM_INSTALL_TREE/usr \ + SPEEX_CFLAGS="-I$ARM_INSTALL_TREE/usr/include" \ + SPEEX_LIBS="-L$ARM_INSTALL_TREE/usr/lib -lspeex " +make +make install DESTDIR='pwd'/armbuild + +You can use the install trees libosip2-x.x.x/armbuild speex-x.x.x/armbuild and +linphone-0.x.x/armbuild/ to make binary packages of +each software, as ipkgs for the familiar distribution (http://www.familiar.org). +In the ipkg/ directory of linphone you can find .control files for ipkg-build. +In order to make the osip ipkg, you have to do the following: +- create a directory named CONTROL inside libosip2-2.2.x/armbuild +- copy the libosip.control file into CONTROL/ and rename it into "control". +- edit the "control" file to adjust version number accordingly. +- remove the non essential parts of libosip inside libosip2-2.x.x/armbuild/usr/ : just + leave the lib/ directory. This saves space on the destination computer. +- then inside libosip2-2.x.x, run ipkg-build -o root -g root armbuild +The same procedure applies to make linphone's ipkg. +Binaries can also be stripped with arm-linux-strip to save more space. + +Running linphone under the handheld computer +******************************************** + +You just have to start linphone from a terminal by typing 'linphonec'. + +Simon diff --git a/linphone/TODO b/linphone/TODO new file mode 100644 index 000000000..3a0199c38 --- /dev/null +++ b/linphone/TODO @@ -0,0 +1,22 @@ +hot stuff: +--------- + +* ice support +* run a user given command upon incoming calls +* linphonec on win32 +* RTP inactivity timeout to close lost calls. + + +low priority: +------------- + +* random RTP ports (to enable direct mapping NAT) +* zeroconf support for advertising services (cool stuff!) +* have the possibility to define several profiles (config files) and switch between them +* display call duration +* help tips for the registration box +* The length (or duration) of the call could be displayed (see icons2.png) +* 2. There could be a sound effect for "busy" - a short "beep-beep-beep" would be sufficient (try http://www.google.com/search?q=busy.wav) +* The call history could be a bit more clear (see history.png). And it + should be saved somewhere, so you can track your calls if you need to... +* move resampling stuff to use speex instead of libresample. \ No newline at end of file diff --git a/linphone/autogen.sh b/linphone/autogen.sh new file mode 100755 index 000000000..b8bd738db --- /dev/null +++ b/linphone/autogen.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +AM_VERSION="1.9" +if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then + # automake-1.9 (recommended) is not available on Fedora 8 + AUTOMAKE=automake + ACLOCAL=aclocal +else + ACLOCAL=aclocal-${AM_VERSION} + AUTOMAKE=automake-${AM_VERSION} +fi + +echo "Generating build scripts in linphone..." +set -x +libtoolize --copy --force +autoheader +$ACLOCAL -I m4 +$AUTOMAKE --force-missing --add-missing --copy +autoconf +rm -rf config.cache + +echo "Generating build scripts in oRTP..." +cd oRTP && ./autogen.sh && cd - + +echo "Generating build scripts in mediastreamer2..." +cd mediastreamer2 && ./autogen.sh && cd - diff --git a/linphone/build.mk b/linphone/build.mk new file mode 100755 index 000000000..be5fe460d --- /dev/null +++ b/linphone/build.mk @@ -0,0 +1,140 @@ +#!/usr/bin/make -f +# This script "automatically" builds some binary distribution of linphone : +# debian packages (sid) and familiar (arm-linux/ipaq) packages. +# generation of rpms can be added in the future. +# it can be invoked in the following way: +# ./build.mk debs LINPHONE= +# ./build.mk all LINPHONE= GLIB=2.2's tar.gz> +# LIBOSIP= +# + + +ARMROOT=/armbuild +ARMTOOLCHAIN=/usr/local/arm/3.2.3/bin + +all: check debs ipks + + +clean: + rm -f *.stamp + rm -rf build-debs + rm -rf build-ipks + +check: + @if test -n "${LD_PRELOAD}" ; then echo "ERROR: LD_PRELOAD is set !!"; exit 1;fi + +ipks: ipkg-tools.stamp libosip.ipk linphone.ipk clean + +ipkg-tools.stamp: + if which ipkg-build ; then echo "Found ipkg-build." ;\ + else echo "** ERROR ** Cannot find ipkg-build"; exit 1; fi + if test -e $(ARMTOOLCHAIN)/arm-linux-gcc ; then \ + echo "arm toolchain seems ok.";\ + else echo "** ERROR ** Cannot find arm toolchain."; exit 1; fi + touch ipkg-tools.stamp + +glib.ipk : glib.stamp linphone-sources-ipk.stamp + rm -rf build-ipks/glib* + cp $(GLIB) build-ipks/. + export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \ + cd build-ipks && tar -xvzf glib*.tar.gz && rm -f glib*.tar.gz && cd glib* && \ + ./configure --prefix=$(ARMROOT)/usr --host=arm-linux --with-gnu-ld --disable-static \ + && make AM_CFLAGS=-DSSIZE_MAX=0xffffffff && make install && \ + make install prefix=`pwd`$(ARMROOT)/usr + echo "Building .ipk file..." + cd build-ipks/glib*$(ARMROOT) && mkdir CONTROL && cd CONTROL && \ + cp ../../../linphone*/ipkg/glib.control control && \ + cd ../.. && rm -rf armbuild/usr/include + cd build-ipks/glib* && ipkg-build -o root -g root armbuild/ + cp build-ipks/glib*/*.ipk . + +libosip.ipk : libosip.stamp linphone-sources-ipk.stamp + rm -rf build-ipks/libosip* + cp $(LIBOSIP) build-ipks/ + export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \ + cd build-ipks && tar -xvzf libosip*.tar.gz && rm -f libosip*.tar.gz && cd libosip* && \ + ./configure --prefix=$(ARMROOT)/usr --host=arm-linux --with-gnu-ld --disable-static \ + && make && make install && make install prefix=`pwd`$(ARMROOT)/usr + echo "Building .ipk file..." + cd build-ipks/libosip*$(ARMROOT) && mkdir CONTROL && cd CONTROL && \ + cp ../../../linphone*/ipkg/libosip.control control &&\ + cd ../.. && rm -rf armbuild/usr/include + cd build-ipks/libosip* && ipkg-build -o root -g root armbuild/ + cp build-ipks/libosip*/*.ipk . + + +linphone.ipk : linphone.stamp linphone-sources-ipk.stamp + export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \ + cd build-ipks/linphone* && export PKG_CONFIG_PATH=$(ARMROOT)/usr/lib/pkgconfig &&\ + ./configure --prefix=$(ARMROOT)/usr --with-realprefix=/usr --host=arm-linux \ + --with-gnu-ld --disable-static --disable-gnome_ui --disable-glib --with-osip=$(ARMROOT)/usr \ + --disable-ogg --disable-rtcp && make && make install prefix=`pwd`$(ARMROOT)/usr + echo "Building .ipk file..." + cd build-ipks/linphone*$(ARMROOT) && mkdir -p CONTROL && cd CONTROL && \ + cp -f ../../ipkg/linphone.control control &&\ + cd ../.. && rm -rf armbuild/usr/include armbuild/usr/share/gtk-doc \ + && cd armbuild/usr/share/sounds/linphone/rings && \ + rm -f rock.wav sweet.wav bigben.wav toy.wav tapping.wav synth.wav && cd - \ + cd build-ipks/linphone* && ipkg-build -o root -g root armbuild/ + cp -f build-ipks/linphone*/*.ipk . + +build-ipks.stamp: + -@touch $(ARMROOT)/dummy + @if test -e $(ARMROOT)/dummy ; \ + then echo "armroot is fine: $(ARMROOT)"; \ + else \ + echo "** ERROR: you need to create a $(ARMROOT) directory readable and writeable by the user running this build script.";\ + exit 1;\ + fi + rm -f $(ARMROOT)/dummy + touch build-ipks.stamp + mkdir build-ipks + + +linphone-sources-ipk.stamp: linphone.stamp build-ipks.stamp + cp $(LINPHONE) build-ipks/. + cd build-ipks && tar -xvzf linphone*.tar.gz && cp linphone*/ipkg/ipaq-config.site . \ + && rm -f linphone*.tar.gz + touch linphone-sources-ipk.stamp + +debs: linphone.stamp clean + rm -f linphone.stamp + rm -rf build-debs + mkdir build-debs + cp $(LINPHONE) build-debs/. + cd build-debs && tar -xvzf *.tar.gz && cd linphone* && dpkg-buildpackage -rfakeroot + cp build-debs/*.deb . + +linphone.stamp: + @if test -n "$(LINPHONE)" ; \ + then echo "linphone source is $(LINPHONE)" ; \ + touch linphone.stamp; \ + else \ + echo "No linphone source found." ; \ + exit 1; \ + fi + +libosip.stamp: + @if test -n "$(LIBOSIP)" ; \ + then echo "libosip source is $(LIBOSIP)" ; \ + touch libosip.stamp; \ + else \ + echo "No libosip source found." ; \ + exit 1; \ + fi + +glib.stamp: + @if test -n "$(GLIB)" ; \ + then echo "glib source is $(GLIB)" ; \ + else \ + echo "No glib source found." ; \ + exit -1; \ + fi + @if which glib-genmarshal ; \ + then \ + echo "native glib-2.2 found on build host." ; \ + touch glib.stamp ;\ + else \ + echo "** ERROR ** You need a working glib>2.2 on the build machine to be able to crosscompile it for arm." ;\ + echo "** ERROR ** Please install a glib on this machine."; exit 1; \ + fi diff --git a/linphone/config.rpath b/linphone/config.rpath new file mode 100755 index 000000000..c492a93b6 --- /dev/null +++ b/linphone/config.rpath @@ -0,0 +1,614 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2006 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | pw32* | os2*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux*) + case $cc_basename in + icc* | ecc*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + sco3.2v5*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + interix3*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. +libname_spec='lib$name' +case "$host_os" in + aix3*) + ;; + aix4* | aix5*) + ;; + amigaos*) + ;; + beos*) + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32*) + shrext=.dll + ;; + darwin* | rhapsody*) + shrext=.dylib + ;; + dgux*) + ;; + freebsd1*) + ;; + kfreebsd*-gnu) + ;; + freebsd* | dragonfly*) + ;; + gnu*) + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + ;; + interix3*) + ;; + irix5* | irix6* | nonstopux*) + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux*) + ;; + knetbsd*-gnu) + ;; + netbsd*) + ;; + newsos6) + ;; + nto-qnx*) + ;; + openbsd*) + ;; + os2*) + libname_spec='$name' + shrext=.dll + ;; + osf3* | osf4* | osf5*) + ;; + solaris*) + ;; + sunos4*) + ;; + sysv4 | sysv4.3*) + ;; + sysv4*MP*) + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + ;; + uts4*) + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <= 2.4.0 gthread-2.0, ,gtk_ui=false) + AC_SUBST(LIBGTK_CFLAGS) + AC_SUBST(LIBGTK_LIBS) + + if test "$gtk_ui" = "true" ; then + AC_DEFINE(HAVE_GTK,1,[Defined if we can use the gtk api]) + else + missing_gtk_libs=true + fi +else + echo "GTK interface compilation is disabled." +fi + + +if test "$gtk_ui" = "true" ; then + PKG_CHECK_MODULES(GNOME_APPLETS, libpanelapplet-2.0 >= 2.0.0 , + build_gnome_applet=true,build_gnome_applet=false) + AC_SUBST(GNOME_APPLETS_CFLAGS) + AC_SUBST(GNOME_APPLETS_LIBS) + PKG_CHECK_MODULES(LIBGLADE, libglade-2.0 >= 2.4.0 , glade_ui=true, glade_ui=false) + AC_SUBST(LIBGLADE_CFLAGS) + AC_SUBST(LIBGLADE_LIBS) +else + build_gnome_applet=false +fi + + +dnl os-specific problems not handled by existing macros. +case "$host_os" in + *freebsd*) + LDFLAGS="$LDFLAGS -pthread" + ;; +esac + +case "$host_cpu" in + *arm*) + AC_DEFINE(__ARM__,1,[Defined if we are compiling for arm processor]) + use_arm_toolchain=yes + ;; +esac + +AC_ARG_WITH( realprefix, + [ --with-realprefix Set the real installation prefix. This option has to be used for cross-compilation only. (ex:/usr or /usr/local)[default=none] ], + [ realprefix=${withval}],[ realprefix="none" ]) + + + +AC_ARG_ENABLE(manual, + [ --disable-manual Do not attempt to build html linphone's user documentation], + [case "${enableval}" in + yes) build_manual=yes ;; + no) build_manual=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-manual) ;; + esac],[build_manual=yes]) + + +dnl enable ipv6 support +AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Turn on ipv6 support], + [case "${enableval}" in + yes) ipv6=true;; + no) ipv6=false;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ipv6) ;; + esac],[ipv6=true]) +IPV6_CFLAGS= +if test x$ipv6 = xtrue ; then + IPV6_CFLAGS=-DINET6 +fi +AC_SUBST(IPV6_CFLAGS) + +dnl enable truespeech codec support +AC_ARG_ENABLE(truespeech, + [ --enable-truespeech Turn on TrueSpeech support (x86 only)], + [case "${enableval}" in + yes) truespeech=true;; + no) truespeech=false;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-truespeech) ;; + esac],[truespeech=false]) +TRUESPEECH_CFLAGS= +if test x$truespeech = xtrue ; then + TRUESPEECH_CFLAGS=-DTRUESPEECH +fi +AC_SUBST(TRUESPEECH_CFLAGS) +AM_CONDITIONAL([BUILD_TRUESPEECH], [test x$truespeech = xtrue]) + + + + +dnl support for RSVP (by Vincent Maury) +AC_ARG_ENABLE(rsvp, +[ --enable-rsvp enable support for QoS reservations.], +AC_DEFINE(VINCENT_MAURY_RSVP,1,[Tell whether RSVP support +should be compiled.]) ) + +if test "x${prefix}" = "xNONE"; then + prefix=${ac_default_prefix} +fi + +dnl Set PACKAGE_LOCALE_DIR in config.h. +DATADIRNAME=share +AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale",[Defines the place where locales can be found]) + +AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${prefix}/${DATADIRNAME}",[Defines the place where data are found]) + +dnl Set PACKAGE_SOUND_DIR in config.h. +AC_DEFINE_UNQUOTED(PACKAGE_SOUND_DIR, "${prefix}/${DATADIRNAME}/sounds/linphone",[Defines the place where linphone sounds are found]) + + +dnl check if we have the getifaddrs() sytem call +AC_CHECK_FUNCS(getifaddrs) + +dnl check for osip2 +LP_CHECK_OSIP2 + +dnl setup flags for exosip library +LP_SETUP_EXOSIP + +if test "$console_ui" = "true" ; then +dnl check gnu readline +LP_CHECK_READLINE +else +echo "Console interface compilation is disabled." +fi + +AC_WORDS_BIGENDIAN + +dnl normaly this should only by done by mediastreamer2/configure.ac +dnl but to workaround bugs when cross-compiling for arm-linux, +dnl we need to have SPEEX_LIBS defined +dnl Furthermore it is good to repeat here all mediastreamer2 toggles +dnl since top-level configure --help will not print them. + +PKG_CHECK_MODULES(SPEEX, speex >= 1.1.6, build_speex=yes) +AC_SUBST(SPEEX_LIBS) + +dnl conditionnal build of video support +AC_ARG_ENABLE(video, + [ --enable-video Turn on video support compiling], + [case "${enableval}" in + yes) video=true ;; + no) video=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-video) ;; + esac],[video=true]) + +AC_ARG_WITH( ffmpeg, + [ --with-ffmpeg Sets the installation prefix of ffmpeg, needed for video support. [default=/usr] ], + [ ffmpegdir=${withval}],[ ffmpegdir=/usr ]) + +AC_ARG_WITH( sdl, + [ --with-sdl Sets the installation prefix of libSDL, needed for video support. [default=/usr] ], + [ libsdldir=${withval}],[ libsdldir=/usr ]) + +if test "$video" = "true"; then + AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available]) +fi + +AC_ARG_ENABLE(alsa, + [ --enable-alsa Turn on alsa native support compiling], + [case "${enableval}" in + yes) alsa=true ;; + no) alsa=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-alsa) ;; + esac],[alsa=true]) + +AC_ARG_ENABLE(artsc, + [ --enable-artsc Turn on artsc (kde) sound input/output (auto) ], + [case "${enableval}" in + yes) artsc=true ;; + no) artsc=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-artsc) ;; + esac],[artsc=false]) + +AC_ARG_ENABLE(portaudio, + [ --enable-portaudio Turn on portaudio native support compiling], + [case "${enableval}" in + yes) portaudio=true ;; + no) portaudio=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-portaudio) ;; + esac],[portaudio=false]) + +dnl same thing for media_api +AM_CONDITIONAL(BUILD_MEDIA_API, test x$media_api = xtrue) + + +dnl build console if required +AM_CONDITIONAL(BUILD_CONSOLE, test x$console_ui = xtrue) +dnl build gtk if required +AM_CONDITIONAL(BUILD_GTK, test x$old_gtk_ui = xtrue) +dnl build gnome applet if possible +AM_CONDITIONAL(BUILD_GNOME_APPLET, test x$build_gnome_applet = xtrue) +dnl special things for arm-linux cross compilation toolchain +AM_CONDITIONAL(ARMBUILD, test x$use_arm_toolchain = xyes) +dnl compilation of gtk-glade user interface +AM_CONDITIONAL(BUILD_GLADE_UI, [test x$glade_ui = xtrue ] ) + +################################################## +# Stricter build options (after external packages) +################################################## + + +AC_ARG_ENABLE(strict, + AC_HELP_STRING([--enable-strict], + [Build with stricter options (gcc only) @<:@yes@:>@]),[ + strictness="${enableval}"],[strictness=yes] +) + +if test "$GCC$strictness" = "yesyes" ; then + STRICT_OPTIONS="-Wall -Wp,-D_FORTIFY_SOURCE=2" + STRICT_OPTIONS="$STRICT_OPTIONS -Werror" + CFLAGS="$CFLAGS -fno-strict-aliasing" +fi + +AC_SUBST(STRICT_OPTIONS) + +AC_CONFIG_SUBDIRS( mediastreamer2 ) + +dnl check for db2html (docbook) to generate html user manual +AC_CHECK_PROG(have_sgmltools,sgmltools, yes, no) +AM_CONDITIONAL(ENABLE_MANUAL, test x$have_sgmltools$build_manual = xyesyes ) + +dnl for external use of linphone libs +LINPHONE_CFLAGS="-I${includedir} -I${includedir}/linphone -I${includedir}/ortp " +LINPHONE_LIBS="-L${libdir} -llinphone" +AC_SUBST(LINPHONE_CFLAGS) +AC_SUBST(LINPHONE_LIBS) + + +AC_DEFINE_UNQUOTED(LINPHONE_VERSION,"$PACKAGE_VERSION",[Linphone's version number]) + + +AC_ARG_ENABLE(external-ortp, + [ --enable-external-ortp Use external oRTP library], + [case "${enableval}" in + yes) external_ortp=true ;; + no) external_ortp=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-external-ortp) ;; + esac],[external_ortp=false]) + +if test "$external_ortp" = 'true'; then + LP_CHECK_ORTP +else + AC_CONFIG_SUBDIRS( oRTP ) + ORTP_CFLAGS="-I\$(top_srcdir)/oRTP/include" + ORTP_LIBS="\$(top_builddir)/oRTP/src/libortp.la" + if test x$ac_cv_c_bigendian = xyes ; then + ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN" + fi +fi +AC_SUBST(ORTP_CFLAGS) +AC_SUBST(ORTP_LIBS) + +AM_CONDITIONAL(EXTERNAL_ORTP, [test "$external_ortp" = 'true']) + +dnl Packaging: Pick oRTP version from ${top_srcdir}/oRTP/configure.ac +dnl Feel free to propose an alternative & cleaner version... +top_srcdir=`dirname $0` +changequote(, )dnl +ORTP_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/oRTP/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'` +MS2_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/mediastreamer2/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'` +changequote([, ])dnl +AC_SUBST([ORTP_VERSION]) +AC_SUBST([MS2_VERSION]) + +AC_OUTPUT([ +Makefile +m4/Makefile +po/Makefile.in +pixmaps/Makefile +ipkg/Makefile +ipkg/linphone.control +media_api/Makefile +coreapi/Makefile +gtk/Makefile +gtk-glade/Makefile +console/Makefile +share/Makefile +share/C/Makefile +share/fr/Makefile +share/it/Makefile +share/ja/Makefile +share/cs/Makefile +share/linphone.pc +linphone.spec +]) + +echo "Linphone build configuration ended." + +if test x$gtk_ui = xtrue ; then +echo "* GTK interface will be compiled." +fi +if test x$gtk_ui = xtrue ; then +echo "* Console interface will be compiled." +fi +if test x$glade_ui = xtrue ; then + echo "* Gtk-glade still in early development interface will be compiled" +fi +if test "$have_db2html" = "no" ; then + echo "* db2html not found; user documentation will not be generated." +fi + +echo "Now type 'make' to compile, and then 'make install' as root to install it." diff --git a/linphone/console/.cvsignore b/linphone/console/.cvsignore new file mode 100644 index 000000000..bbea6ace1 --- /dev/null +++ b/linphone/console/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Makefile +Makefile.in +linphonec +sipomatic +wav2raw diff --git a/linphone/console/Makefile.am b/linphone/console/Makefile.am new file mode 100644 index 000000000..d4a481f9e --- /dev/null +++ b/linphone/console/Makefile.am @@ -0,0 +1,37 @@ +## Process this file with automake to produce Makefile.in + +if BUILD_CONSOLE + +INCLUDES = \ + -I$(top_srcdir)\ + -I$(top_srcdir)/coreapi\ + $(ORTP_CFLAGS) \ + -I$(top_srcdir)/exosip \ + -I$(top_srcdir)/mediastreamer2/include + + + +bin_PROGRAMS = linphonec sipomatic + +linphonec_SOURCES = linphonec.c linphonec.h commands.c + +linphonec_LDADD = $(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) $(OSIP_LIBS) + +sipomatic_SOURCES=\ + sipomatic.c sipomatic.h + +sipomatic_LDADD= $(INTLLIBS) \ + $(top_builddir)/coreapi/liblinphone.la \ + $(OSIP_LIBS) + +endif + +AM_CFLAGS=$(STRICT_OPTIONS) -DENABLE_TRACE -D_ORTP_SOURCE $(VIDEO_CFLAGS) $(READLINE_CFLAGS) $(OSIP_CFLAGS) + + + +AM_LDFLAGS= $(top_builddir)/mediastreamer2/src/libmediastreamer.la \ + $(ORTP_LIBS) \ + $(SPEEX_LIBS) \ + $(OSIP_LIBS) + diff --git a/linphone/console/TODO b/linphone/console/TODO new file mode 100644 index 000000000..420d55abe --- /dev/null +++ b/linphone/console/TODO @@ -0,0 +1,20 @@ + +In pseudo-order of priority: +--------------------------- + +- Exctract presence info in friends list + +- Allow friend call arg to be a pattern + +- hide input during password insertions + [ could use ncurses noecho() ] + +- Allow for single-shot mode (call somebody and quit after the fact) + maybe "linphonec [OPTS] " would do.. + Unfortunately the -s switch would confuse people, I'd rather + change its semantic to "source file" where file wold contain + a list of commands, so ./linephone -s myfriend.sip would call + yourfriend... + +- implement "smart" command completion + diff --git a/linphone/console/commands.c b/linphone/console/commands.c new file mode 100644 index 000000000..8ae3a56e3 --- /dev/null +++ b/linphone/console/commands.c @@ -0,0 +1,1236 @@ +/**************************************************************************** + * + * $Id: commands.c,v 1.39 2008/07/03 15:08:34 smorlat Exp $ + * + * Copyright (C) 2006 Sandro Santilli + * Copyright (C) 2004 Simon MORLAT + * + **************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "linphonec.h" + +/*************************************************************************** + * + * Forward declarations + * + ***************************************************************************/ + +extern char *lpc_strip_blanks(char *input); + +/* Command handlers */ +static int lpc_cmd_help(LinphoneCore *, char *); +static int lpc_cmd_proxy(LinphoneCore *, char *); +static int lpc_cmd_call(LinphoneCore *, char *); +static int lpc_cmd_answer(LinphoneCore *, char *); +static int lpc_cmd_terminate(LinphoneCore *, char *); +static int lpc_cmd_call_logs(LinphoneCore *, char *); +static int lpc_cmd_ipv6(LinphoneCore *, char *); +static int lpc_cmd_refer(LinphoneCore *, char *); +static int lpc_cmd_quit(LinphoneCore *, char *); +static int lpc_cmd_nat(LinphoneCore *, char *); +static int lpc_cmd_stun(LinphoneCore *, char *); +static int lpc_cmd_firewall(LinphoneCore *, char *); +static int lpc_cmd_friend(LinphoneCore *, char*); +static int lpc_cmd_soundcard(LinphoneCore *, char *); +static int lpc_cmd_play(LinphoneCore *, char *); +static int lpc_cmd_record(LinphoneCore *, char *); +/* Command handler helpers */ +static void linphonec_proxy_add(LinphoneCore *lc); +static void linphonec_proxy_display(LinphoneProxyConfig *lc); +static void linphonec_proxy_list(LinphoneCore *lc); +static void linphonec_proxy_remove(LinphoneCore *lc, int index); +static int linphonec_proxy_use(LinphoneCore *lc, int index); +static void linphonec_friend_display(LinphoneFriend *fr); +static int linphonec_friend_list(LinphoneCore *lc, char *arg); +static void linphonec_display_command_help(LPC_COMMAND *cmd); +static int linphonec_friend_call(LinphoneCore *lc, unsigned int num); +static int linphonec_friend_add(LinphoneCore *lc, const char *name, const char *addr); +static int linphonec_friend_delete(LinphoneCore *lc, int num); + +/* Command table management */ +static LPC_COMMAND *lpc_find_command(const char *name); + +/*************************************************************************** + * + * Global variables + * + ***************************************************************************/ + +/* + * Commands table. + */ +LPC_COMMAND commands[] = { + { "help", lpc_cmd_help, "Print commands help", NULL }, + { "call", lpc_cmd_call, "Call a SIP uri", + "'call ' or 'c ' " + ": initiate a call to the specified destination." + }, + { "terminate", lpc_cmd_terminate, "Terminate the current call", + NULL }, + { "answer", lpc_cmd_answer, "Answer a call", + "Accept an incoming call." + }, + { "proxy", lpc_cmd_proxy, "Manage proxies", + "'proxy list' : list all proxy setups.\n" + "'proxy add' : add a new proxy setup.\n" + "'proxy remove ' : remove proxy setup with number index.\n" + "'proxy use ' : use proxy with number index as default proxy.\n" + "'proxy unuse' : don't use a default proxy." + }, + { "soundcard", lpc_cmd_soundcard, "Manage soundcards", + "'soundcard list' : list all sound devices.\n" + "'soundcard use ' : select a sound device.\n" + "'soundcard use files' : use .wav files instead of soundcard\n" + }, + { "ipv6", lpc_cmd_ipv6, "Use IPV6", + "'ipv6 status' : show ipv6 usage status.\n" + "'ipv6 enable' : enable the use of the ipv6 network.\n" + "'ipv6 disable' : do not use ipv6 network." + }, + { "refer", lpc_cmd_refer, + "Refer the current call to the specified destination.", + "'refer ' or 'r ' " + ": refer the current call to the specified destination." + }, + { "nat", lpc_cmd_nat, "Set nat address", + "'nat' : show nat settings.\n" + "'nat ' : set nat address.\n" + }, + { "stun", lpc_cmd_stun, "Set stun server address", + "'stun' : show stun settings.\n" + "'stun ' : set stun address.\n" + }, + { "firewall", lpc_cmd_firewall, "Set ", + "'firewall' : show current firewall policy.\n" + "'firewall none' : use direct connection.\n" + "'firewall nat' : use nat address given with the 'nat' command.\n" + "'firewall stun' : use stun server given with the 'server' command.\n" + }, + { "call-logs", lpc_cmd_call_logs, "Calls history", + NULL }, + { "friend", lpc_cmd_friend, "Manage friends", + "'friend list []' : list friends.\n" + "'friend call ' : call a friend.\n" + "'friend add ' : add friend, must be quoted to include\n" + " spaces, has \"sip:\" added if it isn't\n" + " there. Don't use '<' '>' around .\n" + "'friend delete ' : remove friend, 'all' removes all\n" + }, + { "play", lpc_cmd_play, "play from a wav file", + "This feature is available only in file mode (see 'help soundcard')\n" + "'play ' : play a wav file." + }, + { "record", lpc_cmd_record, "record to a wav file", + "This feature is available only in file mode (see 'help soundcard')\n" + "'record ' : record into wav file." + }, + { "quit", lpc_cmd_quit, "Exit linphonec", NULL }, + { (char *)NULL, (lpc_cmd_handler)NULL, (char *)NULL, (char *)NULL } +}; + +/*************************************************************************** + * + * Public interface + * + ***************************************************************************/ + +/* + * Main command dispatcher. + * WARNING: modifies second argument! + * + * Always return 1 currently. + */ +int +linphonec_parse_command_line(LinphoneCore *lc, char *cl) +{ + char *ptr=cl; + char *args=NULL; + LPC_COMMAND *cmd; + + /* Isolate first word and args */ + while(*ptr && !isspace(*ptr)) ++ptr; + if (*ptr) + { + *ptr='\0'; + /* set args to first nonblank */ + args=ptr+1; + while(*args && isspace(*args)) ++args; + } + + /* Handle DTMF */ + if ( isdigit(*cl) || *cl == '#' || *cl == '*' ) + { + while ( isdigit(*cl) || *cl == '#' || *cl == '*' ) + { + linphone_core_send_dtmf(lc, *cl); + sleep(1); // be nice + ++cl; + } + + // discard spurious trailing chars + return 1; + } + + /* Handle other kind of commands */ + cmd=lpc_find_command(cl); + if ( !cmd ) + { + printf("'%s': Cannot understand this.\n", cl); + return 1; + } + + if ( ! cmd->func(lc, args) ) + { + printf("Syntax error.\n"); + linphonec_display_command_help(cmd); + } + + return 1; +} + +/* + * Generator function for command completion. + * STATE let us know whether to start from scratch; + * without any state (STATE==0), then we start at the + * top of the list. + */ +char * +linphonec_command_generator(const char *text, int state) +{ + static int index, len; + char *name; + + if ( ! state ) + { + index=0; + len=strlen(text); + } + + /* + * Return the next name which partially matches + * from the commands list + */ + while ((name=commands[index].name)) + { + ++index; /* so next call get next command */ + + if (strncmp(name, text, len) == 0) + { + return strdup(name); + } + } + + return NULL; +} + + +/*************************************************************************** + * + * Command handlers + * + ***************************************************************************/ + +static int +lpc_cmd_help(LinphoneCore *lc, char *arg) +{ + int i=0; + LPC_COMMAND *cmd; + + if (!arg || !*arg) + { + printf("Commands are:\n"); + printf("---------------------------\n"); + + while (commands[i].help) + { + printf("%10.10s\t%s\n", commands[i].name, + commands[i].help); + i++; + } + + printf("---------------------------\n"); + printf("Type 'help ' for more details.\n"); + + return 1; + } + + cmd=lpc_find_command(arg); + if ( !cmd ) + { + printf("No such command.\n"); + return 1; + } + + linphonec_display_command_help(cmd); + return 1; + +} + +static int +lpc_cmd_call(LinphoneCore *lc, char *args) +{ + if ( ! args || ! *args ) + { + return 0; + } + + if ( lc->call != NULL ) + { + printf("Terminate current call first.\n"); + } + else + { + if ( -1 == linphone_core_invite(lc, args) ) + { + printf("Error from linphone_core_invite.\n"); + } + else + { + /* current_call=args; */ + } + } + return 1; +} + +static int +lpc_cmd_refer(LinphoneCore *lc, char *args) +{ + if (args) + linphone_core_refer(lc, args); + else{ + printf("refer needs an argument\n"); + } + return 1; +} + +static int +lpc_cmd_terminate(LinphoneCore *lc, char *args) +{ + if ( -1 == linphone_core_terminate_call(lc, NULL) ) + { + printf("No active call.\n"); + } + return 1; +} + +static int +lpc_cmd_answer(LinphoneCore *lc, char *args) +{ + if ( -1 == linphone_core_accept_call(lc, NULL) ) + { + printf("No incoming call.\n"); + } + return 1; +} + +static int +lpc_cmd_quit(LinphoneCore *lc, char *args) +{ + linphonec_finish(EXIT_SUCCESS); + return 1; +} + +static int +lpc_cmd_nat(LinphoneCore *lc, char *args) +{ + bool_t use; + const char *nat; + + if ( args ) args=lpc_strip_blanks(args); + + if ( args && *args ) + { + linphone_core_set_nat_address(lc, args); + /* linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_NAT_ADDRESS); */ + } + + nat = linphone_core_get_nat_address(lc); + use = linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_NAT_ADDRESS; + printf("Nat address: %s%s\n", nat ? nat : "unspecified" , use ? "" : " (disabled - use 'firewall nat' to enable)"); + + return 1; +} + +static int +lpc_cmd_stun(LinphoneCore *lc, char *args) +{ + bool_t use; + const char *stun; + + if ( args ) args=lpc_strip_blanks(args); + + if ( args && *args ) + { + linphone_core_set_stun_server(lc, args); + /* linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_STUN); */ + } + + stun = linphone_core_get_stun_server(lc); + use = linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_STUN; + printf("Stun server: %s%s\n", stun ? stun : "unspecified" , use? "" : " (disabled - use 'firewall stun' to enable)"); + + return 1; +} + +static int +lpc_cmd_firewall(LinphoneCore *lc, char *args) +{ + const char* setting=NULL; + + if ( args ) args=lpc_strip_blanks(args); + + if ( args && *args ) + { + if (strcmp(args,"none")==0) + { + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_NO_FIREWALL); + } + else if (strcmp(args,"stun")==0) + { + setting = linphone_core_get_stun_server(lc); + if ( ! setting ) + { + printf("No stun server address is defined, use 'stun
' first"); + return 1; + } + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_STUN); + } + else if (strcmp(args,"nat")==0) + { + setting = linphone_core_get_nat_address(lc); + if ( ! setting ) + { + printf("No nat address is defined, use 'nat
' first"); + return 1; + } + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_USE_NAT_ADDRESS); + } + } + + switch(linphone_core_get_firewall_policy(lc)) + { + case LINPHONE_POLICY_NO_FIREWALL: + printf("No firewall\n"); + break; + case LINPHONE_POLICY_USE_STUN: + printf("Using stun server %s to discover firewall address\n", setting ? setting : linphone_core_get_stun_server(lc)); + break; + case LINPHONE_POLICY_USE_NAT_ADDRESS: + printf("Using supplied nat address %s.\n", setting ? setting : linphone_core_get_nat_address(lc)); + break; + } + return 1; +} + +/* Helper function for processing freind names */ +static int +lpc_friend_name(char **args, char **name) +{ + /* Use space as a terminator unless quoted */ + if (('"' == **args) || ('\'' == **args)){ + char *end; + char delim = **args; + (*args)++; + end = (*args); + while ((delim != *end) && ('\0' != *end)) end++; + if ('\0' == *end) { + fprintf(stderr, "Mismatched quotes\n"); + return 0; + } + *name = *args; + *end = '\0'; + *args = ++end; + } else { + *name = strsep(args, " "); + + if (NULL == *args) { /* Means there was no separator */ + fprintf(stderr, "Either name or address is missing\n"); + return 0; + } + if (NULL == *name) return 0; + } + return 1; +} + +static int +lpc_cmd_friend(LinphoneCore *lc, char *args) +{ + int friend_num; + + if ( args ) args=lpc_strip_blanks(args); + + if ( ! args || ! *args ) return 0; + + if ( !strncmp(args, "list", 4) ) + { + return linphonec_friend_list(lc, args+4); + return 1; + } + else if ( !strncmp(args, "call", 4) ) + { + args+=4; + if ( ! *args ) return 0; + friend_num = strtol(args, NULL, 10); + if ( errno == ERANGE ) { + printf("Invalid friend number\n"); + return 0; + } + linphonec_friend_call(lc, friend_num); + return 1; + } + else if ( !strncmp(args, "delete", 6) ) + { + args+=6; + if ( ! *args ) return 0; + while (*args == ' ') args++; + if ( ! *args ) return 0; + if (!strncmp(args, "all", 3)) + { + friend_num = -1; + } + else + { + friend_num = strtol(args, NULL, 10); + if ( errno == ERANGE ) { + printf("Invalid friend number\n"); + return 0; + } + } + linphonec_friend_delete(lc, friend_num); + return 1; + } + else if ( !strncmp(args, "add", 3) ) + { + char *name; + char addr[80]; + char *addr_p = addr; + char *addr_orig; + + args+=3; + if ( ! *args ) return 0; + while (*args == ' ') args++; + if ( ! *args ) return 0; + if (!lpc_friend_name(&args, &name)) return 0; + + while (*args == ' ') args++; + if ( ! *args ) return 0; + if (isdigit(*args)) { + strcpy (addr, "sip:"); + addr_p = addr + strlen("sip:"); + } + addr_orig = strsep(&args, " "); + if (1 >= strlen(addr_orig)) { + fprintf(stderr, "A single-digit address is not valid\n"); + return 0; + } + strcpy(addr_p, addr_orig); + linphonec_friend_add(lc, name, addr); + return 1; + } + return 0; +} + +static int lpc_cmd_play(LinphoneCore *lc, char *args){ + if ( args ) args=lpc_strip_blanks(args); + if ( ! args || ! *args ) return 0; + linphone_core_set_play_file(lc,args); + return 1; +} + +static int lpc_cmd_record(LinphoneCore *lc, char *args){ + if ( args ) args=lpc_strip_blanks(args); + if ( ! args || ! *args ) return 0; + linphone_core_set_record_file(lc,args); + return 1; +} + +/* + * Modified input + */ +static int +lpc_cmd_proxy(LinphoneCore *lc, char *args) +{ + char *arg1 = args; + char *arg2 = NULL; + char *ptr = args; + int proxynum; + + if ( ! arg1 ) return 0; + + /* Isolate first and second arg */ + while(*ptr && !isspace(*ptr)) ++ptr; + if ( *ptr ) + { + *ptr='\0'; + arg2=ptr+1; + while(*arg2 && isspace(*arg2)) ++arg2; + } + + if (strcmp(arg1,"add")==0) + { + rl_inhibit_completion=1; + linphonec_proxy_add(lc); + rl_inhibit_completion=0; + } + else if (strcmp(arg1,"list")==0) + { + linphonec_proxy_list(lc); + } + else if (strcmp(arg1,"remove")==0) + { + linphonec_proxy_remove(lc,atoi(arg2)); + } + else if (strcmp(arg1,"use")==0) + { + if ( arg2 && *arg2 ) + { + proxynum=atoi(arg2); + if ( linphonec_proxy_use(lc, proxynum) ) + printf("Default proxy set to %d.\n", proxynum); + } + else + { + proxynum=linphone_core_get_default_proxy(lc, NULL); + if ( proxynum == -1 ) printf("No default proxy.\n"); + else printf("Current default proxy is %d.\n", proxynum); + } + } + else if (strcmp(arg1, "unuse")==0) + { + linphone_core_set_default_proxy(lc, NULL); + printf("Use no proxy.\n"); + } + else + { + printf("Syntax error - see 'help proxy'\n"); + } + + return 1; +} + +static int +lpc_cmd_call_logs(LinphoneCore *lc, char *args) +{ + MSList *elem=linphone_core_get_call_logs(lc); + for (;elem!=NULL;elem=ms_list_next(elem)) + { + LinphoneCallLog *cl=(LinphoneCallLog*)elem->data; + char *str=linphone_call_log_to_str(cl); + printf("%s\n",str); + ms_free(str); + } + return 1; +} + +static int +lpc_cmd_ipv6(LinphoneCore *lc, char *arg1) +{ + if ( ! arg1 ) + { + printf("Syntax error - see 'help ipv6'\n"); + return 1; + } + + if (strcmp(arg1,"status")==0) + { + printf("ipv6 use enabled: %s\n",linphone_core_ipv6_enabled(lc) ? "true":"false"); + } + else if (strcmp(arg1,"enable")==0) + { + linphone_core_enable_ipv6(lc,TRUE); + printf("ipv6 use enabled.\n"); + } + else if (strcmp(arg1,"disable")==0) + { + linphone_core_enable_ipv6(lc,FALSE); + printf("ipv6 use disabled.\n"); + } + else + { + printf("Syntax error - see 'help ipv6'\n"); + } + return 1; +} + +static int lpc_cmd_soundcard(LinphoneCore *lc, char *cmd){ + int i; + if (cmd==NULL){ + printf("Syntax error - see 'help soundcard'\n"); + return 1; + } + if (strcmp(cmd,"list")==0){ + const char **dev=linphone_core_get_sound_devices(lc); + for(i=0;dev[i]!=NULL;i++){ + printf("%i: %s\n",i,dev[i]); + } + return 1; + }else{ + char *tmp=alloca(strlen(cmd)+1); + char *card=alloca(strlen(cmd)+1); + int index; + int n=sscanf(cmd,"%s %s",tmp,card); + if (n==2 && strcmp(tmp,"use")==0){ + if (strcmp(card,"files")==0) { + printf("Using wav files instead of soundcard.\n"); + linphone_core_use_files(lc,TRUE); + return 1; + }else{ + const char **dev=linphone_core_get_sound_devices(lc); + index=atoi(card); + for(i=0;dev[i]!=NULL;i++){ + if (i==index){ + linphone_core_set_ringer_device(lc,dev[i]); + linphone_core_set_playback_device(lc,dev[i]); + linphone_core_set_capture_device(lc,dev[i]); + printf("Using sound device %s\n",dev[i]); + return 1; + } + } + printf("no such sound device\n"); + return 1; + } + } + printf("Syntax error - see 'help soundcard'\n"); + } + return 1; +} + +/*************************************************************************** + * + * Commands helper functions + * + ***************************************************************************/ + + +static void +linphonec_proxy_add(LinphoneCore *lc) +{ + bool_t enable_register=FALSE; + LinphoneProxyConfig *cfg; + + printf("Adding new proxy setup. Hit ^D to abort.\n"); + + /* + * SIP Proxy address + */ + while (1) + { + char *input=readline("Enter proxy sip address: "); + char *clean; + + if ( ! input ) { + printf("Aborted.\n"); + return; + } + + /* Strip blanks */ + clean=lpc_strip_blanks(input); + if ( ! *clean ) { + free(input); + continue; + } + + cfg=linphone_proxy_config_new(); + if (linphone_proxy_config_set_server_addr(cfg,clean)<0) + { + printf("Invalid sip address (sip:sip.domain.tld).\n"); + free(input); + linphone_proxy_config_destroy(cfg); + continue; + } + free(input); + break; + } + + /* + * SIP Proxy identity + */ + while (1) + { + char *input=readline("Your identity for this proxy: "); + char *clean; + + if ( ! input ) { + printf("Aborted.\n"); + linphone_proxy_config_destroy(cfg); + return; + } + + /* Strip blanks */ + clean=lpc_strip_blanks(input); + if ( ! *clean ) { + free(input); + continue; + } + + linphone_proxy_config_set_identity(cfg, clean); + if ( ! cfg->reg_identity ) + { + printf("Invalid identity (sip:name@sip.domain.tld).\n"); + free(input); + continue; + } + free(input); + break; + } + + /* + * SIP Proxy enable register + */ + while (1) + { + char *input=readline("Do you want to register on this proxy (yes/no): "); + char *clean; + + if ( ! input ) { + printf("Aborted.\n"); + linphone_proxy_config_destroy(cfg); + return; + } + + /* Strip blanks */ + clean=lpc_strip_blanks(input); + if ( ! *clean ) { + free(input); + continue; + } + + if ( ! strcmp(clean, "yes") ) enable_register=TRUE; + else if ( ! strcmp(clean, "no") ) enable_register=FALSE; + else { + printf("Please answer with 'yes' or 'no'\n"); + free(input); + continue; + } + linphone_proxy_config_enableregister(cfg, enable_register); + free(input); + break; + } + + /* + * SIP Proxy registration expiration + */ + if ( enable_register==TRUE ) + { + long int expires=0; + while (1) + { + char *input=readline("Specify register expiration time" + " in seconds (default is 600): "); + + if ( ! input ) { + printf("Aborted.\n"); + linphone_proxy_config_destroy(cfg); + return; + } + + expires=strtol(input, (char **)NULL, 10); + if ( expires == LONG_MIN || expires == LONG_MAX ) + { + printf("Invalid value: %s\n", strerror(errno)); + free(input); + continue; + } + + linphone_proxy_config_expires(cfg, expires); + printf("Expiration: %d seconds\n", cfg->expires); + + free(input); + break; + } + } + + /* + * SIP proxy route + */ + while (1) + { + char *input=readline("Specify route if needed: "); + char *clean; + + if ( ! input ) { + printf("Aborted.\n"); + linphone_proxy_config_destroy(cfg); + return; + } + + /* Strip blanks */ + clean=lpc_strip_blanks(input); + if ( ! *clean ) { + free(input); + printf("No route specified.\n"); + break; + } + + linphone_proxy_config_set_route(cfg, clean); + if ( ! cfg->reg_route ) + { + printf("Invalid route.\n"); + free(input); + continue; + } + + free(input); + break; + } + + /* + * Final confirmation + */ + while (1) + { + char *input; + char *clean; + + printf("--------------------------------------------\n"); + linphonec_proxy_display(cfg); + printf("--------------------------------------------\n"); + input=readline("Accept the above proxy configuration (yes/no) ?: "); + + + if ( ! input ) { + printf("Aborted.\n"); + linphone_proxy_config_destroy(cfg); + return; + } + + /* Strip blanks */ + clean=lpc_strip_blanks(input); + if ( ! *clean ) { + free(input); + continue; + } + + if ( ! strcmp(clean, "yes") ) break; + else if ( ! strcmp(clean, "no") ) + { + printf("Declined.\n"); + linphone_proxy_config_destroy(cfg); + free(input); + return; + } + + printf("Please answer with 'yes' or 'no'\n"); + free(input); + continue; + } + + + linphone_core_add_proxy_config(lc,cfg); + + /* automatically set the last entered proxy as the default one */ + linphone_core_set_default_proxy(lc,cfg); + + printf("Proxy added.\n"); +} + +static void +linphonec_proxy_display(LinphoneProxyConfig *cfg) +{ + printf("sip address: %s\nroute: %s\nidentity: %s\nregister: %s\nexpires: %i\n", + cfg->reg_proxy, + (cfg->reg_route!=NULL)?cfg->reg_route:"", + (cfg->reg_identity!=NULL)?cfg->reg_identity:"", + (cfg->reg_sendregister)?"yes":"no", + cfg->expires); +} + +static void +linphonec_proxy_list(LinphoneCore *lc) +{ + const MSList *proxies; + int n; + int def=linphone_core_get_default_proxy(lc,NULL); + + proxies=linphone_core_get_proxy_config_list(lc); + for(n=0;proxies!=NULL;proxies=ms_list_next(proxies),n++){ + if (n==def) + printf("****** Proxy %i - this is the default one - *******\n",n); + else + printf("****** Proxy %i *******\n",n); + linphonec_proxy_display((LinphoneProxyConfig*)proxies->data); + } +} + +static void +linphonec_proxy_remove(LinphoneCore *lc, int index) +{ + const MSList *proxies; + LinphoneProxyConfig *cfg; + proxies=linphone_core_get_proxy_config_list(lc); + cfg=(LinphoneProxyConfig*)ms_list_nth_data(proxies,index); + if (cfg==NULL){ + printf("No such proxy.\n"); + return; + } + linphone_core_remove_proxy_config(lc,cfg); + printf("Proxy %s removed.\n", cfg->reg_proxy); + linphone_proxy_config_destroy(cfg); +} + +static int +linphonec_proxy_use(LinphoneCore *lc, int index) +{ + const MSList *proxies; + LinphoneProxyConfig *cfg; + proxies=linphone_core_get_proxy_config_list(lc); + cfg=(LinphoneProxyConfig*)ms_list_nth_data(proxies,index); + if (cfg==NULL){ + printf("No such proxy (try 'proxy list')."); + return 0; + } + linphone_core_set_default_proxy(lc,cfg); + return 1; +} + +static void +linphonec_friend_display(LinphoneFriend *fr) +{ + char *name = linphone_friend_get_name(fr); + char *addr = linphone_friend_get_addr(fr); + //char *url = linphone_friend_get_url(fr); + + printf("name: %s\n", name); + printf("address: %s\n", addr); +} + +static int +linphonec_friend_list(LinphoneCore *lc, char *pat) +{ + const MSList *friend; + int n; + + if (pat) { + pat=lpc_strip_blanks(pat); + if (!*pat) pat = NULL; + } + + friend = linphone_core_get_friend_list(lc); + for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n ) + { + if ( pat ) { + char *name = linphone_friend_get_name(friend->data); + if ( ! strstr(name, pat) ) continue; + } + printf("****** Friend %i *******\n",n); + linphonec_friend_display((LinphoneFriend*)friend->data); + } + + return 1; +} + +static int +linphonec_friend_call(LinphoneCore *lc, unsigned int num) +{ + const MSList *friend = linphone_core_get_friend_list(lc); + unsigned int n; + char *addr; + + for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n ) + { + if ( n == num ) + { + addr = linphone_friend_get_addr(friend->data); + return lpc_cmd_call(lc, addr); + } + } + printf("No such friend %u\n", num); + return 1; +} + +static int +linphonec_friend_add(LinphoneCore *lc, const char *name, const char *addr) +{ + LinphoneFriend *newFriend; + + char url[PATH_MAX]; + + snprintf(url, PATH_MAX, "%s <%s>", name, addr); + newFriend = linphone_friend_new_with_addr(url); + linphone_core_add_friend(lc, newFriend); + return 0; +} + +static int +linphonec_friend_delete(LinphoneCore *lc, int num) +{ + const MSList *friend = linphone_core_get_friend_list(lc); + unsigned int n; + + for(n=0; friend!=NULL; friend=ms_list_next(friend), ++n ) + { + if ( n == num ) + { + linphone_core_remove_friend(lc, friend->data); + return 0; + } + } + + if (-1 == num) + { + unsigned int i; + for (i = 0 ; i < n ; i++) + linphonec_friend_delete(lc, 0); + return 0; + } + + printf("No such friend %u\n", num); + return 1; +} + +static void +linphonec_display_command_help(LPC_COMMAND *cmd) +{ + if ( cmd->doc ) printf ("%s\n", cmd->doc); + else printf("%s\n", cmd->help); +} + +/*************************************************************************** + * + * Command table management funx + * + ***************************************************************************/ + +/* + * Find a command given its name + */ +static LPC_COMMAND * +lpc_find_command(const char *name) +{ + int i; + + for (i=0; commands[i].name; ++i) + { + if (strcmp(name, commands[i].name) == 0) + return &commands[i]; + } + + return (LPC_COMMAND *)NULL; +} + + +/**************************************************************************** + * + * $Log: commands.c,v $ + * Revision 1.39 2008/07/03 15:08:34 smorlat + * api cleanups, interface in progress. + * + * Revision 1.38 2008/06/17 20:38:59 smorlat + * added missing file. + * + * Revision 1.37 2008/04/09 09:26:00 smorlat + * merge various patches + * H264 support. + * + * Revision 1.36 2007/08/01 14:47:53 strk + * * console/commands.c: Clean up commands 'nat', 'stun' + * and 'firewall' to be more intuitive. + * + * Revision 1.35 2007/06/27 09:01:25 smorlat + * logging improvements. + * + * Revision 1.34 2007/02/20 10:17:13 smorlat + * linphonec friends patch2 + * + * Revision 1.31 2006/09/22 07:22:47 smorlat + * linphonecore api changes. + * + * Revision 1.30 2006/09/08 15:32:57 smorlat + * support for using files instead of soundcard (used by linphonec only) + * + * Revision 1.29 2006/08/28 14:29:07 smorlat + * fix bug. + * + * Revision 1.28 2006/08/21 12:49:59 smorlat + * merged several little patches. + * + * Revision 1.27 2006/07/17 18:45:00 smorlat + * support for several event queues in ortp. + * glib dependency removed from coreapi/ and console/ + * + * Revision 1.26 2006/04/14 15:16:36 smorlat + * soundcard use did nothing ! + * + * Revision 1.25 2006/04/06 20:09:33 smorlat + * add linphonec command to see and select sound devices. + * + * Revision 1.24 2006/03/04 11:17:10 smorlat + * mediastreamer2 in progress. + * + * Revision 1.23 2006/02/20 21:14:01 strk + * Handled syntax errors with 'friend' command + * + * Revision 1.22 2006/02/20 10:20:29 strk + * Added substring-based filter support for command 'friend list' + * + * Revision 1.21 2006/02/02 15:39:18 strk + * - Added 'friend list' and 'friend call' commands + * - Allowed for multiple DTFM send in a single line + * - Added status-specific callback (bare version) + * + * Revision 1.20 2006/01/26 11:54:34 strk + * More robust 'nat' command handler (strip blanks in args) + * + * Revision 1.19 2006/01/26 09:48:05 strk + * Added limits.h include + * + * Revision 1.18 2006/01/26 02:18:05 strk + * Added new commands 'nat use' and 'nat unuse'. + * These will required a pending patch to linphonecore.c + * in order to work. + * + * Revision 1.17 2006/01/20 14:12:33 strk + * Added linphonec_init() and linphonec_finish() functions. + * Handled SIGINT and SIGTERM to invoke linphonec_finish(). + * Handling of auto-termination (-t) moved to linphonec_finish(). + * Reworked main (input read) loop to not rely on 'terminate' + * and 'run' variable (dropped). configfile_name allocated on stack + * using PATH_MAX limit. Changed print_usage signature to allow + * for an exit_status specification. + * + * Revision 1.16 2006/01/18 09:25:32 strk + * Command completion inhibited in proxy addition and auth request prompts. + * Avoided use of readline's internal filename completion. + * + * Revision 1.15 2006/01/14 13:29:32 strk + * Reworked commands interface to use a table structure, + * used by command line parser and help function. + * Implemented first level of completion (commands). + * Added notification of invalid "answer" and "terminate" + * commands (no incoming call, no active call). + * Forbidden "call" intialization when a call is already active. + * Cleaned up all commands, adding more feedback and error checks. + * + * Revision 1.14 2006/01/13 13:00:29 strk + * Added linphonec.h. Code layout change (added comments, forward decl, + * globals on top, copyright notices and Logs). Handled out-of-memory + * condition on history management. Removed assumption on sizeof(char). + * Fixed bug in authentication prompt (introduced by readline). + * Added support for multiple authentication requests (up to MAX_PENDING_AUTH). + * + * + ****************************************************************************/ diff --git a/linphone/console/example/linphonec b/linphone/console/example/linphonec new file mode 100644 index 000000000..a832f8546 --- /dev/null +++ b/linphone/console/example/linphonec @@ -0,0 +1,51 @@ +# this file is used to store user config values for linphonec +# please modify and copy it to ~/.linphonec +# +# + +logfile=~/linphonec.log +debuglevel=0 + +local_addr=192.168.1.10 +if_name=eth0 +# type of network connection 4 = ethernet +con_type=4 + + +# rtp +audio_rtp_port=7078 +jitt_comp=150 + + +# audio +driver_mode=0 +rec_lev=100 +play_lev=100 +source=109 +autokill=0 + + +# sip +sip_port=5060 +use_registrar=0 +username=1006 +hostname=192.168.1.1 +registrar=sip:192.168.1.1:5060 +reg_passwd= +addr_of_rec=sip:1006@192.168.1.1 +reg_expires=900 +as_proxy=1 +as_redirect=0 +as_outbound=1 + + +# codecs +audio_codecs=259 371 264 256 + + +# short dial +s0=sip:1002@130.83.176.121 +s1=sip:1001@192.168.1.1 +s2=sip:1002@192.168.1.1 +s3=sip:1003@192.168.1.1 +s4=sip:1004@192.168.1.1 diff --git a/linphone/console/linphonec.c b/linphone/console/linphonec.c new file mode 100644 index 000000000..bfe770437 --- /dev/null +++ b/linphone/console/linphonec.c @@ -0,0 +1,1114 @@ +/**************************************************************************** + * + * $Id: linphonec.c,v 1.57 2007/11/14 13:40:27 smorlat Exp $ + * + * Copyright (C) 2006 Sandro Santilli + * Copyright (C) 2002 Florian Winterstein + * Copyright (C) 2000 Simon MORLAT + * + **************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "linphonec.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_GETTEXT +#include +#ifndef _ +#define _(String) gettext(String) +#endif +#else +#define _(something) (something) +#endif + +/*************************************************************************** + * + * Types + * + ***************************************************************************/ + +typedef struct { + LinphoneAuthInfo *elem[MAX_PENDING_AUTH]; + int nitems; +} LPC_AUTH_STACK; + +/*************************************************************************** + * + * Forward declarations + * + ***************************************************************************/ + +char *lpc_strip_blanks(char *input); + +static int handle_configfile_migration(void); +static int copy_file(const char *from, const char *to); +static int linphonec_parse_cmdline(int argc, char **argv); +static int linphonec_initialize_readline(void); +static int linphonec_finish_readline(); +static int linphonec_init(int argc, char **argv); +static int linphonec_main_loop (LinphoneCore * opm, char * sipAddr); +static int linphonec_idle_call (void); +static char **linephonec_readline_completion(const char *text, + int start, int end); + +/* These are callback for linphone core */ +static void linphonec_call_received(LinphoneCore *lc, const char *from); +static void linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, + const char *username); +static void linphonec_display_something (LinphoneCore * lc, const char *something); +static void linphonec_display_url (LinphoneCore * lc, const char *something, const char *url); +static void linphonec_display_warning (LinphoneCore * lc, const char *something); +static void stub () {} +static void linphonec_notify_received(LinphoneCore *lc,LinphoneFriend *fid, + const char *from, const char *status, const char *img); +static void linphonec_new_unknown_subscriber(LinphoneCore *lc, + LinphoneFriend *lf, const char *url); +static void linphonec_bye_received(LinphoneCore *lc, const char *from); +static void linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, + const char *from, const char *msg); +static void linphonec_display_status (LinphoneCore * lc, const char *something); +static void linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate); +static void print_prompt(LinphoneCore *opm); + +/*************************************************************************** + * + * Global variables + * + ***************************************************************************/ + +LinphoneCore linphonec; +FILE *mylogfile; +static char *histfile_name=NULL; +static char last_in_history[256]; +//auto answer (-a) option +static bool_t auto_answer=FALSE; +static bool_t answer_call=FALSE; +static bool_t vcap_enabled=FALSE; +static bool_t display_enabled=FALSE; +static bool_t show_general_state=FALSE; +LPC_AUTH_STACK auth_stack; +static int trace_level = 0; +static char *logfile_name = NULL; +static char configfile_name[PATH_MAX]; +static char *sipAddr = NULL; /* for autocall */ +char prompt[PROMPT_MAX_LEN]; + +LinphoneCoreVTable linphonec_vtable = { + show:(ShowInterfaceCb) stub, + inv_recv: linphonec_call_received, + bye_recv: linphonec_bye_received, + notify_recv: linphonec_notify_received, + new_unknown_subscriber: linphonec_new_unknown_subscriber, + auth_info_requested: linphonec_prompt_for_auth, + display_status:linphonec_display_status, + display_message:linphonec_display_something, +#ifdef VINCENT_MAURY_RSVP + /* the yes/no dialog box */ + display_yes_no: (DisplayMessageCb) stub, +#endif + display_warning:linphonec_display_warning, + display_url:linphonec_display_url, + display_question:(DisplayQuestionCb)stub, + text_received:linphonec_text_received, + general_state:linphonec_general_state +}; + +/*************************************************************************** + * + * Linphone core callbacks + * + ***************************************************************************/ + +/* + * Linphone core callback + */ +static void +linphonec_display_something (LinphoneCore * lc, const char *something) +{ + fprintf (stdout, "%s\n%s", something,prompt); + fflush(stdout); +} + +/* + * Linphone core callback + */ +static void +linphonec_display_status (LinphoneCore * lc, const char *something) +{ + fprintf (stdout, "%s\n%s", something,prompt); + fflush(stdout); +} + +/* + * Linphone core callback + */ +static void +linphonec_display_warning (LinphoneCore * lc, const char *something) +{ + fprintf (stdout, "Warning: %s\n%s", something,prompt); + fflush(stdout); +} + +/* + * Linphone core callback + */ +static void +linphonec_display_url (LinphoneCore * lc, const char *something, const char *url) +{ + fprintf (stdout, "%s : %s\n", something, url); +} + + +/* + * Linphone core callback + */ +static void +linphonec_call_received(LinphoneCore *lc, const char *from) +{ + if ( auto_answer) { + answer_call=TRUE; + } +} + +/* + * Linphone core callback + */ +static void +linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, const char *username) +{ + LinphoneAuthInfo *pending_auth; + + if ( auth_stack.nitems+1 > MAX_PENDING_AUTH ) + { + fprintf(stderr, + "Can't accept another authentication request.\n" + "Consider incrementing MAX_PENDING_AUTH macro.\n"); + return; + } + + pending_auth=linphone_auth_info_new(username,NULL,NULL,NULL,realm); + auth_stack.elem[auth_stack.nitems++]=pending_auth; + +} + +/* + * Linphone core callback + */ +static void +linphonec_notify_received(LinphoneCore *lc,LinphoneFriend *fid, + const char *from, const char *status, const char *img) +{ + printf("Friend %s is %s\n", from, status); + // todo: update Friend list state (unimplemented) +} + +/* + * Linphone core callback + */ +static void +linphonec_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, + const char *url) +{ + printf("Friend %s requested subscription " + "(accept/deny is not implemented yet)\n", url); + // This means that this person wishes to be notified + // of your presence information (online, busy, away...). + +} + +/* + * Linphone core callback + */ +static void +linphonec_bye_received(LinphoneCore *lc, const char *from) +{ + // Should change prompt back to original maybe + + // printing this is unneeded as we'd get a "Communication ended" + // message trough display_status callback anyway + //printf("Bye received from %s\n", from); +} + +/* + * Linphone core callback + */ +static void +linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, + const char *from, const char *msg) +{ + printf("%s: %s\n", from, msg); + // TODO: provide mechanism for answering.. ('say' command?) +} + + +static void +linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate) +{ + if (show_general_state) { + switch(gstate->new_state) { + case GSTATE_POWER_OFF: + printf("GSTATE_POWER_OFF"); + break; + case GSTATE_POWER_STARTUP: + printf("GSTATE_POWER_STARTUP"); + break; + case GSTATE_POWER_ON: + printf("GSTATE_POWER_ON"); + break; + case GSTATE_POWER_SHUTDOWN: + printf("GSTATE_POWER_SHUTDOWN"); + break; + case GSTATE_REG_NONE: + printf("GSTATE_REG_NONE"); + break; + case GSTATE_REG_OK: + printf("GSTATE_REG_OK"); + break; + case GSTATE_REG_FAILED: + printf("GSTATE_REG_FAILED"); + break; + case GSTATE_CALL_IDLE: + printf("GSTATE_CALL_IDLE"); + break; + case GSTATE_CALL_OUT_INVITE: + printf("GSTATE_CALL_OUT_INVITE"); + break; + case GSTATE_CALL_OUT_CONNECTED: + printf("GSTATE_CALL_OUT_CONNECTED"); + break; + case GSTATE_CALL_IN_INVITE: + printf("GSTATE_CALL_IN_INVITE"); + break; + case GSTATE_CALL_IN_CONNECTED: + printf("GSTATE_CALL_IN_CONNECTED"); + break; + case GSTATE_CALL_END: + printf("GSTATE_CALL_END"); + break; + case GSTATE_CALL_ERROR: + printf("GSTATE_CALL_ERROR"); + break; + default: + printf("GSTATE_UNKNOWN_%d",gstate->new_state); + } + if (gstate->message) printf(" %s", gstate->message); + printf("\n"); + } +} + + +/***************************************************************************/ +/* + * Main + * + * Use globals: + * + * - char *histfile_name + * - FILE *mylogfile + */ +int +main (int argc, char *argv[]) +{ + + if (! linphonec_init(argc, argv) ) exit(EXIT_FAILURE); + + linphonec_main_loop (&linphonec, sipAddr); + + linphonec_finish(EXIT_SUCCESS); + + exit(EXIT_SUCCESS); /* should never reach here */ +} + +/* + * Initialize linphonec + */ +static int +linphonec_init(int argc, char **argv) +{ + + //g_mem_set_vtable(&dbgtable); + + /* + * Set initial values for global variables + */ + mylogfile = NULL; + snprintf(configfile_name, PATH_MAX, "%s/.linphonerc", + getenv("HOME")); + + + /* Handle configuration filename changes */ + switch (handle_configfile_migration()) + { + case -1: /* error during file copies */ + fprintf(stderr, + "Error in configuration file migration\n"); + break; + + case 0: /* nothing done */ + case 1: /* migrated */ + default: + break; + } + +#ifdef ENABLE_NLS + if (NULL == bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR)) + perror ("bindtextdomain failed"); +#ifndef __ARM__ + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + textdomain (GETTEXT_PACKAGE); +#else + printf ("NLS disabled.\n"); +#endif + + linphonec_parse_cmdline(argc, argv); + + if (trace_level > 0) + { + if (logfile_name != NULL) + mylogfile = fopen (logfile_name, "w+"); + + if (mylogfile == NULL) + { + mylogfile = stdout; + fprintf (stderr, + "INFO: no logfile, logging to stdout\n"); + } + linphone_core_enable_logs(mylogfile); + } + else + { + linphone_core_disable_logs(); + } + /* + * Initialize auth stack + */ + auth_stack.nitems=0; + + /* + * Initialize linphone core + */ + linphone_core_init (&linphonec, &linphonec_vtable, configfile_name, + NULL); + linphone_core_enable_video(&linphonec,vcap_enabled,display_enabled); + if (!(vcap_enabled || display_enabled)) printf("Warning: video is disabled in linphonec.\n"); + /* + * Initialize readline + */ + linphonec_initialize_readline(); + + /* + * Initialize signal handlers + */ + signal(SIGTERM, linphonec_finish); + signal(SIGINT, linphonec_finish); + + return 1; +} + + +/* + * Close linphonec, cleanly terminating + * any pending call + */ +void +linphonec_finish(int exit_status) +{ + printf("Terminating...\n"); + + /* Terminate any pending call */ + linphonec_parse_command_line(&linphonec, "terminate"); + + linphonec_finish_readline(); + + linphone_core_uninit (&linphonec); + + if (mylogfile != NULL && mylogfile != stdout) + { + fclose (mylogfile); + } + + exit(exit_status); + +} + +/* + * This is called from idle_call() whenever + * pending_auth != NULL. + * + * It prompts user for a password. + * Hitting ^D (EOF) would make this function + * return 0 (Cancel). + * Any other input would try to set linphone core + * auth_password for the pending_auth, add the auth_info + * and return 1. + */ +int +linphonec_prompt_for_auth_final(LinphoneCore *lc) +{ + char *input, *iptr; + char auth_prompt[256]; + rl_hook_func_t *old_event_hook; + + LinphoneAuthInfo *pending_auth=auth_stack.elem[auth_stack.nitems-1]; + + snprintf(auth_prompt, 256, "Password for %s on %s: ", + pending_auth->username, pending_auth->realm); + + printf("\n"); + + /* + * Disable event hook to avoid entering an + * infinite loop. This would prevent idle_call + * from being called during authentication reads. + * Note that it might be undesiderable... + */ + old_event_hook=rl_event_hook; + rl_event_hook=NULL; + + while (1) + { + input=readline(auth_prompt); + + /* + * If EOF (^D) is sent you probably don't want + * to provide an auth password... should give up + * the operation, but there's no mechanism to + * send this info back to caller currently... + */ + if ( ! input ) + { + printf("Cancel requested, but not implemented.\n"); + continue; + } + + /* Strip blanks */ + iptr=lpc_strip_blanks(input); + + /* + * Only blanks, continue asking + */ + if ( ! *iptr ) + { + free(input); + continue; + } + + /* Something typed, let's try */ + break; + } + + /* + * No check is done here to ensure password is correct. + * I guess password will be asked again later. + */ + linphone_auth_info_set_passwd(pending_auth, input); + linphone_core_add_auth_info(lc, pending_auth); + --(auth_stack.nitems); + + /* + * Reset line_buffer, to avoid the password + * to be used again from outer readline + */ + rl_line_buffer[0]='\0'; + + rl_event_hook=old_event_hook; + + return 1; +} + +void +print_usage (int exit_status) +{ + fprintf (stdout, "\n\ +usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n\ + linphonec -v\n\ +\n\ + -c file specify path of configuration file.\n\ + -d level be verbose. 0 is no output. 6 is all output\n\ + -l logfile specify the log file for your SIP phone\n\ + -s sipaddress specify the sip call to do at startup\n\ + -a enable auto answering for incoming calls\n\ + -V enable video features globally (disabled by default)\n\ + -C enable video capture only (disabled by default)\n\ + -D enable video display only (disabled by default)\n\ + -S show general state messages (disabled by default)\n\ + -v or --version display version and exits.\n"); + + exit(exit_status); +} + + +/* + * + * Called every second from main read loop. + * + * Will use the following globals: + * + * - LinphoneCore linphonec + * - LPC_AUTH_STACK auth_stack; + * + */ +static int +linphonec_idle_call () +{ + LinphoneCore *opm=&linphonec; + + /* Uncomment the following to verify being called */ + /* printf(".\n"); */ + + linphone_core_iterate(opm); + if (answer_call){ + fprintf (stdout, "-------auto answering to call-------\n" ); + linphone_core_accept_call(opm,NULL); + answer_call=FALSE; + } + +#if 0 /* Automatic exit should be requested with a command line switch */ + /* Quit if autocall mode was on and no call is in progress */ + if ( sipAddr != NULL && opm->call == NULL ) + { + linphonec_parse_command_line(&linphonec, "quit"); + } +#endif + + if ( auth_stack.nitems ) + { + /* + * Inhibit command completion + * during password prompts + */ + rl_inhibit_completion=1; + linphonec_prompt_for_auth_final(opm); + rl_inhibit_completion=0; + } + + return 0; +} + +/* + * Use globals: + * + * - char *histfile_name (also sets this) + * - char *last_in_history (allocates it) + */ +static int +linphonec_initialize_readline() +{ + /*rl_bind_key('\t', rl_insert);*/ + + /* Allow conditional parsing of ~/.inputrc */ + rl_readline_name = "linphonec"; + + /* Call idle_call() every second */ + rl_set_keyboard_input_timeout(LPC_READLINE_TIMEOUT); + rl_event_hook=linphonec_idle_call; + + /* Set history file and read it */ + histfile_name = ms_strdup_printf ("%s/.linphonec_history", + getenv("HOME")); + read_history(histfile_name); + + /* Initialized last_in_history cache*/ + last_in_history[0] = '\0'; + + /* Register a completion function */ + rl_attempted_completion_function = linephonec_readline_completion; + + /* printf("Readline initialized.\n"); */ + setlinebuf(stdout); + return 0; +} + +/* + * Uses globals: + * + * - char *histfile_name (writes history to file and frees it) + * - char *last_in_history (frees it) + * + */ +static int +linphonec_finish_readline() +{ + + stifle_history(HISTSIZE); + write_history(histfile_name); + free(histfile_name); + histfile_name=NULL; + return 0; +} + +static void print_prompt(LinphoneCore *opm){ +#ifdef IDENTITY_AS_PROMPT + snprintf(prompt, PROMPT_MAX_LEN, "%s> ", + linphone_core_get_primary_contact(opm)); +#else + snprintf(prompt, PROMPT_MAX_LEN, "linphonec> "); +#endif +} + +static int +linphonec_main_loop (LinphoneCore * opm, char * sipAddr) +{ + char buf[LINE_MAX_LEN]; /* auto call handling */ + bool_t run=TRUE; + char *input; + + print_prompt(opm); + + + /* auto call handling */ + if (sipAddr != NULL ) + { + snprintf (buf, sizeof(buf),"call %s", sipAddr); + run=linphonec_parse_command_line(&linphonec, buf); + } + + while ((input=readline(prompt))) + { + char *iptr; /* input and input pointer */ + size_t input_len; + + /* Strip blanks */ + iptr=lpc_strip_blanks(input); + + input_len = strlen(iptr); + + /* + * Do nothing but release memory + * if only blanks are read + */ + if ( ! input_len ) + { + free(input); + continue; + } + + + /* + * Only add to history if not already + * last item in it + */ + if ( strcmp(last_in_history, iptr) ) + { + strncpy(last_in_history,iptr,sizeof(last_in_history)); + last_in_history[sizeof(last_in_history)-1]='\0'; + add_history(iptr); + } + + linphonec_parse_command_line(&linphonec, iptr); + free(input); + } + + return 0; +} + +/* + * Parse command line switches + * + * Use globals: + * + * - int trace_level + * - char *logfile_name + * - char *configfile_name + * - char *sipAddr + */ +static int +linphonec_parse_cmdline(int argc, char **argv) +{ + int arg_num=1; + + while (arg_num < argc) + { + int old_arg_num = arg_num; + if (strncmp ("-d", argv[arg_num], 2) == 0) + { + arg_num++; + if (arg_num < argc) + trace_level = atoi (argv[arg_num]); + else + trace_level = 1; + } + else if (strncmp ("-l", argv[arg_num], 2) == 0) + { + arg_num++; + if (arg_num < argc) + logfile_name = argv[arg_num]; + } + else if (strncmp ("-c", argv[arg_num], 2) == 0) + { + if ( ++arg_num >= argc ) print_usage(EXIT_FAILURE); + + if (access(argv[arg_num],F_OK)!=0 ) + { + fprintf (stderr, + "Cannot open config file %s.\n", + argv[arg_num]); + exit(EXIT_FAILURE); + } + snprintf(configfile_name, PATH_MAX, argv[arg_num]); + } + else if (strncmp ("-s", argv[arg_num], 2) == 0) + { + arg_num++; + if (arg_num < argc) + sipAddr = argv[arg_num]; + } + else if (strncmp ("-a", argv[arg_num], 2) == 0) + { + auto_answer = TRUE; + } + else if (strncmp ("-C", argv[arg_num], 2) == 0) + { + vcap_enabled = TRUE; + } + else if (strncmp ("-D", argv[arg_num], 2) == 0) + { + display_enabled = TRUE; + } + else if (strncmp ("-V", argv[arg_num], 2) == 0) + { + display_enabled = TRUE; + vcap_enabled = TRUE; + } + else if ((strncmp ("-v", argv[arg_num], 2) == 0) + || + (strncmp + ("--version", argv[arg_num], + strlen ("--version")) == 0)) + { + printf ("version: " LINPHONE_VERSION "\n"); + exit (EXIT_SUCCESS); + } + else if (strncmp ("-S", argv[arg_num], 2) == 0) + { + show_general_state = TRUE; + } + else if (old_arg_num == arg_num) + { + fprintf (stderr, "ERROR: bad arguments\n"); + print_usage (EXIT_FAILURE); + } + arg_num++; + } + + return 1; +} + +/* + * Up to version 1.2.1 linphone used ~/.linphonec for + * CLI and ~/.gnome2/linphone for GUI as configuration file. + * In newer version both interfaces will use ~/.linphonerc. + * + * This function helps transparently migrating from one + * to the other layout using the following heuristic: + * + * IF new_config EXISTS => do nothing + * ELSE IF old_cli_config EXISTS => copy to new_config + * ELSE IF old_gui_config EXISTS => copy to new_config + * + * Returns: + * 0 if it did nothing + * 1 if it migrated successfully + * -1 on error + */ +static int +handle_configfile_migration() +{ + char *old_cfg_gui; + char *old_cfg_cli; + char *new_cfg; + const char *home = getenv("HOME"); + + new_cfg = ms_strdup_printf("%s/.linphonerc", home); + + /* + * If the *NEW* configuration already exists + * do nothing. + */ + if (access(new_cfg,F_OK)==0) + { + free(new_cfg); + return 0; + } + + old_cfg_cli = ms_strdup_printf("%s/.linphonec", home); + + /* + * If the *OLD* CLI configurations exist copy it to + * the new file and make it a symlink. + */ + if (access(old_cfg_cli, F_OK)==0) + { + if ( ! copy_file(old_cfg_cli, new_cfg) ) + { + free(old_cfg_cli); + free(new_cfg); + return -1; + } + printf("%s copied to %s\n", old_cfg_cli, new_cfg); + free(old_cfg_cli); + free(new_cfg); + return 1; + } + + free(old_cfg_cli); + old_cfg_gui = ms_strdup_printf("%s/.gnome2/linphone", home); + + /* + * If the *OLD* GUI configurations exist copy it to + * the new file and make it a symlink. + */ + if (access(old_cfg_gui, F_OK)==0) + { + if ( ! copy_file(old_cfg_gui, new_cfg) ) + { + exit(EXIT_FAILURE); + free(old_cfg_gui); + free(new_cfg); + return -1; + } + printf("%s copied to %s\n", old_cfg_gui, new_cfg); + free(old_cfg_gui); + free(new_cfg); + return 1; + } + + free(old_cfg_gui); + free(new_cfg); + return 0; +} + +/* + * Copy file "from" to file "to". + * Destination file is truncated if existing. + * Return 1 on success, 0 on error (printing an error). + */ +static int +copy_file(const char *from, const char *to) +{ + char message[256]; + FILE *in, *out; + char buf[256]; + size_t n; + + /* Open "from" file for reading */ + in=fopen(from, "r"); + if ( in == NULL ) + { + snprintf(message, 255, "Can't open %s for reading: %s\n", + from, strerror(errno)); + fprintf(stderr, message); + return 0; + } + + /* Open "to" file for writing (will truncate existing files) */ + out=fopen(to, "w"); + if ( out == NULL ) + { + snprintf(message, 255, "Can't open %s for writing: %s\n", + to, strerror(errno)); + fprintf(stderr, message); + return 0; + } + + /* Copy data from "in" to "out" */ + while ( (n=fread(buf, 1, sizeof buf, in)) > 0 ) + { + if ( ! fwrite(buf, 1, n, out) ) + { + return 0; + } + } + + fclose(in); + fclose(out); + + return 1; +} + +static char ** +linephonec_readline_completion(const char *text, int start, int end) +{ + char **matches = NULL; + + /* + * Prevent readline from falling + * back to filename-completion + */ + rl_attempted_completion_over=1; + + /* + * If this is the start of line we complete with commands + */ + if ( ! start ) + { + return rl_completion_matches(text, linphonec_command_generator); + } + + /* + * Otherwise, we should peek at command name + * or context to implement a smart completion. + * For example: "call .." could return + * friends' sip-uri as matches + */ + + return matches; +} + +/* + * Strip blanks from a string. + * Return a pointer into the provided string. + * Modifies input adding a NULL at first + * of trailing blanks. + */ +char * +lpc_strip_blanks(char *input) +{ + char *iptr; + + /* Find first non-blank */ + while(*input && isspace(*input)) ++input; + + /* Find last non-blank */ + iptr=input+strlen(input); + if (iptr > input) { + while(isspace(*--iptr)); + *(iptr+1)='\0'; + } + + return input; +} + +/**************************************************************************** + * + * $Log: linphonec.c,v $ + * Revision 1.57 2007/11/14 13:40:27 smorlat + * fix --disable-video build. + * + * Revision 1.56 2007/09/26 14:07:27 fixkowalski + * - ANSI/C++ compilation issues with non-GCC compilers + * - Faster epm-based packaging + * - Ability to build & run on FC6's eXosip/osip + * + * Revision 1.55 2007/09/24 16:01:58 smorlat + * fix bugs. + * + * Revision 1.54 2007/08/22 14:06:11 smorlat + * authentication bugs fixed. + * + * Revision 1.53 2007/02/13 21:31:01 smorlat + * added patch for general state. + * new doxygen for oRTP + * gtk-doc removed. + * + * Revision 1.52 2007/01/10 14:11:24 smorlat + * add --video to linphonec. + * + * Revision 1.51 2006/08/21 12:49:59 smorlat + * merged several little patches. + * + * Revision 1.50 2006/07/26 08:17:28 smorlat + * fix bugs. + * + * Revision 1.49 2006/07/17 18:45:00 smorlat + * support for several event queues in ortp. + * glib dependency removed from coreapi/ and console/ + * + * Revision 1.48 2006/04/09 12:45:32 smorlat + * linphonec improvements. + * + * Revision 1.47 2006/04/04 08:04:34 smorlat + * switched to mediastreamer2, most bugs fixed. + * + * Revision 1.46 2006/03/16 17:17:40 smorlat + * fix various bugs. + * + * Revision 1.45 2006/03/12 21:48:31 smorlat + * gcc-2.95 compile error fixed. + * mediastreamer2 in progress + * + * Revision 1.44 2006/03/04 11:17:10 smorlat + * mediastreamer2 in progress. + * + * Revision 1.43 2006/02/13 09:50:50 strk + * fixed unused variable warning. + * + * Revision 1.42 2006/02/02 15:39:18 strk + * - Added 'friend list' and 'friend call' commands + * - Allowed for multiple DTFM send in a single line + * - Added status-specific callback (bare version) + * + * Revision 1.41 2006/02/02 13:30:05 strk + * - Padded vtable with missing callbacks + * (fixing a segfault on friends subscription) + * - Handled friends notify (bare version) + * - Handled text messages receive (bare version) + * - Printed message on subscription request (bare version) + * + * Revision 1.40 2006/01/26 09:48:05 strk + * Added limits.h include + * + * Revision 1.39 2006/01/26 02:11:01 strk + * Removed unused variables, fixed copyright date + * + * Revision 1.38 2006/01/25 18:33:02 strk + * Removed the -t swich, terminate_on_close made the default behaviour + * + * Revision 1.37 2006/01/20 14:12:34 strk + * Added linphonec_init() and linphonec_finish() functions. + * Handled SIGINT and SIGTERM to invoke linphonec_finish(). + * Handling of auto-termination (-t) moved to linphonec_finish(). + * Reworked main (input read) loop to not rely on 'terminate' + * and 'run' variable (dropped). configfile_name allocated on stack + * using PATH_MAX limit. Changed print_usage signature to allow + * for an exit_status specification. + * + * Revision 1.36 2006/01/18 09:25:32 strk + * Command completion inhibited in proxy addition and auth request prompts. + * Avoided use of readline's internal filename completion. + * + * Revision 1.35 2006/01/14 13:29:32 strk + * Reworked commands interface to use a table structure, + * used by command line parser and help function. + * Implemented first level of completion (commands). + * Added notification of invalid "answer" and "terminate" + * commands (no incoming call, no active call). + * Forbidden "call" intialization when a call is already active. + * Cleaned up all commands, adding more feedback and error checks. + * + * Revision 1.34 2006/01/13 13:00:29 strk + * Added linphonec.h. Code layout change (added comments, forward decl, + * globals on top, copyright notices and Logs). Handled out-of-memory + * condition on history management. Removed assumption on sizeof(char). + * Fixed bug in authentication prompt (introduced by readline). + * Added support for multiple authentication requests (up to MAX_PENDING_AUTH). + * + * + ****************************************************************************/ diff --git a/linphone/console/linphonec.h b/linphone/console/linphonec.h new file mode 100644 index 000000000..368d63e0f --- /dev/null +++ b/linphone/console/linphonec.h @@ -0,0 +1,134 @@ +/**************************************************************************** + * + * $Id: linphonec.h,v 1.3 2006/01/20 14:12:34 strk Exp $ + * + * Copyright (C) 2005 Sandro Santilli + * + **************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + ****************************************************************************/ + +#ifndef LINPHONEC_H +#define LINPHONEC_H 1 + +#ifdef HAVE_READLINE_H +#include +#else +#ifdef HAVE_READLINE_READLINE_H +#include +#endif +#endif +#ifdef HAVE_HISTORY_H +#include +#else +#ifdef HAVE_READLINE_HISTORY_H +#include +#endif +#endif + +/************************************************************************** + * + * Compile-time defines + * + **************************************************************************/ + +#define HISTSIZE 500 /* how many lines of input history */ +#define PROMPT_MAX_LEN 256 /* max len of prompt string */ +#define LINE_MAX_LEN 256 /* really needed ? */ + +/* + * Define this to have your primary contact + * as the prompt string + */ +/* #define IDENTITY_AS_PROMPT 1 */ + +/* + * Time between calls to linphonec_idle_call during main + * input read loop in microseconds. + */ +#define LPC_READLINE_TIMEOUT 1000000 + +/* + * Filename of linphonec history + */ +#define LPC_HIST_FILE "~/.linphonec_history" + +/* + * Maximum number of pending authentications + */ +#define MAX_PENDING_AUTH 8 + +/************************************************************************** + * + * Types + * + **************************************************************************/ + +/* + * A structure which contains information on the commands this program + * can understand. + */ +typedef int (*lpc_cmd_handler)(LinphoneCore *, char *); +typedef struct { + char *name; /* User printable name of the function. */ + lpc_cmd_handler func; /* Function to call to do the job. */ + char *help; /* Short help for this function. */ + char *doc; /* Long description. */ +} LPC_COMMAND; + +/*************************************************************************** + * + * Forward declarations + * + ***************************************************************************/ + +extern int linphonec_parse_command_line(LinphoneCore *lc, char *cl); +extern char *linphonec_command_generator(const char *text, int state); +extern void linphonec_finish(int exit_status); + +#endif /* def LINPHONEC_H */ + +/**************************************************************************** + * + * $Log: linphonec.h,v $ + * Revision 1.3 2006/01/20 14:12:34 strk + * Added linphonec_init() and linphonec_finish() functions. + * Handled SIGINT and SIGTERM to invoke linphonec_finish(). + * Handling of auto-termination (-t) moved to linphonec_finish(). + * Reworked main (input read) loop to not rely on 'terminate' + * and 'run' variable (dropped). configfile_name allocated on stack + * using PATH_MAX limit. Changed print_usage signature to allow + * for an exit_status specification. + * + * Revision 1.2 2006/01/14 13:29:32 strk + * Reworked commands interface to use a table structure, + * used by command line parser and help function. + * Implemented first level of completion (commands). + * Added notification of invalid "answer" and "terminate" + * commands (no incoming call, no active call). + * Forbidden "call" intialization when a call is already active. + * Cleaned up all commands, adding more feedback and error checks. + * + * Revision 1.1 2006/01/13 13:00:29 strk + * Added linphonec.h. Code layout change (added comments, forward decl, + * globals on top, copyright notices and Logs). Handled out-of-memory + * condition on history management. Removed assumption on sizeof(char). + * Fixed bug in authentication prompt (introduced by readline). + * Added support for multiple authentication requests (up to MAX_PENDING_AUTH). + * + * + ****************************************************************************/ diff --git a/linphone/console/sipomatic.c b/linphone/console/sipomatic.c new file mode 100644 index 000000000..08b167b1c --- /dev/null +++ b/linphone/console/sipomatic.c @@ -0,0 +1,467 @@ +/*************************************************************************** + linphone - sipomatic.c +This is a test program for linphone. It acts as a sip server and answers to linphone's +call. + ------------------- + begin : ven mar 30 + copyright : (C) 2001 by Simon MORLAT + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include "sipomatic.h" +#include + + +int run_cond=1; + +Sipomatic sipomatic; + +int sipomatic_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload); +int sipomatic_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload); + + +sdp_handler_t sipomatic_sdp_handler={ + sipomatic_accept_audio_offer, /*from remote sdp */ + sipomatic_accept_video_offer, + NULL, + NULL, + NULL, + NULL, +}; + +void stop_handler(int signum) +{ + run_cond=0; +} + +void sipomatic_process_event(Sipomatic *obj,eXosip_event_t *ev) +{ + Call *call; + switch(ev->type){ + case EXOSIP_CALL_INVITE: + call_new(obj,ev); + break; + case EXOSIP_CALL_CLOSED: + case EXOSIP_CALL_CANCELLED: + call=sipomatic_find_call(obj,ev->did); + if (call==NULL){ + ms_warning("Could not find call with did %i !",ev->did); + } + call_release(call); + call_destroy(call); + break; + default: + break; + } + eXosip_event_free(ev); +} + + +void endoffile_cb(void *ud, unsigned int ev,void * arg){ + Call*call=(Call*)ud; + call->eof=1; +} + +void call_accept(Call *call) +{ + sdp_context_t *ctx; + PayloadType *payload; + char *hellofile; + static int call_count=0; + char record_file[250]; + osip_message_t *msg=NULL; + sprintf(record_file,"/tmp/sipomatic%i.wav",call_count); + + ctx=call->sdpc; + payload=rtp_profile_get_payload(call->profile,call->audio.pt); + if (strcmp(payload->mime_type,"telephone-event")==0){ + /* telephone-event is not enough to accept a call */ + ms_message("Cannot accept call with only telephone-event.\n"); + eXosip_call_send_answer(call->did,415,NULL); + call->state=CALL_STATE_FINISHED; + return; + } + if (payload->clock_rate==16000){ + hellofile=call->root->file_path16000hz; + }else hellofile=call->root->file_path8000hz; + eXosip_call_build_answer(call->tid,200,&msg); + osip_message_set_content_type(msg,"application/sdp"); + osip_message_set_body(msg,call->sdpc->answerstr,strlen(call->sdpc->answerstr)); + eXosip_call_send_answer(call->tid,200,msg); + call->audio_stream=audio_stream_new(call->audio.localport,call->root->ipv6); + audio_stream_start_with_files(call->audio_stream, call->profile, + call->audio.remaddr,call->audio.remoteport,call->audio.remoteport+1, + call->audio.pt,20,hellofile,record_file); + call_count++; +#ifdef VIDEO_ENABLED + if (call->video.remoteport!=0){ + video_stream_send_only_start(call->video_stream,call->profile, + call->video.remaddr,call->video.remoteport,call->video.remoteport+1,call->video.pt, 60, + ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get())); + } +#endif + call->time=time(NULL); + call->state=CALL_STATE_RUNNING; + ms_filter_set_notify_callback(call->audio_stream->soundread,endoffile_cb,(void*)call); +} + + +PayloadType * sipomatic_payload_is_supported(sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile) +{ + int localpt; + if (payload->a_rtpmap!=NULL){ + localpt=rtp_profile_get_payload_number_from_rtpmap(local_profile,payload->a_rtpmap); + }else{ + localpt=payload->pt; + ms_warning("payload has no rtpmap."); + } + + if (localpt>=0){ + /* this payload is supported in our local rtp profile, so add it to the dialog rtp + profile */ + PayloadType *rtppayload; + rtppayload=rtp_profile_get_payload(local_profile,localpt); + if (rtppayload==NULL) return NULL; + /*check if we have the appropriate coder/decoder for this payload */ + if (strcmp(rtppayload->mime_type,"telephone-event")!=0) { + if (!ms_filter_codec_supported(rtppayload->mime_type)) { + ms_message("Codec %s is not supported.", rtppayload->mime_type); + return NULL; + } + } + rtppayload=payload_type_clone(rtppayload); + rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload); + /* add to the rtp payload type some other parameters (bandwidth) */ + if (payload->b_as_bandwidth!=0) rtppayload->normal_bitrate=payload->b_as_bandwidth*1000; + if (payload->a_fmtp!=NULL) + payload_type_set_send_fmtp(rtppayload,payload->a_fmtp); + if (strcasecmp(rtppayload->mime_type,"iLBC")==0){ + /*default to 30 ms mode */ + payload->a_fmtp="ptime=30"; + payload_type_set_recv_fmtp(rtppayload,payload->a_fmtp); + } + return rtppayload; + } + return NULL; +} + +int sipomatic_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload) +{ + static int audioport=8000; + Call *call=(Call*)sdp_context_get_user_pointer(ctx); + PayloadType *supported; + struct stream_params *params=&call->audio; + + /* see if this codec is supported in our local rtp profile*/ + supported=sipomatic_payload_is_supported(payload,&av_profile,call->profile); + if (supported==NULL) { + ms_message("Refusing codec %i (%s)",payload->pt,payload->a_rtpmap); + return -1; + } + if (strcmp(supported->mime_type,"telephone-event")==0) return 0; + if (params->ncodecs==0 ){ + /* this is the first codec we may accept*/ + params->localport=payload->localport=audioport; + params->remoteport=payload->remoteport; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + params->remaddr=payload->c_addr; + params->ncodecs++; + audioport+=4; + }else{ + /* refuse all other audio lines*/ + if(params->line!=payload->line) return -1; + } + return 0; +} + +int sipomatic_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload) +{ +#ifdef VIDEO_ENABLED + static int videoport=80000; + Call *call=(Call*)sdp_context_get_user_pointer(ctx); + PayloadType *supported; + struct stream_params *params=&call->video; + + /* see if this codec is supported in our local rtp profile*/ + supported=sipomatic_payload_is_supported(payload,&av_profile,call->profile); + if (supported==NULL) { + ms_message("Refusing video codec %i (%s)",payload->pt,payload->a_rtpmap); + return -1; + } + if (params->ncodecs==0 ){ + /* this is the first codec we may accept*/ + params->localport=payload->localport=videoport; + params->remoteport=payload->remoteport; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + params->remaddr=payload->c_addr; + params->ncodecs++; + videoport+=4; + }else{ + /* refuse all other video lines*/ + if(params->line!=payload->line) return -1; + } + return 0; +#else + return -1; +#endif +} + +void sipomatic_init(Sipomatic *obj, char *url, bool_t ipv6) +{ + osip_uri_t *uri=NULL; + int port=5064; + + obj->ipv6=ipv6; + + if (url==NULL){ + url=getenv("SIPOMATIC_URL"); + if (url==NULL){ + if (ipv6) url="sip:robot@[::1]:5064"; + else url="sip:robot@127.0.0.1:5064"; + } + } + if (url!=NULL) { + osip_uri_init(&uri); + if (osip_uri_parse(uri,url)==0){ + if (uri->port!=NULL) port=atoi(uri->port); + }else{ + ms_warning("Invalid identity uri:%s",url); + } + } + ms_message("Starting using url %s",url); + ms_mutex_init(&obj->lock,NULL); + obj->calls=NULL; + obj->acceptance_time=5; + obj->max_call_time=300; + obj->file_path8000hz=ms_strdup_printf("%s/%s",PACKAGE_SOUND_DIR,ANNOUCE_FILE8000HZ); + obj->file_path16000hz=ms_strdup_printf("%s/%s",PACKAGE_SOUND_DIR,ANNOUCE_FILE16000HZ); + osip_trace_initialize(OSIP_INFO1,stdout); + osip_trace_initialize(OSIP_INFO2,stdout); + osip_trace_initialize(OSIP_WARNING,stdout); + osip_trace_initialize(OSIP_ERROR,stdout); + osip_trace_initialize(OSIP_BUG,stdout); + osip_trace_initialize(OSIP_FATAL,stdout); + osip_trace_enable_level(OSIP_INFO1); + osip_trace_enable_level(OSIP_INFO2); + osip_trace_enable_level(OSIP_WARNING); + osip_trace_enable_level(OSIP_ERROR); + osip_trace_enable_level(OSIP_BUG); + osip_trace_enable_level(OSIP_FATAL); + eXosip_init(); + eXosip_set_user_agent("sipomatic-" LINPHONE_VERSION "/eXosip"); + eXosip_listen_addr(IPPROTO_UDP,NULL,port,ipv6 ? AF_INET6 : AF_INET,0); +} + +void sipomatic_uninit(Sipomatic *obj) +{ + ms_mutex_destroy(&obj->lock); + eXosip_quit(); +} + +void sipomatic_iterate(Sipomatic *obj) +{ + MSList *elem; + MSList *to_be_destroyed=NULL; + Call *call; + double elapsed; + eXosip_event_t *ev; + + while((ev=eXosip_event_wait(0,0))!=NULL){ + sipomatic_process_event(obj,ev); + } + elem=obj->calls; + while(elem!=NULL){ + call=(Call*)elem->data; + elapsed=time(NULL)-call->time; + switch(call->state){ + case CALL_STATE_INIT: + if (elapsed>obj->acceptance_time){ + call_accept(call); + } + break; + case CALL_STATE_RUNNING: + if (elapsed>obj->max_call_time || call->eof){ + call_release(call); + to_be_destroyed=ms_list_append(to_be_destroyed,call); + } + break; + } + elem=ms_list_next(elem); + } + for(;to_be_destroyed!=NULL; to_be_destroyed=ms_list_next(to_be_destroyed)){ + call_destroy((Call*)to_be_destroyed->data); + } +} + + +Call* sipomatic_find_call(Sipomatic *obj,int did) +{ + MSList *it; + Call *call=NULL; + for (it=obj->calls;it!=NULL;it=ms_list_next(it)){ + call=(Call*)it->data; + if ( call->did==did) return call; + } + return call; +} + + +Call * call_new(Sipomatic *root, eXosip_event_t *ev) +{ + Call *obj; + char *sdpans; + int status; + sdp_message_t *sdp; + sdp_context_t *sdpc; + + sdp=eXosip_get_sdp_info(ev->request); + sdpc=sdp_handler_create_context(&sipomatic_sdp_handler,NULL,"sipomatic",NULL); + obj=ms_new0(Call,1); + obj->profile=rtp_profile_new("remote"); + eXosip_call_send_answer(ev->tid,100,NULL); + sdp_context_set_user_pointer(sdpc,obj); + sdpans=sdp_context_get_answer(sdpc,sdp); + if (sdpans!=NULL){ + eXosip_call_send_answer(ev->tid,180,NULL); + + }else{ + status=sdp_context_get_status(sdpc); + eXosip_call_send_answer(ev->tid,status,NULL); + sdp_context_free(sdpc); + rtp_profile_destroy(obj->profile); + ms_free(obj); + return NULL; + } + obj->sdpc=sdpc; + obj->did=ev->did; + obj->tid=ev->tid; + obj->time=time(NULL); + obj->audio_stream=NULL; + obj->state=CALL_STATE_INIT; + obj->eof=0; + obj->root=root; + root->calls=ms_list_append(root->calls,obj); + return obj; +} + +void call_release(Call *call) +{ + eXosip_call_terminate(0,call->did); + if (call->audio_stream!=NULL) audio_stream_stop(call->audio_stream); +#ifdef VIDEO_ENABLED + if (call->video_stream!=NULL) video_stream_send_only_stop(call->video_stream); +#endif + call->state=CALL_STATE_FINISHED; +} + +void call_destroy(Call *obj) +{ + obj->root->calls=ms_list_remove(obj->root->calls,obj); + rtp_profile_destroy(obj->profile); + sdp_context_free(obj->sdpc); + ms_free(obj); +} + +void sipomatic_set_annouce_file(Sipomatic *obj, char *file) +{ + if (obj->file_path8000hz!=NULL){ + ms_free(obj->file_path8000hz); + } + obj->file_path8000hz=ms_strdup(file); +} + + +void display_help() +{ + printf("sipomatic [-u sip-url] [-f annouce-file ] [-s port]\n" + "sipomatic -h or --help: display this help.\n" + "sipomatic -v or --version: display version information.\n" + " -u sip-url : specify the sip url sipomatic listens and answers.\n" + " -f annouce-file : set the annouce file (16 bit raw format,8000Hz)\n" + " -6 enable ipv6 network usage\n"); + exit(0); +} + +char *getarg(int argc, char*argv[], int i) +{ + if (i +#undef PACKAGE +#undef VERSION +#include "mediastreamer2/mediastream.h" + +#include +#include + + +#define ANNOUCE_FILE8000HZ "hello8000.wav" +#define ANNOUCE_FILE16000HZ "hello16000.wav" + +struct _Sipomatic +{ + ms_mutex_t lock; + MSList *calls; + double acceptance_time; + double max_call_time; + char *file_path8000hz; + char *file_path16000hz; + bool_t ipv6; +}; + +typedef struct _Sipomatic Sipomatic; + +void sipomatic_init(Sipomatic *obj, char *url, bool_t ipv6); +void sipomatic_uninit(Sipomatic *obj); +void sipomatic_iterate(Sipomatic *obj); +#define sipomatic_lock(obj) ms_mutex_lock(&(obj)->lock); +#define sipomatic_unlock(obj) ms_mutex_unlock(&(obj)->lock); + +void sipomatic_set_annouce_file(Sipomatic *obj, char *file); + +struct stream_params{ + int ncodecs; + int line; + int localport; + int remoteport; + int pt; + char *remaddr; +}; + +struct _Call +{ + Sipomatic *root; + sdp_context_t *sdpc; + int time; + int did; + int tid; + AudioStream *audio_stream; +#ifdef VIDEO_ENABLED + VideoStream *video_stream; +#endif + int state; + struct _CallParams *params; + int eof; + RtpProfile *profile; + struct stream_params audio; + struct stream_params video; +}; + +#define CALL_STATE_INIT 0 +#define CALL_STATE_RUNNING 1 +#define CALL_STATE_FINISHED 2 + +typedef struct _Call Call; + + +Call * call_new(Sipomatic *obj, eXosip_event_t *ev); +void call_accept(Call *call); +void call_release(Call *call); +void call_destroy(Call *call); + +Call* sipomatic_find_call(Sipomatic *obj,int cid); diff --git a/linphone/console/wav2raw.c b/linphone/console/wav2raw.c new file mode 100644 index 000000000..1dc218374 --- /dev/null +++ b/linphone/console/wav2raw.c @@ -0,0 +1,67 @@ + + +#include "../config.h" +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int ifd,ofd; + char *name,*p; + char buf[200]; + int len; + + if (argc<2) return -1; + name=malloc(strlen(argv[1])+10); + sprintf(name,"%s",argv[1]); + p=strstr(name,".raw"); + if (p!=NULL){ + sprintf(p,"%s",".wav\0"); + }else{ + sprintf(name,"%s%s",argv[1],".raw"); + } + + ifd=open(name,O_RDONLY); + if (ifd<0) { + perror("Could not open input file"); + return -1; + } + ofd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (ofd<0) { + perror("Could not open output file"); + return -1; + } + len=read(ifd,buf,20); + printf("len=%i\n",len); + /* erase the wav header */ + if (len>0){ + memset(buf,0,20); + write(ofd,buf,20); + }else{ + printf("Error while processing %s: %s\n",argv[1],strerror(errno)); + return -1; + }; + + while ( (len=read(ifd,buf,200))>0){ + #ifdef WORDS_BIGENDIAN + for (i=0;i +#include +#include "lpconfig.h" + +extern LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid); +extern void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm); +extern void linphone_core_retry_proxy_register(LinphoneCore *lc, const char *realm); + +LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid, + const char *passwd, const char *ha1,const char *realm) +{ + LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1); + if (username!=NULL && (strlen(username)>0) ) obj->username=ms_strdup(username); + if (userid!=NULL && (strlen(userid)>0)) obj->userid=ms_strdup(userid); + if (passwd!=NULL && (strlen(passwd)>0)) obj->passwd=ms_strdup(passwd); + if (ha1!=NULL && (strlen(ha1)>0)) obj->ha1=ms_strdup(ha1); + if (realm!=NULL && (strlen(realm)>0)) obj->realm=ms_strdup(realm); + obj->works=FALSE; + obj->first_time=TRUE; + return obj; +} + +void linphone_auth_info_set_passwd(LinphoneAuthInfo *info, const char *passwd){ + if (info->passwd!=NULL) { + ms_free(info->passwd); + info->passwd=NULL; + } + if (passwd!=NULL && (strlen(passwd)>0)) info->passwd=ms_strdup(passwd); +} + +void linphone_auth_info_destroy(LinphoneAuthInfo *obj){ + if (obj->username!=NULL) ms_free(obj->username); + if (obj->userid!=NULL) ms_free(obj->userid); + if (obj->passwd!=NULL) ms_free(obj->passwd); + if (obj->ha1!=NULL) ms_free(obj->ha1); + if (obj->realm!=NULL) ms_free(obj->realm); + ms_free(obj); +} + +void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, int pos) +{ + char key[50]; + sprintf(key,"auth_info_%i",pos); + lp_config_clean_section(config,key); + + if (obj==NULL){ + return; + } + if (obj->username!=NULL){ + lp_config_set_string(config,key,"username",obj->username); + } + if (obj->userid!=NULL){ + lp_config_set_string(config,key,"userid",obj->userid); + } + if (obj->passwd!=NULL){ + lp_config_set_string(config,key,"passwd",obj->passwd); + } + if (obj->ha1!=NULL){ + lp_config_set_string(config,key,"ha1",obj->ha1); + } + if (obj->realm!=NULL){ + lp_config_set_string(config,key,"realm",obj->realm); + } + lp_config_sync(config); +} + +LinphoneAuthInfo *linphone_auth_info_new_from_config_file(LpConfig * config, int pos) +{ + char key[50]; + const char *username,*userid,*passwd,*ha1,*realm; + + sprintf(key,"auth_info_%i",pos); + if (!lp_config_has_section(config,key)){ + return NULL; + } + + username=lp_config_get_string(config,key,"username",NULL); + userid=lp_config_get_string(config,key,"userid",NULL); + passwd=lp_config_get_string(config,key,"passwd",NULL); + ha1=lp_config_get_string(config,key,"ha1",NULL); + realm=lp_config_get_string(config,key,"realm",NULL); + return linphone_auth_info_new(username,userid,passwd,ha1,realm); +} + +static bool_t key_match(const char *tmp1, const char *tmp2){ + if (tmp1==NULL && tmp2==NULL) return TRUE; + if (tmp1!=NULL && tmp2!=NULL && strcmp(tmp1,tmp2)==0) return TRUE; + return FALSE; + +} + +static int auth_info_compare(const void *pinfo,const void *pref){ + LinphoneAuthInfo *info=(LinphoneAuthInfo*)pinfo; + LinphoneAuthInfo *ref=(LinphoneAuthInfo*)pref; + if (key_match(info->realm,ref->realm) && key_match(info->username,ref->username)) return 0; + return -1; +} + +LinphoneAuthInfo *linphone_core_auth_info_find(LinphoneCore *lc, const char *realm, const char *username) +{ + LinphoneAuthInfo ref; + MSList *elem; + ref.realm=(char*)realm; + ref.username=(char*)username; + elem=ms_list_find_custom(lc->auth_info,auth_info_compare,(void*)&ref); + if (elem==NULL) return NULL; + return (LinphoneAuthInfo*)elem->data; +} + +void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info) +{ + int n; + MSList *elem; + char *userid; + if (info->userid==NULL || info->userid[0]=='\0') userid=info->username; + else userid=info->userid; + eXosip_lock(); + eXosip_add_authentication_info(info->username,userid, + info->passwd,info->ha1,info->realm); + eXosip_unlock(); + /* if the user was prompted, re-allow automatic_action */ + if (lc->automatic_action>0) lc->automatic_action--; + /* find if we are attempting to modify an existing auth info */ + elem=ms_list_find_custom(lc->auth_info,auth_info_compare,info); + if (elem!=NULL){ + linphone_auth_info_destroy((LinphoneAuthInfo*)elem->data); + elem->data=(void *)info; + n=ms_list_position(lc->auth_info,elem); + }else { + lc->auth_info=ms_list_append(lc->auth_info,(void *)info); + n=ms_list_size(lc->auth_info)-1; + } +} + +void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info){ + if (lc->automatic_action>0) lc->automatic_action--; +} + +void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info){ + int len=ms_list_size(lc->auth_info); + int newlen; + int i; + MSList *elem; + lc->auth_info=ms_list_remove(lc->auth_info,info); + newlen=ms_list_size(lc->auth_info); + /*printf("len=%i newlen=%i\n",len,newlen);*/ + linphone_auth_info_destroy(info); + for (i=0;iconfig,NULL,i); + } + for (elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ + linphone_auth_info_write_config(lc->config,(LinphoneAuthInfo*)elem->data,i); + } + +} + +void linphone_core_clear_all_auth_info(LinphoneCore *lc){ + MSList *elem; + int i; + eXosip_lock(); + eXosip_clear_authentication_info(); + eXosip_unlock(); + for(i=0,elem=lc->auth_info;elem!=NULL;elem=ms_list_next(elem),i++){ + LinphoneAuthInfo *info=(LinphoneAuthInfo*)elem->data; + linphone_auth_info_destroy(info); + linphone_auth_info_write_config(lc->config,NULL,i); + } + ms_list_free(lc->auth_info); + lc->auth_info=NULL; +} + +void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev){ + char *prx_realm=NULL,*www_realm=NULL; + osip_proxy_authorization_t *prx_auth; + osip_authorization_t *www_auth; + osip_message_t *msg=ev->request; + char *username; + LinphoneAuthInfo *as=NULL; + + username=osip_uri_get_username(msg->from->url); + osip_message_get_proxy_authorization(msg,0,&prx_auth); + osip_message_get_authorization(msg,0,&www_auth); + if (prx_auth!=NULL) + prx_realm=osip_proxy_authorization_get_realm(prx_auth); + if (www_auth!=NULL) + www_realm=osip_authorization_get_realm(www_auth); + + if (prx_realm==NULL && www_realm==NULL){ + ms_message("No authentication info in the request, ignoring"); + return; + } + /* see if we already have this auth information , not to ask it everytime to the user */ + if (prx_realm!=NULL) + as=linphone_core_auth_info_find(lc,prx_realm,username); + if (www_realm!=NULL) + as=linphone_core_auth_info_find(lc,www_realm,username); + if (as){ + ms_message("Authentication for user=%s realm=%s is working.",username,prx_realm ? prx_realm : www_realm); + as->works=TRUE; + } +} + + +void linphone_core_find_or_ask_for_auth_info(LinphoneCore *lc,const char *username,const char* realm, int tid) +{ + LinphoneAuthInfo *as; + if ((as=linphone_core_auth_info_find(lc,realm,username))==NULL || + (as->works==FALSE && as->first_time==FALSE) ) { + if (lc->vtable.auth_info_requested!=NULL) { + lc->vtable.auth_info_requested(lc,realm,username); + lc->automatic_action++;/*suspends eXosip_automatic_action until the user supplies a password */ + } + if (as) as->first_time=FALSE; + } +} + +void linphone_process_authentication(LinphoneCore *lc, eXosip_event_t *ev) +{ + char *prx_realm=NULL,*www_realm=NULL; + osip_proxy_authenticate_t *prx_auth; + osip_www_authenticate_t *www_auth; + osip_message_t *resp=ev->response; + char *username; + + if (strcmp(ev->request->sip_method,"REGISTER")==0) { + gstate_new_state(lc, GSTATE_REG_FAILED, "Authentication required"); + } + + username=osip_uri_get_username(resp->from->url); + prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0); + www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0); + if (prx_auth!=NULL) + prx_realm=osip_proxy_authenticate_get_realm(prx_auth); + if (www_auth!=NULL) + www_realm=osip_www_authenticate_get_realm(www_auth); + + if (prx_realm==NULL && www_realm==NULL){ + ms_warning("No realm in the server response."); + return; + } + /* see if we already have this auth information , not to ask it everytime to the user */ + if (prx_realm!=NULL) + linphone_core_find_or_ask_for_auth_info(lc,username,prx_realm,ev->tid); + if (www_realm!=NULL) + linphone_core_find_or_ask_for_auth_info(lc,username,www_realm,ev->tid); +} + diff --git a/linphone/coreapi/chat.c b/linphone/coreapi/chat.c new file mode 100644 index 000000000..500c957d9 --- /dev/null +++ b/linphone/coreapi/chat.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * chat.c + * + * Sun Jun 5 19:34:18 2005 + * Copyright 2005 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + #include "linphonecore.h" + #include "private.h" + #include + + LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){ + char *real_url=NULL; + osip_from_t *parsed_url=NULL; + char *route; + if (linphone_core_interpret_url(lc,to,&real_url,&parsed_url,&route)){ + LinphoneChatRoom *cr=ms_new0(LinphoneChatRoom,1); + cr->lc=lc; + cr->peer=real_url; + cr->peer_url=parsed_url; + cr->route=route; + lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr); + return cr; + } + return NULL; + } + + + void linphone_chat_room_destroy(LinphoneChatRoom *cr){ + LinphoneCore *lc=cr->lc; + lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr); + osip_from_free(cr->peer_url); + ms_free(cr->peer); + ms_free(cr->route); + } + +void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ + const char *identity=linphone_core_get_identity(cr->lc); + osip_message_t *sip=NULL; + eXosip_message_build_request(&sip,"MESSAGE",cr->peer,identity,cr->route); + osip_message_set_content_type(sip,"text/plain"); + osip_message_set_body(sip,msg,strlen(msg)); + eXosip_message_send_request(sip); +} + +bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, osip_from_t *from){ + if (cr->peer_url->url->username && from->url->username && + strcmp(cr->peer_url->url->username,from->url->username)==0) return TRUE; + return FALSE; +} + +void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const char *from, const char *msg){ + if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg); +} + +void linphone_core_text_received(LinphoneCore *lc, eXosip_event_t *ev){ + MSList *elem; + const char *msg; + LinphoneChatRoom *cr=NULL; + char *cleanfrom; + osip_from_t *from_url=ev->request->from; + osip_body_t *body=NULL; + + osip_message_get_body(ev->request,0,&body); + if (body==NULL){ + ms_error("Could not get text message from SIP body"); + return; + } + msg=body->body; + from_2char_without_params(from_url,&cleanfrom); + for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){ + cr=(LinphoneChatRoom*)elem->data; + if (linphone_chat_room_matches(cr,from_url)){ + break; + } + cr=NULL; + } + if (cr==NULL){ + /* create a new chat room */ + cr=linphone_core_create_chat_room(lc,cleanfrom); + } + linphone_chat_room_text_received(cr,lc,cleanfrom,msg); + osip_free(cleanfrom); +} + + +void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud){ + cr->user_data=ud; +} +void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr){ + return cr->user_data; +} diff --git a/linphone/coreapi/enum.c b/linphone/coreapi/enum.c new file mode 100644 index 000000000..7bded2299 --- /dev/null +++ b/linphone/coreapi/enum.c @@ -0,0 +1,172 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* enum lookup code */ + +#include +#include + +#include "enum.h" + +#define DNS_ANSWER_MAX_SIZE 2048 + + +char *create_enum_domain(const char *number){ + int len=strlen(number); + char *domain=ms_malloc((len*2)+10); + int i,j; + + for (i=0,j=len-1;j>=0;j--){ + domain[i]=number[j]; + i++; + domain[i]='.'; + i++; + } + strcpy(&domain[i],"e164.arpa"); + ms_message("enum domain for %s is %s",number,domain); + return domain; +} + + +bool_t is_a_number(const char *str){ + char *p=(char *)str; + bool_t res=FALSE; + bool_t space_found=FALSE; + for(;;p++){ + switch(p[0]){ + case '9': + case '8': + case '7': + case '6': + case '5': + case '4': + case '3': + case '2': + case '1': + case '0': + res=TRUE; + if (space_found) return FALSE; /* avoid splited numbers */ + break; + case '\0': + return res; + break; + case ' ': + space_found=TRUE; + break; + default: + return FALSE; + } + } + return FALSE; +} +//4970072278724 +bool_t is_enum(const char *sipaddress, char **enum_domain){ + char *p; + p=strstr(sipaddress,"sip:"); + if (p==NULL) return FALSE; /* enum should look like sip:4369959250*/ + else p+=4; + if (is_a_number(p)){ + if (enum_domain!=NULL){ + *enum_domain=create_enum_domain(p); + } + return TRUE; + } + return FALSE; +} + + + +int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){ + int err; + //char dns_answer[DNS_ANSWER_MAX_SIZE]; + char *begin,*end; + char *host_result, *command; + int i; + bool_t forkok; + /* + ns_msg handle; + int count; + + memset(&handle,0,sizeof(handle)); + *res=NULL; + ms_message("Resolving %s...",enum_domain); + + err=res_search(enum_domain,ns_c_in,ns_t_naptr,dns_answer,DNS_ANSWER_MAX_SIZE); + if (err<0){ + ms_warning("Error resolving enum:",herror(h_errno)); + return -1; + } + ns_initparse(dns_answer,DNS_ANSWER_MAX_SIZE,&handle); + count=ns_msg_count(handle,ns_s_an); + + for(i=0;isip_address[i]=ms_strdup(begin); + err++; + begin=strstr(end+1,"sip:"); + if (begin==NULL) break; + } + ms_free(host_result); + return err; + + parse_error: + ms_free(*res); + ms_free(host_result); + *res=NULL; + ms_warning("Parse error in enum_lookup()."); + return -1; +} + +void enum_lookup_res_free(enum_lookup_res_t *res){ + int i; + for (i=0;isip_address[i]!=NULL) ms_free(res->sip_address[i]); + } + ms_free(res); +} diff --git a/linphone/coreapi/enum.h b/linphone/coreapi/enum.h new file mode 100644 index 000000000..05b285fb7 --- /dev/null +++ b/linphone/coreapi/enum.h @@ -0,0 +1,35 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ENUM_LOOKUP_H +#define ENUM_LOOKUP_H + +#include "private.h" + +#define MAX_ENUM_LOOKUP_RESULTS 10 + +typedef struct enum_lookup_res{ + char *sip_address[MAX_ENUM_LOOKUP_RESULTS]; +}enum_lookup_res_t; + +bool_t is_enum(const char *sipaddress, char **enum_domain); +int enum_lookup(const char *enum_domain, enum_lookup_res_t **res); +void enum_lookup_res_free(enum_lookup_res_t *res); + +#endif diff --git a/linphone/coreapi/exevents.c b/linphone/coreapi/exevents.c new file mode 100644 index 000000000..693d1367d --- /dev/null +++ b/linphone/coreapi/exevents.c @@ -0,0 +1,1012 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "exevents.h" +#include "linphonecore.h" +#include "private.h" +#include "mediastreamer2/mediastream.h" +#include +#include + +static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp); + +static void linphone_call_proceeding(LinphoneCore *lc, eXosip_event_t *ev){ + if (lc->call==NULL){ + ms_warning("Bug in call_proceeding()"); + return; + } + lc->call->cid=ev->cid; + lc->call->did=ev->did; + lc->call->tid=ev->tid; +} + +static void linphone_connect_incoming(LinphoneCore *lc){ + lc->vtable.show(lc); + lc->vtable.display_status(lc,_("Connected.")); + lc->call->state=LCStateAVRunning; + if (lc->ringstream!=NULL){ + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } + if (lc->audiostream->ticker!=NULL){ + /*case where we accepted early media */ + linphone_core_stop_media_streams(lc); + linphone_core_init_media_streams(lc); + } + linphone_core_start_media_streams(lc,lc->call); +} + +int linphone_call_accepted(LinphoneCore *lc, eXosip_event_t *ev) +{ + LinphoneCall *call=lc->call; + sdp_message_t *sdp=eXosip_get_sdp_info(ev->response); + const char *sdpanswer=NULL; + osip_message_t *msg=NULL; + int err; + if (call==NULL){ + ms_warning("No call to accept."); + return 0; + } + linphone_call_proceeding(lc,ev); + call->auth_pending=FALSE; + if (call->state==LCStateAVRunning){ + return 0; /*already accepted*/ + } + linphone_call_init_media_params(call); + if (!lc->sip_conf.sdp_200_ack){ + err=0; + sdp_context_read_answer(call->sdpctx,sdp); + }else{ + /*we receive a 200OK with an sdp offer*/ + err=linphone_answer_sdp(lc,ev,sdp); + if (err==0) sdpanswer=call->sdpctx->answerstr; + } + if (err==0){ + gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL); + linphone_connect_incoming(lc); + } + /*send the ack once streams are started*/ + eXosip_call_build_ack(ev->did,&msg); + if (sdpanswer!=NULL) linphone_set_sdp(msg,sdpanswer); + eXosip_call_send_ack(ev->did,msg); + if (err!=0){ + /*send a bye*/ + ms_error("Incompatible SDP offer received in 200Ok, need to abort the call"); + linphone_core_terminate_call(lc,NULL); + } + return 0; +} + + +int linphone_call_terminated(LinphoneCore *lc, eXosip_event_t *ev) +{ + /*stop ringing if necessary*/ + if (lc->call!=NULL){ + if (lc->call->cid!=ev->cid){ + /* this is not current call */ + ms_message("call %i terminated, this was not current call.",ev->cid); + return 0; + } + } + + ms_message("Current call terminated..."); + if (lc->ringstream!=NULL) { + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } + linphone_core_stop_media_streams(lc); + lc->vtable.show(lc); + lc->vtable.display_status(lc,_("Call terminated.")); + gstate_new_state(lc, GSTATE_CALL_END, NULL); + if (lc->vtable.bye_recv!=NULL){ + char *from; + osip_from_to_str(ev->request->from,&from); + lc->vtable.bye_recv(lc,from); + osip_free(from); + } + if (lc->call!=NULL){ + linphone_call_destroy(lc->call); + lc->call=NULL; + } + return 0; +} + + +int linphone_call_released(LinphoneCore *lc, int cid){ + LinphoneCall *call=lc->call; + if (call!=NULL && call->cid==cid){ + + linphone_call_destroy(lc->call); + lc->call=NULL; + lc->vtable.display_status(lc,_("Could not reach destination.")); + gstate_new_state(lc, GSTATE_CALL_ERROR, NULL); + } + return 0; +} + +int linphone_call_failure(LinphoneCore *lc, eXosip_event_t *ev) +{ + const char *reason=""; + char *msg486=_("User is busy."); + char *msg480=_("User is temporarily unavailable."); + char *msg487=_("Request Cancelled."); + /*char *retrymsg=_("%s. Retry after %i minute(s).");*/ + char *msg600=_("User does not want to be disturbed."); + char *msg603=_("Call declined."); + char* tmpmsg=msg486; + int code; + + if (ev->response){ + code=osip_message_get_status_code(ev->response); + reason=osip_message_get_reason_phrase(ev->response); + }else code=-110; + lc->vtable.show(lc); + + switch(code) + { + case 401: + case 407: + if (lc->call!=NULL) + linphone_process_authentication(lc,ev); + return 0; + break; + case 400: + lc->vtable.display_status(lc,_("Bad request")); + break; + case 404: + lc->vtable.display_status(lc,_("User cannot be found at given address.")); + break; + case 415: + lc->vtable.display_status(lc,_("Remote user cannot support any of proposed codecs.")); + break; + case 480: + tmpmsg=msg480; + case 486: + /* + msg_header_getbyname(msg,"retry-after",0,&retry); + if (retry!=NULL) + { + umsg=g_malloc(strlen(tmpmsg)+strlen(retrymsg)+13); + sprintf(umsg,retrymsg,tmpmsg,atoi(retry->hvalue)/60); + lc->vtable.display_message(lc,umsg); + ms_free(umsg); + }*/ + lc->vtable.display_message(lc,tmpmsg); + break; + case 487: + lc->vtable.display_status(lc,msg487); + break; + case 600: + lc->vtable.display_message(lc,msg600); + break; + case 603: + lc->vtable.display_status(lc,msg603); + break; + case -110: /* time out, call leg is lost */ + lc->vtable.display_status(lc,_("Timeout.")); + break; + case -111: + lc->vtable.display_status(lc,_("Remote host was found but refused connection.")); + break; + + default: + if (code>0) + { + lc->vtable.display_status(lc,reason); + } + else ms_warning("failure_cb unknown code=%i\n",code); + } + if (lc->ringstream!=NULL) { + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } + linphone_core_stop_media_streams(lc); + if (lc->call!=NULL) { + linphone_call_destroy(lc->call); + gstate_new_state(lc, GSTATE_CALL_ERROR, NULL); + lc->call=NULL; + } + return 0; +} + +extern sdp_handler_t linphone_sdphandler; + +static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp){ + int status=200; + sdp_context_t *ctx=NULL; + + ctx=lc->call->sdpctx; + /* get the result of the negociation */ + sdp_context_get_answer(ctx,sdp); + status=sdp_context_get_status(ctx); + + if (status==200){ + linphone_core_init_media_streams(lc); + return 0; + }else{ + if (status==-1) status=415; + } + return -1; +} + +int linphone_inc_new_call(LinphoneCore *lc, eXosip_event_t *ev) +{ + sdp_message_t *sdp=eXosip_get_sdp_info(ev->request); + osip_from_t *from_url=ev->request->from; + char *barmesg; + char *from; + char *to; + int err; + + osip_from_to_str(ev->request->from,&from); + osip_to_to_str(ev->request->to,&to); + + /* first check if we can answer successfully to this invite */ + if (lc->presence_mode!=LINPHONE_STATUS_ONLINE){ + ms_message("Not present !! presence mode : %d\n",lc->presence_mode); + eXosip_lock(); + if (lc->presence_mode==LINPHONE_STATUS_BUSY) + eXosip_call_send_answer(ev->tid,486,NULL); + else if (lc->presence_mode==LINPHONE_STATUS_AWAY + ||lc->presence_mode==LINPHONE_STATUS_BERIGHTBACK + ||lc->presence_mode==LINPHONE_STATUS_ONTHEPHONE + ||lc->presence_mode==LINPHONE_STATUS_OUTTOLUNCH + ||lc->presence_mode==LINPHONE_STATUS_OFFLINE) + eXosip_call_send_answer(ev->tid,480,NULL); + else if (lc->presence_mode==LINPHONE_STATUS_NOT_DISTURB) + eXosip_call_send_answer(ev->tid,480,NULL); + else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_MOVED) + { + osip_message_t *msg; + eXosip_call_build_answer(ev->tid,302,&msg); + osip_message_set_contact(msg,lc->alt_contact); + eXosip_call_send_answer(ev->tid,302,msg); + } + else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_ALT_SERVICE) + { + osip_message_t *msg; + eXosip_call_build_answer(ev->tid,380,&msg); + osip_message_set_contact(msg,lc->alt_contact); + eXosip_call_send_answer(ev->tid,380,msg); + } + else + eXosip_call_send_answer(ev->tid,486,NULL); + eXosip_unlock(); + goto end; + } + if (lc->call!=NULL){/*busy*/ + eXosip_lock(); + eXosip_call_send_answer(ev->tid,486,NULL); + eXosip_unlock(); + goto end; + } + lc->call=linphone_call_new_incoming(lc,from,to,ev->cid,ev->did,ev->tid); + if (sdp==NULL){ + ms_message("No sdp body in invite, 200-ack scheme"); + err=0; + }else{ + err=linphone_answer_sdp(lc,ev,sdp); + } + if (!err){ + char *tmp; + if (from_2char_without_params(from_url,&tmp)!=0){ + tmp=ms_strdup("Unknown user"); + } + gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp); + barmesg=ortp_strdup_printf("%s %s",tmp,_("is contacting you.")); + lc->vtable.show(lc); + lc->vtable.display_status(lc,barmesg); + lc->vtable.inv_recv(lc,tmp); + ms_free(barmesg); + osip_free(tmp); + + linphone_call_set_state(lc->call,LCStateRinging); + eXosip_lock(); + eXosip_call_send_answer(ev->tid,180,NULL); + eXosip_unlock(); + /* play the ring */ + if (lc->sound_conf.ring_sndcard!=NULL){ + ms_message("Starting local ring..."); + lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard); + } + }else{ + ms_error("Error during sdp negociation. "); + eXosip_lock(); + eXosip_call_send_answer(ev->tid,415,NULL); + eXosip_unlock(); + linphone_call_destroy(lc->call); + lc->call=NULL; + } + end: + osip_free(from); + osip_free(to); + return 0; +} + +void linphone_handle_ack(LinphoneCore *lc, eXosip_event_t *ev){ + sdp_message_t *sdp=eXosip_get_sdp_info(ev->ack); + if (sdp){ + sdp_context_read_answer(lc->call->sdpctx,sdp); + linphone_connect_incoming(lc); + } +} + +void linphone_handle_reinvite(LinphoneCore *lc, eXosip_event_t *ev){ + sdp_message_t *sdp=eXosip_get_sdp_info(ev->request); + sdp_context_t *ctx; + LinphoneCall *call=lc->call; + char *answer; + int status; + if (sdp==NULL){ + ms_warning("No sdp in reinvite !"); + eXosip_lock(); + eXosip_call_send_answer(ev->tid,603,NULL); + eXosip_unlock(); + return; + } + ctx=call->sdpctx; + /* get the result of the negociation */ + linphone_call_init_media_params(call); + answer=sdp_context_get_answer(ctx,sdp); + status=sdp_context_get_status(ctx); + if (status==200){ + osip_message_t *msg=NULL; + linphone_core_stop_media_streams(lc); + linphone_core_init_media_streams(lc); + eXosip_lock(); + if (eXosip_call_build_answer(ev->tid,200,&msg)<0){ + ms_warning("Reinvite for closed call ?"); + eXosip_unlock(); + linphone_core_stop_media_streams(lc); + return ; + } + answer=call->sdpctx->answerstr; /* takes the sdp already computed*/ + linphone_set_sdp(msg,answer); + eXosip_call_send_answer(ev->tid,200,msg); + eXosip_unlock(); + linphone_core_start_media_streams(lc,call); + }else{ + eXosip_lock(); + eXosip_call_send_answer(ev->tid,status,NULL); + eXosip_unlock(); + } +} + +void linphone_do_automatic_redirect(LinphoneCore *lc, const char *contact){ + char *msg=ortp_strdup_printf(_("Redirected to %s..."),contact); + lc->vtable.display_status(lc,msg); + ms_free(msg); + if (lc->call!=NULL) linphone_call_destroy(lc->call); + lc->call=NULL; + linphone_core_invite(lc,contact); +} + +void linphone_call_redirected(LinphoneCore *lc, eXosip_event_t *ev){ + int code=osip_message_get_status_code(ev->response); + char *contact=NULL; + osip_contact_t *ct; + osip_message_get_contact(ev->response,0,&ct); + if (ct) osip_contact_to_str(ct,&contact); + switch(code){ + case 380: + lc->vtable.display_url(lc,_("User is not reachable at the moment but he invites you\nto contact him using the following alternate resource:"),contact); + if (lc->call!=NULL) linphone_call_destroy(lc->call); + lc->call=NULL; + break; + case 302: + linphone_do_automatic_redirect(lc,contact); + break; + } + if (contact) osip_free(contact); +} + + +/* these are the SdpHandler callbacks: we are called in to be aware of the content +of the SDP messages exchanged */ + +int linphone_set_audio_offer(sdp_context_t *ctx) +{ + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + PayloadType *codec; + MSList *elem; + sdp_payload_t payload; + + + elem=lc->codecs_conf.audio_codecs; + while(elem!=NULL){ + codec=(PayloadType*) elem->data; + if (linphone_core_check_payload_type_usability(lc,codec) && payload_type_enabled(codec)){ + sdp_payload_init(&payload); + payload.a_rtpmap=ortp_strdup_printf("%s/%i/1",codec->mime_type,codec->clock_rate); + payload.pt=rtp_profile_get_payload_number_from_rtpmap(lc->local_profile,payload.a_rtpmap); + payload.localport=lc->rtp_conf.audio_rtp_port; + if (strcasecmp(codec->mime_type,"iLBC")==0){ + /* prefer the 30 ms mode */ + payload.a_fmtp="ptime=30"; + } + sdp_context_add_audio_payload(ctx,&payload); + ms_free(payload.a_rtpmap); + } + elem=ms_list_next(elem); + } + /* add telephone-event payload*/ + sdp_payload_init(&payload); + payload.pt=rtp_profile_get_payload_number_from_mime(lc->local_profile,"telephone-event"); + payload.a_rtpmap="telephone-event/8000"; + payload.a_fmtp="0-11"; + if (lc->dw_audio_bw>0) payload.b_as_bandwidth=lc->dw_audio_bw; + sdp_context_add_audio_payload(ctx,&payload); + return 0; +} + +static int find_payload_type_number(RtpProfile *prof, PayloadType *pt){ + int candidate=-1,i; + PayloadType *it; + for(i=0;i<127;++i){ + it=rtp_profile_get_payload(prof,i); + if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0 + && (pt->clock_rate==it->clock_rate || pt->clock_rate<=0) ){ + if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) || + (pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){ + /*exact match*/ + return i; + }else candidate=i; + } + } + if (candidate==-1) ms_fatal("Should not happen."); + return candidate; +} + +static int find_payload_type_number_best_match(RtpProfile *prof, const char *rtpmap, const char *fmtp){ + int localpt=rtp_profile_get_payload_number_from_rtpmap(prof,rtpmap); + PayloadType *pt; + char value[10]; + if (localpt<0) return -1; + pt=rtp_profile_get_payload(prof,localpt); + if (strcasecmp(pt->mime_type,"H264")==0){ + /*hack for H264: need to answer with same packetization-mode*/ + if (fmtp && fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){ + PayloadType tmp; + memset(&tmp,0,sizeof(tmp)); + tmp.mime_type="H264"; + tmp.clock_rate=pt->clock_rate; + tmp.recv_fmtp=(atoi(value)==1) ? "packetization-mode=1" : NULL; + localpt=find_payload_type_number(prof,&tmp); + } + } + return localpt; +} + +int linphone_set_video_offer(sdp_context_t *ctx) +{ + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + PayloadType *codec; + MSList *elem; + bool_t firsttime=TRUE; + + if (!linphone_core_video_enabled(lc)) return -1; + + for(elem=lc->codecs_conf.video_codecs;elem!=NULL;elem=ms_list_next(elem)){ + codec=(PayloadType*) elem->data; + if (linphone_core_check_payload_type_usability(lc,codec) && payload_type_enabled(codec)){ + sdp_payload_t payload; + sdp_payload_init(&payload); + payload.line=1; + payload.a_rtpmap=ortp_strdup_printf("%s/%i",codec->mime_type,codec->clock_rate); + payload.localport=lc->rtp_conf.video_rtp_port; + payload.pt=find_payload_type_number(lc->local_profile,codec); + payload.a_fmtp=codec->recv_fmtp; + if(firsttime){ + firsttime=FALSE; + if (lc->dw_video_bw>0) + payload.b_as_bandwidth=lc->dw_video_bw; + } + sdp_context_add_video_payload(ctx,&payload); + ms_free(payload.a_rtpmap); + } + } + return 0; +} + +typedef enum { + Unsupported, + Supported, + SupportedAndValid /* valid= the presence of this codec is enough to make a call */ +}SupportLevel; + +SupportLevel linphone_payload_is_supported(LinphoneCore *lc, sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile, bool_t answering, PayloadType **local_payload_type) +{ + int localpt; + SupportLevel ret; + if (payload->a_rtpmap!=NULL){ + localpt=find_payload_type_number_best_match(local_profile,payload->a_rtpmap,payload->a_fmtp); + }else{ + localpt=payload->pt; + ms_warning("payload has no rtpmap."); + } + + if (localpt>=0 && localpt <128 ){ + /* this payload is understood, but does the user want to use it ?? */ + PayloadType *rtppayload; + rtppayload=rtp_profile_get_payload(local_profile,localpt); + if (rtppayload==NULL) { + ms_warning("strange error !!"); + return Unsupported; + } + *local_payload_type=rtppayload; + if (strcmp(rtppayload->mime_type,"telephone-event")!=0){ + if (answering && !linphone_core_check_payload_type_usability(lc,rtppayload) ){ + ms_warning("payload %s is not usable",rtppayload->mime_type); + return Unsupported; + } + if ( !payload_type_enabled(rtppayload)) { + ms_warning("payload %s is not enabled.",rtppayload->mime_type); + return Unsupported; + } + ret=SupportedAndValid; + }else ret=Supported; + if (dialog_profile!=NULL){ + int dbw,ubw; + /* this payload is supported in our local rtp profile, so add it to the dialog rtp + profile */ + rtppayload=payload_type_clone(rtppayload); + rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload); + /* add to the rtp payload type some other parameters (bandwidth) */ + if (rtppayload->type==PAYLOAD_VIDEO){ + dbw=lc->dw_video_bw; + ubw=lc->up_video_bw; + }else{ + dbw=lc->dw_audio_bw; + ubw=lc->up_audio_bw; + } + if (payload->b_as_bandwidth!=0){ + ms_message("Remote bandwidth constraint: %i",payload->b_as_bandwidth); + /*obey to remote bandwidth constraint AND our own upbandwidth constraint*/ + rtppayload->normal_bitrate=1000*get_min_bandwidth( + payload->b_as_bandwidth, ubw); + }else{ + /*limit to upload bandwidth if exist, else no limit*/ + rtppayload->normal_bitrate=(ubw>0)? 1000*ubw : -1; + } + /* but anyway give our download bandwidth constraint*/ + payload->b_as_bandwidth=(dbw>0) ? dbw : 0; + if (payload->a_fmtp!=NULL){ + payload_type_set_send_fmtp(rtppayload,payload->a_fmtp); + } + payload->a_fmtp=rtppayload->recv_fmtp; + if (payload->a_ptime>0){ + char tmp[30]; + snprintf(tmp,sizeof(tmp),"ptime=%i",payload->a_ptime); + payload_type_append_send_fmtp(rtppayload,tmp); + ms_message("%s attribute added to fmtp",tmp); + } + } + return ret; + } + return Unsupported; +} + +int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload) +{ + RtpProfile *remote_profile; + StreamParams *params; + SupportLevel supported; + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + PayloadType *lpt=NULL; + + if (call->profile==NULL){ + /* create a remote user agent profile */ + call->profile=remote_profile=rtp_profile_new("remote"); + } + remote_profile=call->profile; + /* see if this codec is supported in our local rtp profile*/ + supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt); + if (supported==Unsupported) { + ms_message("Refusing audio codec %i (%s)",payload->pt,payload->a_rtpmap); + return -1; + } + if (supported==SupportedAndValid) { + params=&call->audio_params; + if (params->initialized==0){ + /* this is the first codec we accept, it is going to be used*/ + params->localport=payload->localport=lc->rtp_conf.audio_rtp_port; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + if (payload->relay_host!=NULL){ + params->remoteaddr=payload->relay_host; + params->remoteport=payload->relay_port; + params->remotertcpport=payload->relay_port; + params->relay_session_id=payload->relay_session_id; + }else{ + params->remoteaddr=payload->c_addr; + params->remoteport=payload->remoteport; + params->remotertcpport=payload->remoteport+1; + } + params->initialized=1; + /* we can now update the allocated bandwidth for audio, and then video*/ + linphone_core_update_allocated_audio_bandwidth(lc,lpt); + }else{ + /* refuse all other audio lines*/ + if(params->line!=payload->line) return -1; + } + } + return 0; +} + +int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload) +{ + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + RtpProfile *remote_profile; + StreamParams *params; + SupportLevel supported; + PayloadType *lpt=NULL; + + if (!linphone_core_video_enabled(lc)) return -1; + + if (call->profile==NULL){ + /* create a remote user agent profile */ + call->profile=rtp_profile_new("remote"); + } + remote_profile=call->profile; + /* see if this codec is supported in our local rtp profile*/ + supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt); + if (supported==Unsupported) { + ms_message("Refusing video codec %i (%s)",payload->pt,payload->a_rtpmap); + return -1; + } + if (supported==SupportedAndValid){ + params=&call->video_params; + if (params->initialized==0){ + /* this is the first codec we may accept*/ + params->localport=payload->localport=lc->rtp_conf.video_rtp_port; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + if (payload->relay_host!=NULL){ + params->remoteaddr=payload->relay_host; + params->remoteport=payload->relay_port; + params->remotertcpport=payload->relay_port; + params->relay_session_id=payload->relay_session_id; + }else{ + params->remoteaddr=payload->c_addr; + params->remoteport=payload->remoteport; + params->remotertcpport=params->remoteport+1; + } + params->initialized=1; + }else{ + /* refuse all other video lines*/ + if(params->line!=payload->line) return -1; + } + } + return 0; +} + +int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload) +{ + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + StreamParams *params; + SupportLevel supported; + PayloadType *lpt=NULL; + + /* paranoid check: see if this codec is supported in our local rtp profile*/ + supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt); + if (supported==Unsupported) { + ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap); + return 0; + } + if (supported==SupportedAndValid){ + params=&call->audio_params; + if (params->initialized==0){ + /* this is the first codec we accept, this is the one that is going to be used (at least for sending + data.*/ + params->localport=lc->rtp_conf.audio_rtp_port; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + if (payload->relay_host!=NULL){ + params->remoteaddr=payload->relay_host; + params->remoteport=payload->relay_port; + params->remotertcpport=payload->relay_port; + params->relay_session_id=payload->relay_session_id; + }else{ + params->remoteaddr=payload->c_addr; + params->remoteport=payload->remoteport; + params->remotertcpport=payload->remoteport+1; + } + params->initialized=1; + /* we can now update the allocated bandwidth for audio, and then video*/ + linphone_core_update_allocated_audio_bandwidth(lc,lpt); + } + } + return 0; +} + +int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload) +{ + LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx); + LinphoneCore *lc=call->core; + StreamParams *params; + SupportLevel supported; + PayloadType *lpt=NULL; + + /* paranoid check: see if this codec is supported in our local rtp profile*/ + supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt); + if (supported==Unsupported) { + ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap); + return 0; + } + if (supported==SupportedAndValid){ + params=&call->video_params; + if (params->initialized==0){ + /* this is the first codec we may accept*/ + params->localport=lc->rtp_conf.video_rtp_port; + params->line=payload->line; + params->pt=payload->pt; /* remember the first payload accepted */ + if (payload->relay_host!=NULL){ + params->remoteaddr=payload->relay_host; + params->remoteport=payload->relay_port; + params->remotertcpport=payload->relay_port; + params->relay_session_id=payload->relay_session_id; + }else{ + params->remoteaddr=payload->c_addr; + params->remoteport=payload->remoteport; + params->remotertcpport=payload->remoteport+1; + } + params->initialized=1; + } + } + return 0; +} + +void linphone_call_ringing(LinphoneCore *lc, eXosip_event_t *ev){ + sdp_message_t *sdp=eXosip_get_sdp_info(ev->response); + LinphoneCall *call=lc->call; + + linphone_call_proceeding(lc,ev); + + if (sdp==NULL){ + if (lc->ringstream!=NULL) return; /*already ringing !*/ + if (lc->sound_conf.play_sndcard!=NULL){ + ms_message("Remote ringing..."); + lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,lc->sound_conf.play_sndcard); + } + }else{ + /*accept early media */ + StreamParams *audio_params; + if (call==NULL){ + ms_error("No call ?"); + goto end; + } + if (lc->audiostream->ticker!=NULL){ + /*streams already started */ + ms_message("Early media already started."); + goto end; + } + audio_params=&call->audio_params; + sdp_context_read_answer(lc->call->sdpctx,sdp); + lc->vtable.show(lc); + lc->vtable.display_status(lc,_("Early media.")); + gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL); + if (lc->ringstream!=NULL){ + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } + ms_message("Doing early media..."); + linphone_core_start_media_streams(lc,call); + } + call->state=LCStateRinging; + goto end; + end: + sdp_message_free(sdp); + +} + +void linphone_call_message_new(LinphoneCore *lc, eXosip_event_t *ev){ +#ifdef VIDEO_ENABLED + if (ev->request){ + if (MSG_IS_INFO(ev->request)){ + osip_content_type_t *ct; + ct=osip_message_get_content_type(ev->request); + if (ct && ct->subtype && + strcmp(ct->subtype,"media_control+xml")==0){ + osip_body_t *body=NULL; + osip_message_get_body(ev->request,0,&body); + if (body && body->body!=NULL && + strstr(body->body,"picture_fast_update")){ + osip_message_t *ans=NULL; + ms_message("Receiving VFU request !"); + if (lc->videostream) + video_stream_send_vfu(lc->videostream); + eXosip_call_build_answer(ev->tid,200,&ans); + if (ans) + eXosip_call_send_answer(ev->tid,200,ans); + } + } + } + }else ms_warning("linphone_call_message_new: No request ?"); +#endif +} + + +void linphone_registration_faillure(LinphoneCore *lc, eXosip_event_t *ev){ + int status_code=0; + char *msg; + const char *reason=NULL; + osip_uri_t *requri=osip_message_get_uri(ev->request); + char *ru; + + osip_uri_to_str(requri,&ru); + + if (ev->response){ + status_code=osip_message_get_status_code(ev->response); + reason=osip_message_get_reason_phrase(ev->response); + } + switch(status_code){ + case 401: + case 407: + linphone_process_authentication(lc,ev); + break; + default: + msg=ortp_strdup_printf(_("Registration on %s failed: %s"),ru,(reason!=NULL) ? reason : _("no response timeout")); + lc->vtable.display_status(lc,msg); + gstate_new_state(lc, GSTATE_REG_FAILED, msg); + ms_free(msg); + } + osip_free(ru); +} + +void linphone_registration_success(LinphoneCore *lc,eXosip_event_t *ev){ + LinphoneProxyConfig *cfg; + osip_uri_t *requri=osip_message_get_uri(ev->request); + char *msg; + char *ru; + osip_uri_to_str(requri,&ru); + msg=ms_strdup_printf(_("Registration on %s successful."),ru); + lc->vtable.display_status(lc,msg); + ms_free(msg); + osip_free(ru); + cfg=linphone_core_get_proxy_config_from_rid(lc,ev->rid); + ms_return_if_fail(cfg!=NULL); + cfg->auth_pending=FALSE; + cfg->registered=TRUE; + gstate_new_state(lc, GSTATE_REG_OK, NULL); +} + +static void linphone_other_request(LinphoneCore *lc, eXosip_event_t *ev){ + if (ev->request==NULL) return; + if (strcmp(ev->request->sip_method,"MESSAGE")==0){ + linphone_core_text_received(lc,ev); + eXosip_message_send_answer(ev->tid,200,NULL); + }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){ + eXosip_options_send_answer(ev->tid,200,NULL); + } + else { + ms_message("Unsupported request received."); + /*answer with a 501 Not implemented*/ + eXosip_message_send_answer(ev->tid,501,NULL); + } +} + +void linphone_core_process_event(LinphoneCore *lc,eXosip_event_t *ev) +{ + switch(ev->type){ + case EXOSIP_CALL_ANSWERED: + ms_message("CALL_ANSWERED\n"); + linphone_call_accepted(lc,ev); + linphone_authentication_ok(lc,ev); + break; + case EXOSIP_CALL_CLOSED: + case EXOSIP_CALL_CANCELLED: + ms_message("CALL_CLOSED or CANCELLED\n"); + linphone_call_terminated(lc,ev); + break; + case EXOSIP_CALL_TIMEOUT: + case EXOSIP_CALL_NOANSWER: + ms_message("CALL_TIMEOUT or NOANSWER\n"); + linphone_call_failure(lc,ev); + break; + case EXOSIP_CALL_REQUESTFAILURE: + case EXOSIP_CALL_GLOBALFAILURE: + case EXOSIP_CALL_SERVERFAILURE: + ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n"); + linphone_call_failure(lc,ev); + break; + case EXOSIP_CALL_INVITE: + ms_message("CALL_NEW\n"); + /* CALL_NEW is used twice in qos mode : + * when you receive invite (textinfo = "With QoS" or "Without QoS") + * and when you receive update (textinfo = "New Call") */ + linphone_inc_new_call(lc,ev); + break; + case EXOSIP_CALL_REINVITE: + linphone_handle_reinvite(lc,ev); + break; + case EXOSIP_CALL_ACK: + ms_message("CALL_ACK"); + linphone_handle_ack(lc,ev); + break; + case EXOSIP_CALL_REDIRECTED: + ms_message("CALL_REDIRECTED"); + linphone_call_redirected(lc,ev); + break; + case EXOSIP_CALL_PROCEEDING: + ms_message("CALL_PROCEEDING"); + linphone_call_proceeding(lc,ev); + break; + case EXOSIP_CALL_RINGING: + ms_message("CALL_RINGING"); + linphone_call_ringing(lc,ev); + break; + case EXOSIP_CALL_MESSAGE_NEW: + ms_message("EXOSIP_CALL_MESSAGE_NEW"); + linphone_call_message_new(lc,ev); + break; + case EXOSIP_CALL_MESSAGE_REQUESTFAILURE: + if (ev->did<0 && ev->response && + (ev->response->status_code==407 || ev->response->status_code==401)){ + eXosip_default_action(ev); + } + break; + case EXOSIP_IN_SUBSCRIPTION_NEW: + ms_message("CALL_SUBSCRIPTION_NEW or UPDATE"); + linphone_subscription_new(lc,ev); + break; + case EXOSIP_SUBSCRIPTION_UPDATE: + break; + case EXOSIP_SUBSCRIPTION_NOTIFY: + ms_message("CALL_SUBSCRIPTION_NOTIFY"); + linphone_notify_recv(lc,ev); + break; + case EXOSIP_SUBSCRIPTION_ANSWERED: + ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid); + linphone_subscription_answered(lc,ev); + break; + case EXOSIP_SUBSCRIPTION_CLOSED: + ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n"); + linphone_subscription_closed(lc,ev); + break; + case EXOSIP_CALL_RELEASED: + ms_message("CALL_RELEASED\n"); + linphone_call_released(lc, ev->cid); + break; + case EXOSIP_REGISTRATION_FAILURE: + ms_message("REGISTRATION_FAILURE\n"); + linphone_registration_faillure(lc,ev); + break; + case EXOSIP_REGISTRATION_SUCCESS: + linphone_registration_success(lc,ev); + linphone_authentication_ok(lc,ev); + break; + case EXOSIP_MESSAGE_NEW: + linphone_other_request(lc,ev); + break; + case EXOSIP_MESSAGE_REQUESTFAILURE: + if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){ + /*the user is expected to have registered to the proxy, thus password is known*/ + eXosip_default_action(ev); + } + break; + default: + break; + } + eXosip_event_free(ev); +} diff --git a/linphone/coreapi/exevents.h b/linphone/coreapi/exevents.h new file mode 100644 index 000000000..c7e7baa9b --- /dev/null +++ b/linphone/coreapi/exevents.h @@ -0,0 +1,40 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef EXEVENTS_H +#define EXEVENTS_H +#include +#include "sdphandler.h" + + +void linphone_core_process_event(LinphoneCore *lc, eXosip_event_t *ev); + +/* these are the SdpHandler callbacks: we are called in to be aware of the content +of the SDP messages exchanged */ + +int linphone_set_audio_offer(sdp_context_t *ctx); +int linphone_set_video_offer(sdp_context_t *ctx); +int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload); +int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload); +int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload); +int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload); + +void linphone_core_text_received(LinphoneCore *lc, eXosip_event_t *ev); + +#endif diff --git a/linphone/coreapi/friend.c b/linphone/coreapi/friend.c new file mode 100644 index 000000000..50938a61f --- /dev/null +++ b/linphone/coreapi/friend.c @@ -0,0 +1,736 @@ +/*************************************************************************** + * friend.c + * + * Sat May 15 15:25:16 2004 + * Copyright 2004 Simon Morlat + * Email + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "linphonecore.h" +#include "private.h" +#include +#include +#include "lpconfig.h" + +const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){ + const char *str=NULL; + switch(ss){ + case LINPHONE_STATUS_UNKNOWN: + str=_("Unknown"); + break; + case LINPHONE_STATUS_ONLINE: + str=_("Online"); + break; + case LINPHONE_STATUS_BUSY: + str=_("Busy"); + break; + case LINPHONE_STATUS_BERIGHTBACK: + str=_("Be right back"); + break; + case LINPHONE_STATUS_AWAY: + str=_("Away"); + break; + case LINPHONE_STATUS_ONTHEPHONE: + str=_("On the phone"); + break; + case LINPHONE_STATUS_OUTTOLUNCH: + str=_("Out to lunch"); + break; + case LINPHONE_STATUS_NOT_DISTURB: + str=_("Do not disturb"); + break; + case LINPHONE_STATUS_MOVED: + str=_("Moved"); + break; + case LINPHONE_STATUS_ALT_SERVICE: + str=_("Using another messaging service"); + break; + case LINPHONE_STATUS_OFFLINE: + str=_("Offline"); + break; + case LINPHONE_STATUS_PENDING: + str=_("Pending"); + break; + case LINPHONE_STATUS_CLOSED: + str=_("Closed"); + break; + default: + str=_("Unknown-bug"); + } + return str; +} + +static int friend_data_compare(const void * a, const void * b, void * data){ + osip_from_t *fa=((LinphoneFriend*)a)->url; + osip_from_t *fb=((LinphoneFriend*)b)->url; + char *ua,*ub; + ua=fa->url->username; + ub=fb->url->username; + if (ua!=NULL && ub!=NULL) { + //printf("Comparing usernames %s,%s\n",ua,ub); + return strcasecmp(ua,ub); + } + else { + /* compare hosts*/ + ua=fa->url->host; + ub=fb->url->host; + if (ua!=NULL && ub!=NULL){ + int ret=strcasecmp(ua,ub); + //printf("Comparing hostnames %s,%s,res=%i\n",ua,ub,ret); + return ret; + } + else return -1; + } +} + +static int friend_compare(const void * a, const void * b){ + return friend_data_compare(a,b,NULL); +} + + +MSList *find_friend(MSList *fl, const osip_from_t *friend, LinphoneFriend **lf){ + MSList *res=NULL; + LinphoneFriend dummy; + if (lf!=NULL) *lf=NULL; + dummy.url=(osip_from_t*)friend; + res=ms_list_find_custom(fl,friend_compare,&dummy); + if (lf!=NULL && res!=NULL) *lf=(LinphoneFriend*)res->data; + return res; +} + +LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid){ + MSList *elem; + for (elem=l;elem!=NULL;elem=elem->next){ + LinphoneFriend *lf=(LinphoneFriend*)elem->data; + if (lf->nid==nid) return lf; + } + return NULL; +} + +LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid){ + MSList *elem; + for (elem=l;elem!=NULL;elem=elem->next){ + LinphoneFriend *lf=(LinphoneFriend*)elem->data; + if (lf->sid==sid) return lf; + } + return NULL; +} + +void __linphone_friend_do_subscribe(LinphoneFriend *fr){ + char *friend=NULL; + const char *route=NULL; + const char *from=NULL; + osip_message_t *msg=NULL; + osip_from_to_str(fr->url,&friend); + if (fr->proxy!=NULL){ + route=fr->proxy->reg_route; + from=fr->proxy->reg_identity; + }else from=linphone_core_get_primary_contact(fr->lc); + if (fr->sid<0){ + /* people for which we don't have yet an answer should appear as offline */ + fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr,friend,_("Gone"),"sip-closed.png"); + } + eXosip_lock(); + eXosip_subscribe_build_initial_request(&msg,friend,from,route,"presence",600); + eXosip_subscribe_send_initial_request(msg); + eXosip_unlock(); + osip_free(friend); +} + + +LinphoneFriend * linphone_friend_new(){ + LinphoneFriend *obj=ms_new0(LinphoneFriend,1); + obj->out_did=-1; + obj->in_did=-1; + obj->nid=-1; + obj->sid=-1; + obj->pol=LinphoneSPAccept; + obj->status=LINPHONE_STATUS_OFFLINE; + obj->subscribe=TRUE; + return obj; +} + +LinphoneFriend *linphone_friend_new_with_addr(const char *addr){ + LinphoneFriend *fr=linphone_friend_new(); + if (linphone_friend_set_sip_addr(fr,addr)<0){ + linphone_friend_destroy(fr); + return NULL; + } + return fr; +} + + +int linphone_friend_set_sip_addr(LinphoneFriend *lf, const char *addr){ + int err; + osip_from_t *fr=NULL; + osip_from_init(&fr); + err=osip_from_parse(fr,addr); + if (err<0) { + ms_warning("Invalid friend sip uri: %s",addr); + osip_from_free(fr); + return -1; + } + if (lf->url!=NULL) osip_from_free(lf->url); + lf->url=fr; + return 0; +} + +int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ + osip_from_t *fr=lf->url; + if (fr==NULL){ + ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name()."); + return -1; + } + if (fr->displayname!=NULL){ + osip_free(fr->displayname); + fr->displayname=NULL; + } + if (name && name[0]!='\0'){ + fr->displayname=osip_strdup(name); + } + return 0; +} + +int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val){ + fr->subscribe=val; + return 0; +} + +int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol) +{ + fr->pol=pol; + return 0; +} + +int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg){ + fr->proxy=cfg; + return 0; +} + +void linphone_friend_set_sid(LinphoneFriend *lf, int sid){ + lf->sid=sid; +} +void linphone_friend_set_nid(LinphoneFriend *lf, int nid){ + lf->nid=nid; + lf->inc_subscribe_pending=TRUE; +} + +void add_presence_body(osip_message_t *notify, LinphoneOnlineStatus online_status) +{ + char buf[1000]; +#ifdef SUPPORT_MSN + int atom_id = 1000; +#endif + char *contact_info; + + osip_contact_t *ct=NULL; + osip_message_get_contact(notify,0,&ct); + osip_contact_to_str(ct,&contact_info); + +#ifdef SUPPORT_MSN + + if (online_status==LINPHONE_STATUS_ONLINE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else if (online_status==LINPHONE_STATUS_BUSY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else if (online_status==LINPHONE_STATUS_BERIGHTBACK) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else if (online_status==LINPHONE_STATUS_AWAY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else if (online_status==LINPHONE_STATUS_ONTHEPHONE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else if (online_status==LINPHONE_STATUS_OUTTOLUNCH) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + + } + else + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", contact_info, atom_id, contact_info); + } + + osip_message_set_body(notify, buf, strlen(buf)); + osip_message_set_content_type(notify, "application/xpidf+xml"); +#else + + if (online_status==LINPHONE_STATUS_ONLINE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ +%s\n\ +online\n\ +\n\ +", + contact_info, contact_info); + } + else if (online_status==LINPHONE_STATUS_BUSY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + busy\n\ +\n\ +\n\ +%s\n\ +busy\n\ +\n\ +", + contact_info, contact_info); + } + else if (online_status==LINPHONE_STATUS_BERIGHTBACK) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + in-transit\n\ +\n\ +\n\ +%s\n\ +be right back\n\ +\n\ +", + contact_info, contact_info); + } + else if (online_status==LINPHONE_STATUS_AWAY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + away\n\ +\n\ +\n\ +%s\n\ +away\n\ +\n\ +", + contact_info, contact_info); + } + else if (online_status==LINPHONE_STATUS_ONTHEPHONE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + on-the-phone\n\ +\n\ +\n\ +%s\n\ +on the phone\n\ +\n\ +", + contact_info, contact_info); + } + else if (online_status==LINPHONE_STATUS_OUTTOLUNCH) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + meal\n\ +\n\ +\n\ +%s\n\ +out to lunch\n\ +\n\ +", + contact_info, contact_info); + } + else + { + /* */ + sprintf(buf, "\n\ +\n%s", + contact_info, +"\n\ +\n\ +closed\n\ +\n\ + permanent-absence\n\ +\n\ +\n\ +\n\ +\n\n"); + } + osip_message_set_body(notify, buf, strlen(buf)); + osip_message_set_content_type(notify, "application/pidf+xml"); + +#endif + osip_free(contact_info); +} + + +void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os){ + //printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid); + if (lf->in_did!=-1){ + osip_message_t *msg=NULL; + const char *identity; + if (lf->proxy!=NULL) identity=lf->proxy->reg_identity; + else identity=linphone_core_get_primary_contact(lf->lc); + eXosip_lock(); + eXosip_insubscription_build_notify(lf->in_did,ss,0,&msg); + if (msg!=NULL){ + osip_message_set_contact(msg,identity); + add_presence_body(msg,os); + eXosip_insubscription_send_request(lf->in_did,msg); + }else ms_error("could not create notify for incoming subscription."); + eXosip_unlock(); + } +} + +static void linphone_friend_unsubscribe(LinphoneFriend *lf){ + if (lf->out_did!=-1) { + osip_message_t *msg=NULL; + eXosip_lock(); + eXosip_subscribe_build_refresh_request(lf->out_did,&msg); + if (msg){ + osip_message_set_expires(msg,"0"); + eXosip_subscribe_send_refresh_request(lf->out_did,msg); + }else ms_error("Could not build subscribe refresh request !"); + eXosip_unlock(); + } +} + +void linphone_friend_destroy(LinphoneFriend *lf){ + linphone_friend_notify(lf,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED); + linphone_friend_unsubscribe(lf); + if (lf->url!=NULL) osip_from_free(lf->url); + ms_free(lf); +} + +void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg){ + if (lf->proxy==cfg){ + lf->proxy=NULL; + } +} + +char *linphone_friend_get_addr(LinphoneFriend *lf){ + char *ret,*tmp; + if (lf->url==NULL) return NULL; + osip_uri_to_str(lf->url->url,&tmp); + ret=ms_strdup(tmp); + osip_free(tmp); + return ret; +} + +char *linphone_friend_get_name(LinphoneFriend *lf){ + if (lf->url==NULL) return NULL; + if (lf->url->displayname==NULL) return NULL; + return ms_strdup(lf->url->displayname); +} + +char * linphone_friend_get_url(LinphoneFriend *lf){ + char *tmp,*ret; + if (lf->url==NULL) return NULL; + osip_from_to_str(lf->url,&tmp); + ret=ms_strdup(tmp); + ms_free(tmp); + return ret; +} + +bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){ + return lf->subscribe; +} + +LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf){ + return lf->pol; +} + +LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){ + return lf->status; +} + + +void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){ + if (fr->url==NULL) { + ms_warning("No sip url defined."); + return; + } + fr->lc=lc; + + if (fr->inc_subscribe_pending){ + switch(fr->pol){ + case LinphoneSPWait: + linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_PENDING,LINPHONE_STATUS_PENDING); + break; + case LinphoneSPAccept: + if (fr->lc!=NULL) + { + linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_ACTIVE,fr->lc->presence_mode); + } + break; + case LinphoneSPDeny: + linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED); + break; + } + fr->inc_subscribe_pending=FALSE; + } + if (fr->subscribe && fr->out_did==-1){ + + __linphone_friend_do_subscribe(fr); + } + ms_message("linphone_friend_apply() done."); +} + +void linphone_friend_edit(LinphoneFriend *fr){ +} + +void linphone_friend_done(LinphoneFriend *fr){ + ms_return_if_fail(fr!=NULL); + if (fr->lc==NULL) return; + linphone_friend_apply(fr,fr->lc); +} + +void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) +{ + ms_return_if_fail(lf->lc==NULL); + ms_return_if_fail(lf->url!=NULL); + linphone_friend_apply(lf,lc); + lc->friends=ms_list_append(lc->friends,lf); + return ; +} + +void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ + MSList *el=ms_list_find(lc->friends,(void *)fl); + if (el!=NULL){ + lc->friends=ms_list_remove_link(lc->friends,el); + linphone_friend_destroy((LinphoneFriend*)el->data); + } +} + +#define key_compare(key, word) strncasecmp((key),(word),strlen(key)) + +LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){ + if (key_compare("accept",pol)==0){ + return LinphoneSPAccept; + } + if (key_compare("deny",pol)==0){ + return LinphoneSPDeny; + } + if (key_compare("wait",pol)==0){ + return LinphoneSPWait; + } + ms_warning("Unrecognized subscribe policy: %s",pol); + return LinphoneSPWait; +} + +LinphoneProxyConfig *__index_to_proxy(LinphoneCore *lc, int index){ + if (index>=0) return (LinphoneProxyConfig*)ms_list_nth_data(lc->sip_conf.proxies,index); + else return NULL; +} + +LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int index){ + const char *tmp; + char item[50]; + int a; + LinphoneFriend *lf; + LpConfig *config=lc->config; + + sprintf(item,"friend_%i",index); + + if (!lp_config_has_section(config,item)){ + return NULL; + } + + tmp=lp_config_get_string(config,item,"url",NULL); + if (tmp==NULL) { + return NULL; + } + lf=linphone_friend_new_with_addr(tmp); + if (lf==NULL) { + return NULL; + } + tmp=lp_config_get_string(config,item,"pol",NULL); + if (tmp==NULL) linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPWait); + else{ + linphone_friend_set_inc_subscribe_policy(lf,__policy_str_to_enum(tmp)); + } + a=lp_config_get_int(config,item,"subscribe",0); + linphone_friend_send_subscribe(lf,a); + + a=lp_config_get_int(config,item,"proxy",-1); + if (a!=-1) { + linphone_friend_set_proxy(lf,__index_to_proxy(lc,a)); + } + return lf; +} + +const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){ + switch(pol){ + case LinphoneSPAccept: + return "accept"; + break; + case LinphoneSPDeny: + return "deny"; + break; + case LinphoneSPWait: + return "wait"; + break; + } + ms_warning("Invalid policy enum value."); + return "wait"; +} + +void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, int index){ + char key[50]; + char *tmp; + int a; + + sprintf(key,"friend_%i",index); + + if (lf==NULL){ + lp_config_clean_section(config,key); + return; + } + if (lf->url!=NULL){ + osip_from_to_str(lf->url,&tmp); + if (tmp==NULL) { + return; + } + lp_config_set_string(config,key,"url",tmp); + osip_free(tmp); + } + lp_config_set_string(config,key,"pol",__policy_enum_to_str(lf->pol)); + lp_config_set_int(config,key,"subscribe",lf->subscribe); + if (lf->proxy!=NULL){ + a=ms_list_index(lf->lc->sip_conf.proxies,lf->proxy); + lp_config_set_int(config,key,"proxy",a); + }else lp_config_set_int(config,key,"proxy",-1); +} diff --git a/linphone/coreapi/general_state.c b/linphone/coreapi/general_state.c new file mode 100644 index 000000000..b92a0fd75 --- /dev/null +++ b/linphone/coreapi/general_state.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * + * File: general_state.c + * + * Copyright (C) 2006, 2007 Thomas Reitmayr + * + **************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + ****************************************************************************/ + + +#include "linphonecore.h" + + +static gstate_t _gstates[GSTATE_GROUP_CALL+1]; + +#if 0 +static const char *_gstates_text[] = { + "GSTATE_POWER_OFF", /* 0 */ + "GSTATE_POWER_STARTUP", /* 1 */ + "GSTATE_POWER_ON", /* 2 */ + "GSTATE_POWER_SHUTDOWN", /* 3 */ + NULL, NULL, NULL, NULL, NULL, NULL, + + "GSTATE_REG_NONE", /* 10 */ + "GSTATE_REG_OK", /* 11 */ + "GSTATE_REG_FAILED", /* 12 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + "GSTATE_CALL_IDLE", /* 20 */ + "GSTATE_CALL_OUT_INVITE", /* 21 */ + "GSTATE_CALL_OUT_CONNECTED", /* 22 */ + "GSTATE_CALL_IN_INVITE", /* 23 */ + "GSTATE_CALL_IN_CONNECTED", /* 24 */ + "GSTATE_CALL_END", /* 25 */ + "GSTATE_CALL_ERROR" /* 26 */ +}; +#endif + +/* set the initial states */ +void gstate_initialize(void) { + _gstates[GSTATE_GROUP_POWER] = GSTATE_POWER_OFF; + _gstates[GSTATE_GROUP_REG] = GSTATE_REG_NONE; + _gstates[GSTATE_GROUP_CALL] = GSTATE_CALL_IDLE; +} + + +/* retrieve the current state of the specified state group */ +gstate_t gstate_get_state(gstate_group_t group) { + return _gstates[group]; +} + + +void gstate_new_state(struct _LinphoneCore *lc, + gstate_t new_state, + const char *message) { + LinphoneGeneralState states_arg; + + /* determine the affected group */ + if (new_state < GSTATE_REG_NONE) + states_arg.group = GSTATE_GROUP_POWER; + else if (new_state < GSTATE_CALL_IDLE) + states_arg.group = GSTATE_GROUP_REG; + else + states_arg.group = GSTATE_GROUP_CALL; + + /* store the new state while remembering the old one */ + states_arg.new_state = new_state; + states_arg.old_state = _gstates[states_arg.group]; + _gstates[states_arg.group] = new_state; + states_arg.message = message; + + /*printf("gstate_new_state: %s\t-> %s\t(%s)\n", + _gstates_text[states_arg.old_state], + _gstates_text[states_arg.new_state], + message);*/ + + /* call the virtual method */ + if (lc->vtable.general_state) + lc->vtable.general_state(lc, &states_arg); + + /* immediately proceed to idle state */ + if (new_state == GSTATE_CALL_END || + new_state == GSTATE_CALL_ERROR) + gstate_new_state(lc, GSTATE_CALL_IDLE, NULL); +} + diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c new file mode 100644 index 000000000..947dc535c --- /dev/null +++ b/linphone/coreapi/linphonecore.c @@ -0,0 +1,2261 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "lpconfig.h" +#include "private.h" +#include "mediastreamer2/mediastream.h" +#include +#include "sdphandler.h" + +#include +#include +#include "exevents.h" + + +#ifdef INET6 +#ifndef WIN32 +#include +#endif +#endif + +#ifdef WIN32 +#define HAVE_EXOSIP_GET_VERSION 1 +#endif + + +static const char *liblinphone_version=LIBLINPHONE_VERSION; + +#include "enum.h" + +void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result); +static void apply_nat_settings(LinphoneCore *lc); +static void toggle_video_preview(LinphoneCore *lc, bool_t val); + +/* relative path where is stored local ring*/ +#define LOCAL_RING "rings/oldphone.wav" +/* same for remote ring (ringback)*/ +#define REMOTE_RING_FR "ringback.wav" +#define REMOTE_RING_US "ringback.wav" + + +sdp_handler_t linphone_sdphandler={ + linphone_accept_audio_offer, /*from remote sdp */ + linphone_accept_video_offer, /*from remote sdp */ + linphone_set_audio_offer, /*to local sdp */ + linphone_set_video_offer, /*to local sdp */ + linphone_read_audio_answer, /*from incoming answer */ + linphone_read_video_answer /*from incoming answer */ +}; + +void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud) +{ + obj->_func=func; + obj->_user_data=ud; +} + +int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){ + if (obj->_func!=NULL) obj->_func(lc,obj->_user_data); + return 0; +} + +static void linphone_call_init_common(LinphoneCall *call, char *from, char *to){ + sdp_context_set_user_pointer(call->sdpctx,(void*)call); + call->state=LCStateInit; + call->start_time=time(NULL); + call->log=linphone_call_log_new(call, from, to); + linphone_core_notify_all_friends(call->core,LINPHONE_STATUS_ONTHEPHONE); +} + +void linphone_call_init_media_params(LinphoneCall *call){ + memset(&call->audio_params,0,sizeof(call->audio_params)); + memset(&call->video_params,0,sizeof(call->video_params)); +} + +static void discover_mtu(LinphoneCore *lc, const char *remote){ + int mtu; + if (lc->net_conf.mtu==0 ){ + /*attempt to discover mtu*/ + mtu=ms_discover_mtu(remote); + if (mtu>0){ + ms_set_mtu(mtu); + ms_message("Discovered mtu is %i, RTP payload max size is %i", + mtu, ms_get_payload_max_size()); + } + } +} + +LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_from_t *from, const osip_to_t *to) +{ + LinphoneCall *call=ms_new0(LinphoneCall,1); + char localip[LINPHONE_IPADDR_SIZE]; + char *fromstr=NULL,*tostr=NULL; + call->dir=LinphoneCallOutgoing; + call->cid=-1; + call->did=-1; + call->tid=-1; + call->core=lc; + linphone_core_get_local_ip(lc,to->url->host,localip); + call->sdpctx=sdp_handler_create_context(&linphone_sdphandler,localip,from->url->username,NULL); + osip_from_to_str(from,&fromstr); + osip_to_to_str(to,&tostr); + linphone_call_init_common(call,fromstr,tostr); + discover_mtu(lc,to->url->host); + return call; +} + + +LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, const char *from, const char *to, int cid, int did, int tid) +{ + char localip[LINPHONE_IPADDR_SIZE]; + LinphoneCall *call=ms_new0(LinphoneCall,1); + osip_from_t *me= linphone_core_get_primary_contact_parsed(lc); + osip_from_t *from_url=NULL; + call->dir=LinphoneCallIncoming; + call->cid=cid; + call->did=did; + call->tid=tid; + call->core=lc; + osip_from_init(&from_url); + osip_from_parse(from_url, from); + linphone_core_get_local_ip(lc,from_url->url->host,localip); + call->sdpctx=sdp_handler_create_context(&linphone_sdphandler,localip,me->url->username,NULL); + linphone_call_init_common(call, osip_strdup(from), osip_strdup(to)); + discover_mtu(lc,from_url->url->host); + osip_from_free(me); + osip_from_free(from_url); + return call; +} + +void linphone_call_destroy(LinphoneCall *obj) +{ + linphone_core_notify_all_friends(obj->core,obj->core->prev_mode); + linphone_call_log_completed(obj->log,obj); + if (obj->profile!=NULL && obj->profile!=obj->core->local_profile) rtp_profile_destroy(obj->profile); + if (obj->sdpctx!=NULL) sdp_context_free(obj->sdpctx); + ms_free(obj); +} + +/*prevent a gcc bug with %c*/ +static size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm){ + return strftime(s, max, fmt, tm); +} + +LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, char *from, char *to){ + LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1); + struct tm loctime; + cl->dir=call->dir; +#ifdef WIN32 + loctime=*localtime(&call->start_time); +#else + localtime_r(&call->start_time,&loctime); +#endif + my_strftime(cl->start_date,sizeof(cl->start_date),"%c",&loctime); + cl->from=from; + cl->to=to; + return cl; +} +void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call){ + LinphoneCore *lc=call->core; + calllog->duration=time(NULL)-call->start_time; + switch(call->state){ + case LCStateInit: + calllog->status=LinphoneCallAborted; + break; + case LCStateRinging: + if (calllog->dir==LinphoneCallIncoming){ + char *info; + calllog->status=LinphoneCallMissed; + lc->missed_calls++; + info=ortp_strdup_printf(_("You have missed %i call(s)."),lc->missed_calls); + lc->vtable.display_status(lc,info); + ms_free(info); + } + else calllog->status=LinphoneCallAborted; + break; + case LCStateAVRunning: + calllog->status=LinphoneCallSuccess; + break; + } + lc->call_logs=ms_list_append(lc->call_logs,(void *)calllog); + if (ms_list_size(lc->call_logs)>lc->max_call_logs){ + MSList *elem; + elem=lc->call_logs; + linphone_call_log_destroy((LinphoneCallLog*)elem->data); + lc->call_logs=ms_list_remove_link(lc->call_logs,elem); + } + if (lc->vtable.call_log_updated!=NULL){ + lc->vtable.call_log_updated(lc,calllog); + } +} + +char * linphone_call_log_to_str(LinphoneCallLog *cl){ + char *status; + switch(cl->status){ + case LinphoneCallAborted: + status=_("aborted"); + break; + case LinphoneCallSuccess: + status=_("completed"); + break; + case LinphoneCallMissed: + status=_("missed"); + break; + default: + status="unknown"; + } + return ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"), + (cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"), + cl->start_date, + cl->from, + cl->to, + status, + cl->duration/60, + cl->duration%60); +} + +void linphone_call_log_destroy(LinphoneCallLog *cl){ + if (cl->from!=NULL) osip_free(cl->from); + if (cl->to!=NULL) osip_free(cl->to); + ms_free(cl); +} + +void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){ + int ortp_level=ORTP_DEBUG; + switch(level){ + case OSIP_INFO1: + case OSIP_INFO2: + case OSIP_INFO3: + case OSIP_INFO4: + ortp_level=ORTP_MESSAGE; + break; + case OSIP_WARNING: + ortp_level=ORTP_WARNING; + break; + case OSIP_ERROR: + case OSIP_BUG: + ortp_level=ORTP_ERROR; + break; + case OSIP_FATAL: + ortp_level=ORTP_FATAL; + break; + case END_TRACE_LEVEL: + break; + } + if (ortp_log_level_enabled(level)){ + int len=strlen(chfr); + char *chfrdup=ortp_strdup(chfr); + /*need to remove endline*/ + if (len>1){ + if (chfrdup[len-1]=='\n') + chfrdup[len-1]='\0'; + if (chfrdup[len-2]=='\r') + chfrdup[len-2]='\0'; + } + ortp_logv(ortp_level,chfrdup,ap); + ortp_free(chfrdup); + } +} + + +void linphone_core_enable_logs(FILE *file){ + if (file==NULL) file=stdout; + ortp_set_log_file(file); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func); +} + +void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){ + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func); + ortp_set_log_handler(logfunc); +} + +void linphone_core_disable_logs(){ + int tl; + for (tl=0;tl<=OSIP_INFO4;tl++) osip_trace_disable_level(tl); + ortp_set_log_level_mask(ORTP_ERROR|ORTP_FATAL); +} + + +void +net_config_read (LinphoneCore *lc) +{ + int tmp; + const char *tmpstr; + LpConfig *config=lc->config; + + tmp=lp_config_get_int(config,"net","download_bw",0); + linphone_core_set_download_bandwidth(lc,tmp); + tmp=lp_config_get_int(config,"net","upload_bw",0); + linphone_core_set_upload_bandwidth(lc,tmp); + linphone_core_set_stun_server(lc,lp_config_get_string(config,"net","stun_server",NULL)); + tmpstr=lp_config_get_string(lc->config,"net","nat_address",NULL); + if (tmpstr!=NULL && (strlen(tmpstr)<1)) tmpstr=NULL; + linphone_core_set_nat_address(lc,tmpstr); + tmp=lp_config_get_int(lc->config,"net","firewall_policy",0); + linphone_core_set_firewall_policy(lc,tmp); + tmp=lp_config_get_int(lc->config,"net","nat_sdp_only",0); + lc->net_conf.nat_sdp_only=tmp; + tmp=lp_config_get_int(lc->config,"net","mtu",0); + linphone_core_set_mtu(lc,tmp); +} + + +void sound_config_read(LinphoneCore *lc) +{ + /*int tmp;*/ + const char *tmpbuf; + const char *devid; + const MSList *elem; + const char **devices; + int ndev; + int i; +#ifndef WIN32 + /*alsadev let the user use custom alsa device within linphone*/ + devid=lp_config_get_string(lc->config,"sound","alsadev",NULL); + if (devid){ + MSSndCard *card=ms_alsa_card_new_custom(devid,devid); + ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card); + } +#endif + /* retrieve all sound devices */ + elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get()); + ndev=ms_list_size(elem); + devices=ms_malloc((ndev+1)*sizeof(const char *)); + for (i=0;elem!=NULL;elem=elem->next,i++){ + devices[i]=ms_snd_card_get_string_id((MSSndCard *)elem->data); + } + devices[ndev]=NULL; + lc->sound_conf.cards=devices; + devid=lp_config_get_string(lc->config,"sound","playback_dev_id",NULL); + linphone_core_set_playback_device(lc,devid); + + devid=lp_config_get_string(lc->config,"sound","ringer_dev_id",NULL); + linphone_core_set_ringer_device(lc,devid); + + devid=lp_config_get_string(lc->config,"sound","capture_dev_id",NULL); + linphone_core_set_capture_device(lc,devid); + +/* + tmp=lp_config_get_int(lc->config,"sound","play_lev",80); + linphone_core_set_play_level(lc,tmp); + tmp=lp_config_get_int(lc->config,"sound","ring_lev",80); + linphone_core_set_ring_level(lc,tmp); + tmp=lp_config_get_int(lc->config,"sound","rec_lev",80); + linphone_core_set_rec_level(lc,tmp); + tmpbuf=lp_config_get_string(lc->config,"sound","source","m"); + linphone_core_set_sound_source(lc,tmpbuf[0]); +*/ + + tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING; + tmpbuf=lp_config_get_string(lc->config,"sound","local_ring",tmpbuf); + if (access(tmpbuf,F_OK)==-1) { + tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING; + } + if (strstr(tmpbuf,".wav")==NULL){ + /* it currently uses old sound files, so replace them */ + tmpbuf=PACKAGE_SOUND_DIR "/" LOCAL_RING; + } + + linphone_core_set_ring(lc,tmpbuf); + + tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING_FR; + tmpbuf=lp_config_get_string(lc->config,"sound","remote_ring",tmpbuf); + if (access(tmpbuf,F_OK)==-1){ + tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING_FR; + } + if (strstr(tmpbuf,".wav")==NULL){ + /* it currently uses old sound files, so replace them */ + tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING_FR; + } + linphone_core_set_ringback(lc,0); + check_sound_device(lc); + lc->sound_conf.latency=0; + + linphone_core_enable_echo_cancelation(lc, + lp_config_get_int(lc->config,"sound","echocancelation",0)); +} + +void sip_config_read(LinphoneCore *lc) +{ + char *contact; + const char *tmpstr; + int port; + int i,tmp; + int ipv6; + port=lp_config_get_int(lc->config,"sip","use_info",0); + linphone_core_set_use_info_for_dtmf(lc,port); + + ipv6=lp_config_get_int(lc->config,"sip","use_ipv6",-1); + if (ipv6==-1){ + ipv6=0; + if (host_has_ipv6_network()){ + lc->vtable.display_message(lc,_("Your machine appears to be connected to an IPv6 network. By default linphone always uses IPv4. Please update your configuration if you want to use IPv6")); + } + } + linphone_core_enable_ipv6(lc,ipv6); + port=lp_config_get_int(lc->config,"sip","sip_port",5060); + linphone_core_set_sip_port(lc,port); + + tmpstr=lp_config_get_string(lc->config,"sip","contact",NULL); + if (tmpstr==NULL || linphone_core_set_primary_contact(lc,tmpstr)==-1) { + char *hostname=getenv("HOST"); + char *username=getenv("USER"); + if (hostname==NULL) hostname=getenv("HOSTNAME"); + if (hostname==NULL) + hostname="unknown-host"; + if (username==NULL){ + username="toto"; + } + contact=ortp_strdup_printf("sip:%s@%s",username,hostname); + linphone_core_set_primary_contact(lc,contact); + ms_free(contact); + } + + tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1); + linphone_core_set_guess_hostname(lc,tmp); + + + tmp=lp_config_get_int(lc->config,"sip","inc_timeout",15); + linphone_core_set_inc_timeout(lc,tmp); + + /* get proxies config */ + for(i=0;; i++){ + LinphoneProxyConfig *cfg=linphone_proxy_config_new_from_config_file(lc->config,i); + if (cfg!=NULL){ + linphone_core_add_proxy_config(lc,cfg); + }else{ + break; + } + } + /* get the default proxy */ + tmp=lp_config_get_int(lc->config,"sip","default_proxy",-1); + linphone_core_set_default_proxy_index(lc,tmp); + + /* read authentication information */ + for(i=0;; i++){ + LinphoneAuthInfo *ai=linphone_auth_info_new_from_config_file(lc->config,i); + if (ai!=NULL){ + linphone_core_add_auth_info(lc,ai); + }else{ + break; + } + } + /*for test*/ + lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0); + +} + +void rtp_config_read(LinphoneCore *lc) +{ + int port; + int jitt_comp; + int nortp_timeout; + port=lp_config_get_int(lc->config,"rtp","audio_rtp_port",7078); + linphone_core_set_audio_port(lc,port); + + port=lp_config_get_int(lc->config,"rtp","video_rtp_port",9078); + if (port==0) port=9078; + linphone_core_set_video_port(lc,port); + + jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60); + linphone_core_set_audio_jittcomp(lc,jitt_comp); + jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60); + nortp_timeout=lp_config_get_int(lc->config,"rtp","nortp_timeout",30); + linphone_core_set_nortp_timeout(lc,nortp_timeout); +} + + +PayloadType * get_codec(LpConfig *config, char* type,int index){ + char codeckey[50]; + const char *mime,*fmtp; + int rate,enabled; + PayloadType *pt; + + snprintf(codeckey,50,"%s_%i",type,index); + mime=lp_config_get_string(config,codeckey,"mime",NULL); + if (mime==NULL || strlen(mime)==0 ) return NULL; + + pt=payload_type_new(); + pt->mime_type=ms_strdup(mime); + + rate=lp_config_get_int(config,codeckey,"rate",8000); + pt->clock_rate=rate; + fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL); + if (fmtp) pt->recv_fmtp=ms_strdup(fmtp); + enabled=lp_config_get_int(config,codeckey,"enabled",1); + if (enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED; + //ms_message("Found codec %s/%i",pt->mime_type,pt->clock_rate); + return pt; +} + +void codecs_config_read(LinphoneCore *lc) +{ + int i; + PayloadType *pt; + MSList *audio_codecs=NULL; + MSList *video_codecs=NULL; + for (i=0;;i++){ + pt=get_codec(lc->config,"audio_codec",i); + if (pt==NULL) break; + audio_codecs=ms_list_append(audio_codecs,(void *)pt); + } + for (i=0;;i++){ + pt=get_codec(lc->config,"video_codec",i); + if (pt==NULL) break; + video_codecs=ms_list_append(video_codecs,(void *)pt); + } + linphone_core_set_audio_codecs(lc,audio_codecs); + linphone_core_set_video_codecs(lc,video_codecs); + linphone_core_setup_local_rtp_profile(lc); +} + +void video_config_read(LinphoneCore *lc) +{ + int capture, display; + int enabled; + const char *str; + int ndev; + const char **devices; + const MSList *elem; + int i; + + /* retrieve all video devices */ + elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get()); + ndev=ms_list_size(elem); + devices=ms_malloc((ndev+1)*sizeof(const char *)); + for (i=0;elem!=NULL;elem=elem->next,i++){ + devices[i]=ms_web_cam_get_string_id((MSWebCam *)elem->data); + } + devices[ndev]=NULL; + lc->video_conf.cams=devices; + + str=lp_config_get_string(lc->config,"video","device",NULL); + if (str && str[0]==0) str=NULL; + linphone_core_set_video_device(lc,str); + + enabled=lp_config_get_int(lc->config,"video","enabled",1); + capture=lp_config_get_int(lc->config,"video","capture",enabled); + display=lp_config_get_int(lc->config,"video","display",enabled); +#ifdef VIDEO_ENABLED + linphone_core_enable_video(lc,capture,display); +#endif +} + +void ui_config_read(LinphoneCore *lc) +{ + LinphoneFriend *lf; + int i; + for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){ + linphone_core_add_friend(lc,lf); + } + +} + +void autoreplier_config_init(LinphoneCore *lc) +{ + autoreplier_config_t *config=&lc->autoreplier_conf; + config->enabled=lp_config_get_int(lc->config,"autoreplier","enabled",0); + config->after_seconds=lp_config_get_int(lc->config,"autoreplier","after_seconds",6); + config->max_users=lp_config_get_int(lc->config,"autoreplier","max_users",1); + config->max_rec_time=lp_config_get_int(lc->config,"autoreplier","max_rec_time",60); + config->max_rec_msg=lp_config_get_int(lc->config,"autoreplier","max_rec_msg",10); + config->message=lp_config_get_string(lc->config,"autoreplier","message",NULL); +} + +void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){ + lc->net_conf.download_bw=bw; + if (bw==0){ /*infinite*/ + lc->dw_audio_bw=-1; + lc->dw_video_bw=-1; + }else { + if (bw>=256){ + lc->dw_audio_bw=80; + }else if (bw>=128){ + if (linphone_core_video_enabled(lc)) + lc->dw_audio_bw=30; + else + lc->dw_audio_bw=bw; + }else{ + lc->dw_audio_bw=bw; + } + lc->dw_video_bw=bw-lc->dw_audio_bw; + } +} + +void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){ + lc->net_conf.upload_bw=bw; + if (bw==0){ /*infinite*/ + lc->up_audio_bw=-1; + lc->up_video_bw=-1; + return; + }else if (bw>=128){ + if (linphone_core_video_enabled(lc)) + lc->up_audio_bw=lc->audio_bw; + else + lc->up_audio_bw=bw; + }else{ + lc->up_audio_bw=bw; + } + lc->up_video_bw=bw-lc->up_audio_bw-10;/*-10: security margin*/ +} + +int linphone_core_get_download_bandwidth(const LinphoneCore *lc){ + return lc->net_conf.download_bw; +} + +int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){ + return lc->net_conf.upload_bw; +} + +const char * linphone_core_get_version(void){ + return liblinphone_version; +} + +#ifdef VIDEO_ENABLED + +static PayloadType * payload_type_h264_packetization_mode_1=NULL; +static PayloadType * linphone_h263_1998=NULL; +static PayloadType * linphone_mp4v_es=NULL; +#endif + +void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path, void * userdata) +{ + memset (lc, 0, sizeof (LinphoneCore)); + lc->data=userdata; + + memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable)); + + gstate_initialize(); + gstate_new_state(lc, GSTATE_POWER_STARTUP, NULL); + + ortp_init(); + rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015); + rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb); + rtp_profile_set_payload(&av_profile,111,&payload_type_speex_wb); + rtp_profile_set_payload(&av_profile,112,&payload_type_ilbc); + rtp_profile_set_payload(&av_profile,116,&payload_type_truespeech); + rtp_profile_set_payload(&av_profile,101,&payload_type_telephone_event); + +#ifdef VIDEO_ENABLED + rtp_profile_set_payload(&av_profile,97,&payload_type_theora); + + linphone_h263_1998=payload_type_clone(&payload_type_h263_1998); + payload_type_set_recv_fmtp(linphone_h263_1998,"CIF=1;QCIF=1"); + rtp_profile_set_payload(&av_profile,98,linphone_h263_1998); + + linphone_mp4v_es=payload_type_clone(&payload_type_mp4v); + payload_type_set_recv_fmtp(linphone_mp4v_es,"profile-level-id=3"); + rtp_profile_set_payload(&av_profile,99,linphone_mp4v_es); + rtp_profile_set_payload(&av_profile,100,&payload_type_x_snow); + payload_type_h264_packetization_mode_1=payload_type_clone(&payload_type_h264); + payload_type_set_recv_fmtp(payload_type_h264_packetization_mode_1,"packetization-mode=1"); + rtp_profile_set_payload(&av_profile,103,payload_type_h264_packetization_mode_1); + rtp_profile_set_payload(&av_profile,102,&payload_type_h264); +#endif + + ms_init(); + + lc->config=lp_config_new(config_path); + +#ifdef VINCENT_MAURY_RSVP + /* default qos parameters : rsvp on, rpc off */ + lc->rsvp_enable = 1; + lc->rpc_enable = 0; +#endif + sound_config_read(lc); + net_config_read(lc); + rtp_config_read(lc); + codecs_config_read(lc); + sip_config_read(lc); /* this will start eXosip*/ + video_config_read(lc); + //autoreplier_config_init(&lc->autoreplier_conf); + lc->prev_mode=LINPHONE_STATUS_ONLINE; + lc->presence_mode=LINPHONE_STATUS_ONLINE; + lc->max_call_logs=15; + ui_config_read(lc); + ms_mutex_init(&lc->lock,NULL); + lc->vtable.display_status(lc,_("Ready")); + gstate_new_state(lc, GSTATE_POWER_ON, NULL); +} + +LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, + const char *config_path, void * userdata) +{ + LinphoneCore *core=ms_new(LinphoneCore,1); + linphone_core_init(core,vtable,config_path,userdata); + return core; +} + +const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc) +{ + return lc->codecs_conf.audio_codecs; +} + +const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc) +{ + return lc->codecs_conf.video_codecs; +} + +int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact) +{ + osip_from_t *ctt=NULL; + osip_from_init(&ctt); + if (osip_from_parse(ctt,contact)!=0){ + ms_error("Bad contact url: %s",contact); + osip_from_free(ctt); + return -1; + } + if (lc->sip_conf.contact!=NULL) ms_free(lc->sip_conf.contact); + lc->sip_conf.contact=ms_strdup(contact); + if (lc->sip_conf.guessed_contact!=NULL){ + ms_free(lc->sip_conf.guessed_contact); + lc->sip_conf.guessed_contact=NULL; + } + osip_from_free(ctt); + return 0; +} + +static bool_t stun_get_localip(LinphoneCore *lc, char *result, int *port){ + const char *server=linphone_core_get_stun_server(lc); + StunAddress4 addr; + StunAddress4 mapped; + StunAddress4 changed; + if (server!=NULL){ + if (stunParseServerName((char*)server,&addr)){ + if (lc->vtable.display_status!=NULL) + lc->vtable.display_status(lc,_("Stun lookup in progress...")); + if (stunTest(&addr,1,TRUE,NULL,&mapped,&changed)==0){ + struct in_addr inaddr; + char *tmp; + inaddr.s_addr=ntohl(mapped.addr); + tmp=inet_ntoa(inaddr); + *port=ntohs(mapped.port); + strncpy(result,tmp,LINPHONE_IPADDR_SIZE); + if (lc->vtable.display_status!=NULL) + lc->vtable.display_status(lc,_("Stun lookup done...")); + ms_message("Stun server says we have address %s:i",result,*port); + return TRUE; + }else{ + ms_warning("stun lookup failed."); + } + }else{ + ms_warning("Fail to resolv or parse %s",server); + } + } + return FALSE; +} + +/*result must be an array of chars at least LINPHONE_IPADDR_SIZE */ +void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result){ + if (lc->apply_nat_settings){ + apply_nat_settings(lc); + lc->apply_nat_settings=FALSE; + } + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_NAT_ADDRESS){ + strncpy(result,linphone_core_get_nat_address(lc),LINPHONE_IPADDR_SIZE); + return; + } + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_STUN) { + if (lc->sip_conf.ipv6_enabled){ + ms_warning("stun support is not implemented for ipv6"); + }else{ + int mport=0; + ms_message("doing stun lookup for local address..."); + if (stun_get_localip(lc,result,&mport)){ + if (!lc->net_conf.nat_sdp_only) + eXosip_masquerade_contact(result,mport); + return; + } + ms_warning("stun lookup failed, falling back to a local interface..."); + } + + } + if (eXosip_guess_localip(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE)<0){ + /*default to something */ + strncpy(result,lc->sip_conf.ipv6_enabled ? "::1" : "127.0.0.1",LINPHONE_IPADDR_SIZE); + ms_error("Could not find default routable ip address !"); + } + eXosip_masquerade_contact("",0); +} + +const char *linphone_core_get_primary_contact(LinphoneCore *lc) +{ + char *identity; + char tmp[LINPHONE_IPADDR_SIZE]; + if (lc->sip_conf.guess_hostname){ + if (lc->sip_conf.guessed_contact==NULL || lc->sip_conf.loopback_only){ + char *guessed=NULL; + osip_from_t *url; + if (lc->sip_conf.guessed_contact!=NULL){ + ms_free(lc->sip_conf.guessed_contact); + lc->sip_conf.guessed_contact=NULL; + } + + osip_from_init(&url); + if (osip_from_parse(url,lc->sip_conf.contact)==0){ + + }else ms_error("Could not parse identity contact !"); + linphone_core_get_local_ip(lc, NULL, tmp); + if (strcmp(tmp,"127.0.0.1")==0 || strcmp(tmp,"::1")==0 ){ + ms_warning("Local loopback network only !"); + lc->sip_conf.loopback_only=TRUE; + }else lc->sip_conf.loopback_only=FALSE; + osip_free(url->url->host); + url->url->host=osip_strdup(tmp); + if (url->url->port!=NULL){ + osip_free(url->url->port); + url->url->port=NULL; + } + if (lc->sip_conf.sip_port!=5060){ + url->url->port=ortp_strdup_printf("%i",lc->sip_conf.sip_port); + } + osip_from_to_str(url,&guessed); + lc->sip_conf.guessed_contact=guessed; + + osip_from_free(url); + + } + identity=lc->sip_conf.guessed_contact; + }else{ + identity=lc->sip_conf.contact; + } + return identity; +} + +void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val){ + lc->sip_conf.guess_hostname=val; +} + +bool_t linphone_core_get_guess_hostname(LinphoneCore *lc){ + return lc->sip_conf.guess_hostname; +} + +osip_from_t *linphone_core_get_primary_contact_parsed(LinphoneCore *lc){ + int err; + osip_from_t *contact; + osip_from_init(&contact); + err=osip_from_parse(contact,linphone_core_get_primary_contact(lc)); + if (err<0) { + osip_from_free(contact); + return NULL; + } + return contact; +} + +int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs) +{ + if (lc->codecs_conf.audio_codecs!=NULL) ms_list_free(lc->codecs_conf.audio_codecs); + lc->codecs_conf.audio_codecs=codecs; + return 0; +} + +int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs) +{ + if (lc->codecs_conf.video_codecs!=NULL) ms_list_free(lc->codecs_conf.video_codecs); + lc->codecs_conf.video_codecs=codecs; + return 0; +} + +const MSList * linphone_core_get_friend_list(LinphoneCore *lc) +{ + return lc->friends; +} + +int linphone_core_get_audio_jittcomp(LinphoneCore *lc) +{ + return lc->rtp_conf.audio_jitt_comp; +} + +int linphone_core_get_audio_port(const LinphoneCore *lc) +{ + return lc->rtp_conf.audio_rtp_port; +} + +int linphone_core_get_video_port(const LinphoneCore *lc){ + return lc->rtp_conf.video_rtp_port; +} + +int linphone_core_get_nortp_timeout(const LinphoneCore *lc){ + return lc->rtp_conf.nortp_timeout; +} + +void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value) +{ + lc->rtp_conf.audio_jitt_comp=value; +} + +void linphone_core_set_audio_port(LinphoneCore *lc, int port) +{ + lc->rtp_conf.audio_rtp_port=port; +} + +void linphone_core_set_video_port(LinphoneCore *lc, int port){ + lc->rtp_conf.video_rtp_port=port; +} + +void linphone_core_set_nortp_timeout(LinphoneCore *lc, int nortp_timeout){ + lc->rtp_conf.nortp_timeout=nortp_timeout; +} + +bool_t linphone_core_get_use_info_for_dtmf(LinphoneCore *lc) +{ + return lc->sip_conf.use_info; +} + +void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc,bool_t use_info) +{ + lc->sip_conf.use_info=use_info; +} + +int linphone_core_get_sip_port(LinphoneCore *lc) +{ + return lc->sip_conf.sip_port; +} + +static bool_t exosip_running=FALSE; + +void linphone_core_set_sip_port(LinphoneCore *lc,int port) +{ + const char *anyaddr; + char ua_string[256]; + int err=0; + if (port==lc->sip_conf.sip_port) return; + lc->sip_conf.sip_port=port; + if (exosip_running) eXosip_quit(); + eXosip_init(); + eXosip_enable_ipv6(lc->sip_conf.ipv6_enabled); + if (lc->sip_conf.ipv6_enabled) + anyaddr="::0"; + else + anyaddr="0.0.0.0"; + err=eXosip_listen_addr (IPPROTO_UDP, anyaddr, port, + lc->sip_conf.ipv6_enabled ? PF_INET6 : PF_INET, 0); + if (err<0){ + char *msg=ortp_strdup_printf("UDP port %i seems already in use ! Cannot initialize.",port); + ms_warning(msg); + lc->vtable.display_warning(lc,msg); + ms_free(msg); + return; + } +#ifdef VINCENT_MAURY_RSVP + /* tell exosip the qos settings according to default linphone parameters */ + eXosip_set_rsvp_mode (lc->rsvp_enable); + eXosip_set_rpc_mode (lc->rpc_enable); +#endif + snprintf(ua_string,sizeof(ua_string),"Linphone/%s (eXosip2/%s)",LINPHONE_VERSION, +#ifdef HAVE_EXOSIP_GET_VERSION + eXosip_get_version() +#else + "unknown" +#endif +); + eXosip_set_user_agent(ua_string); + exosip_running=TRUE; +} + +bool_t linphone_core_ipv6_enabled(LinphoneCore *lc){ + return lc->sip_conf.ipv6_enabled; +} +void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){ + if (lc->sip_conf.ipv6_enabled!=val){ + lc->sip_conf.ipv6_enabled=val; + if (exosip_running){ + /* we need to restart eXosip */ + linphone_core_set_sip_port(lc, lc->sip_conf.sip_port); + } + } +} + +static void display_bandwidth(RtpSession *as, RtpSession *vs){ + ms_message("bandwidth usage: audio=[d=%.1f,u=%.1f] video=[d=%.1f,u=%.1f] kbit/sec", + (as!=NULL) ? (rtp_session_compute_recv_bandwidth(as)*1e-3) : 0, + (as!=NULL) ? (rtp_session_compute_send_bandwidth(as)*1e-3) : 0, + (vs!=NULL) ? (rtp_session_compute_recv_bandwidth(vs)*1e-3) : 0, + (vs!=NULL) ? (rtp_session_compute_send_bandwidth(vs)*1e-3) : 0); +} + +static void linphone_core_disconnected(LinphoneCore *lc){ + lc->vtable.display_warning(lc,_("Remote end seems to have disconnected, the call is going to be closed.")); + linphone_core_terminate_call(lc,NULL); +} + +void linphone_core_iterate(LinphoneCore *lc) +{ + eXosip_event_t *ev; + bool_t disconnected=FALSE; + int disconnect_timeout = linphone_core_get_nortp_timeout(lc); + if (lc->preview_finished){ + lc->preview_finished=0; + ring_stop(lc->ringstream); + lc->ringstream=NULL; + lc_callback_obj_invoke(&lc->preview_finished_cb,lc); + } + + if (exosip_running){ + while((ev=eXosip_event_wait(0,0))!=NULL){ + linphone_core_process_event(lc,ev); + } + if (lc->automatic_action==0) eXosip_automatic_action(); + } + if (lc->call!=NULL){ + LinphoneCall *call=lc->call; + int elapsed; + time_t curtime=time(NULL); + if (call->dir==LinphoneCallIncoming && call->state==LCStateRinging){ + elapsed=curtime-call->start_time; + ms_message("incoming call ringing for %i seconds",elapsed); + if (elapsed>lc->sip_conf.inc_timeout){ + linphone_core_terminate_call(lc,NULL); + } + }else if (call->state==LCStateAVRunning){ + elapsed=curtime-lc->prevtime; + if (elapsed>=1){ + RtpSession *as=NULL,*vs=NULL; + lc->prevtime=curtime; + if (lc->audiostream!=NULL) + as=lc->audiostream->session; + if (lc->videostream!=NULL) + vs=lc->videostream->session; + display_bandwidth(as,vs); + } +#ifdef VIDEO_ENABLED + if (lc->videostream!=NULL) + video_stream_iterate(lc->videostream); +#endif + if (lc->audiostream!=NULL && disconnect_timeout>0) + disconnected=!audio_stream_alive(lc->audiostream,disconnect_timeout); + } + } + if (linphone_core_video_preview_enabled(lc)){ + if (lc->previewstream==NULL) + toggle_video_preview(lc,TRUE); +#ifdef VIDEO_ENABLED + else video_stream_iterate(lc->previewstream); +#endif + }else{ + if (lc->previewstream!=NULL) + toggle_video_preview(lc,FALSE); + } + if (disconnected) + linphone_core_disconnected(lc); +} + + +bool_t linphone_core_is_in_main_thread(LinphoneCore *lc){ + return TRUE; +} + +static osip_to_t *osip_to_create(const char *to){ + osip_to_t *ret; + osip_to_init(&ret); + if (osip_to_parse(ret,to)<0){ + osip_to_free(ret); + return NULL; + } + return ret; +} + +bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, char **real_url, osip_to_t **real_parsed_url, char **route){ + enum_lookup_res_t *enumres=NULL; + osip_to_t *parsed_url=NULL; + char *enum_domain=NULL; + LinphoneProxyConfig *proxy; + char *tmpurl; + const char *tmproute; + if (real_url!=NULL) *real_url=NULL; + if (real_parsed_url!=NULL) *real_parsed_url=NULL; + *route=NULL; + tmproute=linphone_core_get_route(lc); + + if (is_enum(url,&enum_domain)){ + lc->vtable.display_status(lc,_("Looking for telephone number destination...")); + if (enum_lookup(enum_domain,&enumres)<0){ + lc->vtable.display_status(lc,_("Could not resolve this number.")); + ms_free(enum_domain); + return FALSE; + } + ms_free(enum_domain); + tmpurl=enumres->sip_address[0]; + if (real_url!=NULL) *real_url=ms_strdup(tmpurl); + if (real_parsed_url!=NULL) *real_parsed_url=osip_to_create(tmpurl); + enum_lookup_res_free(enumres); + if (tmproute) *route=ms_strdup(tmproute); + return TRUE; + } + /* check if we have a "sip:" */ + if (strstr(url,"sip:")==NULL){ + /* this doesn't look like a true sip uri */ + proxy=lc->default_proxy; + if (proxy!=NULL){ + /* append the proxy domain suffix */ + osip_from_t *uri; + char *sipaddr; + const char *identity=linphone_proxy_config_get_identity(proxy); + osip_from_init(&uri); + if (osip_from_parse(uri,identity)<0){ + osip_from_free(uri); + return FALSE; + } + sipaddr=ortp_strdup_printf("sip:%s@%s",url,uri->url->host); + if (real_parsed_url!=NULL) *real_parsed_url=osip_to_create(sipaddr); + if (real_url!=NULL) *real_url=sipaddr; + else ms_free(sipaddr); + /*if the prompted uri was auto-suffixed with proxy domain, + then automatically set a route so that the request goes + through the proxy*/ + if (tmproute==NULL){ + osip_route_t *rt=NULL; + char *rtstr=NULL; + osip_route_init(&rt); + if (osip_route_parse(rt,linphone_proxy_config_get_addr(proxy))==0){ + osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL); + osip_route_to_str(rt,&rtstr); + *route=ms_strdup(rtstr); + osip_free(rtstr); + } + ms_message("setting automatically a route to %s",*route); + } + else *route=ms_strdup(tmproute); + return TRUE; + } + } + parsed_url=osip_to_create(url); + if (parsed_url!=NULL){ + if (real_url!=NULL) *real_url=ms_strdup(url); + if (real_parsed_url!=NULL) *real_parsed_url=parsed_url; + else osip_to_free(parsed_url); + if (tmproute) *route=ms_strdup(tmproute); + return TRUE; + } + /* else we could not do anything with url given by user, so display an error */ + if (lc->vtable.display_warning!=NULL){ + lc->vtable.display_warning(lc,_("Could not parse given sip address. A sip url usually looks like sip:user@domain")); + } + return FALSE; +} + +const char * linphone_core_get_identity(LinphoneCore *lc){ + LinphoneProxyConfig *proxy=NULL; + const char *from; + linphone_core_get_default_proxy(lc,&proxy); + if (proxy!=NULL) { + from=linphone_proxy_config_get_identity(proxy); + }else from=linphone_core_get_primary_contact(lc); + return from; +} + +const char * linphone_core_get_route(LinphoneCore *lc){ + LinphoneProxyConfig *proxy=NULL; + const char *route=NULL; + linphone_core_get_default_proxy(lc,&proxy); + if (proxy!=NULL) { + route=linphone_proxy_config_get_route(proxy); + } + return route; +} + +void linphone_set_sdp(osip_message_t *sip, const char *sdpmesg){ + int sdplen=strlen(sdpmesg); + char clen[10]; + snprintf(clen,sizeof(clen),"%i",sdplen); + osip_message_set_body(sip,sdpmesg,sdplen); + osip_message_set_content_type(sip,"application/sdp"); + osip_message_set_content_length(sip,clen); +} + +int linphone_core_invite(LinphoneCore *lc, const char *url) +{ + char *barmsg; + int err=0; + char *sdpmesg=NULL; + char *route=NULL; + const char *from=NULL; + osip_message_t *invite=NULL; + sdp_context_t *ctx=NULL; + LinphoneProxyConfig *proxy=NULL; + osip_from_t *parsed_url2=NULL; + osip_to_t *real_parsed_url=NULL; + char *real_url=NULL; + + if (lc->call!=NULL){ + lc->vtable.display_warning(lc,_("Sorry, having multiple simultaneous calls is not supported yet !")); + return -1; + } + + gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, url); + linphone_core_get_default_proxy(lc,&proxy); + if (!linphone_core_interpret_url(lc,url,&real_url,&real_parsed_url,&route)){ + /* bad url */ + gstate_new_state(lc, GSTATE_CALL_ERROR, NULL); + return -1; + } + barmsg=ortp_strdup_printf("%s %s", _("Contacting"), real_url); + lc->vtable.display_status(lc,barmsg); + ms_free(barmsg); + if (proxy!=NULL) { + from=linphone_proxy_config_get_identity(proxy); + + } + /* if no proxy or no identity defined for this proxy, default to primary contact*/ + if (from==NULL) from=linphone_core_get_primary_contact(lc); + + err=eXosip_call_build_initial_invite(&invite,real_url,from, + route,"Phone call"); + + if (err<0){ + ms_warning("Could not build initial invite"); + goto end; + } + + /* make sdp message */ + + osip_from_init(&parsed_url2); + osip_from_parse(parsed_url2,from); + + lc->call=linphone_call_new_outgoing(lc,parsed_url2,real_parsed_url); + if (!lc->sip_conf.sdp_200_ack){ + ctx=lc->call->sdpctx; + lc->call->profile=lc->local_profile; + sdpmesg=sdp_context_get_offer(ctx); + linphone_set_sdp(invite,sdpmesg); + linphone_core_init_media_streams(lc); + } + eXosip_lock(); + err=eXosip_call_send_initial_invite(invite); + lc->call->cid=err; + eXosip_unlock(); + if (err<0){ + ms_warning("Could not initiate call."); + lc->vtable.display_status(lc,_("could not call")); + linphone_call_destroy(lc->call); + lc->call=NULL; + linphone_core_stop_media_streams(lc); + } + + goto end; + end: + if (real_url!=NULL) ms_free(real_url); + if (real_parsed_url!=NULL) osip_to_free(real_parsed_url); + if (parsed_url2!=NULL) osip_from_free(parsed_url2); + if (err<0) + gstate_new_state(lc, GSTATE_CALL_ERROR, NULL); + if (route!=NULL) ms_free(route); + return (err<0) ? -1 : 0; +} + +int linphone_core_refer(LinphoneCore *lc, const char *url) +{ + char *real_url=NULL; + osip_to_t *real_parsed_url=NULL; + LinphoneCall *call; + osip_message_t *msg=NULL; + char *route; + if (!linphone_core_interpret_url(lc,url,&real_url,&real_parsed_url, &route)){ + /* bad url */ + return -1; + } + if (route!=NULL) ms_free(route); + call=lc->call; + if (call==NULL){ + ms_warning("No established call to refer."); + return -1; + } + lc->call=NULL; + eXosip_call_build_refer(call->did, real_url, &msg); + eXosip_lock(); + eXosip_call_send_request(call->did, msg); + eXosip_unlock(); + return 0; +} + +bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ + if (lc->call!=NULL && lc->call->dir==LinphoneCallIncoming){ + return TRUE; + } + return FALSE; +} + +#ifdef VINCENT_MAURY_RSVP +/* on=1 for RPC_ENABLE=1...*/ +int linphone_core_set_rpc_mode(LinphoneCore *lc, int on) +{ + if (on==1) + printf("RPC_ENABLE set on\n"); + else + printf("RPC_ENABLE set off\n"); + lc->rpc_enable = (on==1); + /* need to tell eXosip the new setting */ + if (eXosip_set_rpc_mode (lc->rpc_enable)!=0) + return -1; + return 0; +} + +/* on=1 for RSVP_ENABLE=1...*/ +int linphone_core_set_rsvp_mode(LinphoneCore *lc, int on) +{ + if (on==1) + printf("RSVP_ENABLE set on\n"); + else + printf("RSVP_ENABLE set off\n"); + lc->rsvp_enable = (on==1); + /* need to tell eXosip the new setting */ + if (eXosip_set_rsvp_mode (lc->rsvp_enable)!=0) + return -1; + return 0; +} + +/* answer : 1 for yes, 0 for no */ +int linphone_core_change_qos(LinphoneCore *lc, int answer) +{ + char *sdpmesg; + if (lc->call==NULL){ + return -1; + } + + if (lc->rsvp_enable && answer==1) + { + /* answer is yes, local setting is with qos, so + * the user chose to continue with no qos ! */ + /* so switch in normal mode : ring and 180 */ + lc->rsvp_enable = 0; /* no more rsvp */ + eXosip_set_rsvp_mode (lc->rsvp_enable); + /* send 180 */ + eXosip_lock(); + eXosip_answer_call(lc->call->did,180,NULL); + eXosip_unlock(); + /* play the ring */ + ms_message("Starting local ring..."); + lc->ringstream=ring_start(lc->sound_conf.local_ring, + 2000,ms_snd_card_manager_get_card(ms_snd_card_manager_get(),lc->sound_conf.ring_sndcard)); + } + else if (!lc->rsvp_enable && answer==1) + { + /* switch to QoS mode on : answer 183 session progress */ + lc->rsvp_enable = 1; + eXosip_set_rsvp_mode (lc->rsvp_enable); + /* take the sdp already computed, see osipuacb.c */ + sdpmesg=lc->call->sdpctx->answerstr; + eXosip_lock(); + eXosip_answer_call_with_body(lc->call->did,183,"application/sdp",sdpmesg); + eXosip_unlock(); + } + else + { + /* decline offer (603) */ + linphone_core_terminate_call(lc, NULL); + } + return 0; +} +#endif + +void linphone_core_init_media_streams(LinphoneCore *lc){ + lc->audiostream=audio_stream_new(linphone_core_get_audio_port(lc),linphone_core_ipv6_enabled(lc)); +#ifdef VIDEO_ENABLED + lc->videostream=video_stream_new(linphone_core_get_video_port(lc),linphone_core_ipv6_enabled(lc)); +#else + lc->videostream=NULL; +#endif +} + +void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){ + osip_from_t *me=linphone_core_get_primary_contact_parsed(lc); + const char *tool="linphone-" LINPHONE_VERSION; + /* adjust rtp jitter compensation. It must be at least the latency of the sound card */ + int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp); + char *cname=ortp_strdup_printf("%s@%s",me->url->username,me->url->host); + { + StreamParams *audio_params=&call->audio_params; + if (!lc->use_files){ + MSSndCard *playcard=lc->sound_conf.play_sndcard; + MSSndCard *captcard=lc->sound_conf.capt_sndcard; + if (playcard==NULL) { + ms_warning("No card defined for playback !"); + goto end; + } + if (captcard==NULL) { + ms_warning("No card defined for capture !"); + goto end; + } + if (audio_params->relay_session_id!=NULL) + audio_stream_set_relay_session_id(lc->audiostream,audio_params->relay_session_id); + audio_stream_start_now( + lc->audiostream, + call->profile, + audio_params->remoteaddr, + audio_params->remoteport, + audio_params->remotertcpport, + audio_params->pt, + jitt_comp, + playcard, + captcard, + linphone_core_echo_cancelation_enabled(lc)); + }else{ + audio_stream_start_with_files( + lc->audiostream, + call->profile, + audio_params->remoteaddr, + audio_params->remoteport, + audio_params->remotertcpport, + audio_params->pt, + 100, + lc->play_file, + lc->rec_file); + } + audio_stream_set_rtcp_information(lc->audiostream, cname, tool); + } +#ifdef VIDEO_ENABLED + { + /* shutdown preview */ + if (lc->previewstream!=NULL) { + video_preview_stop(lc->previewstream); + lc->previewstream=NULL; + } + if (lc->video_conf.display || lc->video_conf.capture) { + StreamParams *video_params=&call->video_params; + + if (video_params->remoteport>0){ + if (video_params->relay_session_id!=NULL) + video_stream_set_relay_session_id(lc->videostream,video_params->relay_session_id); + if (lc->video_conf.display && lc->video_conf.capture) + video_stream_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->remotertcpport, + video_params->pt, jitt_comp, lc->video_conf.device); + else if (lc->video_conf.display) + video_stream_recv_only_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->pt, jitt_comp); + else if (lc->video_conf.capture) + video_stream_send_only_start(lc->videostream, + call->profile, video_params->remoteaddr, video_params->remoteport, + video_params->remotertcpport, + video_params->pt, jitt_comp, lc->video_conf.device); + video_stream_set_rtcp_information(lc->videostream, cname,tool); + } + } + } +#endif + goto end; + end: + ms_free(cname); + osip_from_free(me); + lc->call->state=LCStateAVRunning; +} + +void linphone_core_stop_media_streams(LinphoneCore *lc){ + if (lc->audiostream!=NULL) { + audio_stream_stop(lc->audiostream); + lc->audiostream=NULL; + } +#ifdef VIDEO_ENABLED + if (lc->videostream!=NULL){ + if (lc->video_conf.display && lc->video_conf.capture) + video_stream_stop(lc->videostream); + else if (lc->video_conf.display) + video_stream_recv_only_stop(lc->videostream); + else if (lc->video_conf.capture) + video_stream_send_only_stop(lc->videostream); + lc->videostream=NULL; + } + if (linphone_core_video_preview_enabled(lc)){ + if (lc->previewstream==NULL){ + lc->previewstream=video_preview_start(lc->video_conf.device); + } + } +#endif +} + +int linphone_core_accept_call(LinphoneCore *lc, const char *url) +{ + char *sdpmesg; + osip_message_t *msg=NULL; + LinphoneCall *call=lc->call; + int err; + bool_t offering=FALSE; + + if (call==NULL){ + return -1; + } + + if (lc->call->state==LCStateAVRunning){ + /*call already accepted*/ + return -1; + } + + /*stop ringing */ + if (lc->ringstream!=NULL) { + ms_message("stop ringing"); + ring_stop(lc->ringstream); + ms_message("ring stopped"); + lc->ringstream=NULL; + } + /* sends a 200 OK */ + err=eXosip_call_build_answer(call->tid,200,&msg); + if (err<0 || msg==NULL){ + ms_error("Fail to build answer for call: err=%i",err); + return -1; + } + ms_message("eXosip_call_build_answer done"); + /*if a sdp answer is computed, send it, else send an offer */ + sdpmesg=call->sdpctx->answerstr; + if (sdpmesg==NULL){ + offering=TRUE; + call->profile=lc->local_profile; + ms_message("generating sdp offer"); + sdpmesg=sdp_context_get_offer(call->sdpctx); + + if (sdpmesg==NULL){ + ms_error("fail to generate sdp offer !"); + return -1; + } + ms_message("sdp message generated (sdpmesg=%p):\n%s",sdpmesg,sdpmesg); + linphone_set_sdp(msg,sdpmesg); + ms_message("sdp message attached to SIP answer"); + linphone_core_init_media_streams(lc); + ms_message("init_media_streams done"); + }else{ + linphone_set_sdp(msg,sdpmesg); + } + eXosip_lock(); + ms_message("eXosip_lock() done"); + eXosip_call_send_answer(call->tid,200,msg); + ms_message("SIP answer sent."); + eXosip_unlock(); + lc->vtable.display_status(lc,_("Connected.")); + gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL); + + if (!offering) linphone_core_start_media_streams(lc, lc->call); + ms_message("call answered."); + return 0; +} + +int linphone_core_terminate_call(LinphoneCore *lc, const char *url) +{ + LinphoneCall *call=lc->call; + if (call==NULL){ + return -1; + } + lc->call=NULL; + + eXosip_lock(); + eXosip_call_terminate(call->cid,call->did); + eXosip_unlock(); + + /*stop ringing*/ + if (lc->ringstream!=NULL) { + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } + linphone_core_stop_media_streams(lc); + lc->vtable.display_status(lc,_("Call ended") ); + gstate_new_state(lc, GSTATE_CALL_END, NULL); + linphone_call_destroy(call); + return 0; +} + +bool_t linphone_core_in_call(const LinphoneCore *lc){ + return lc->call!=NULL; +} + +int linphone_core_send_publish(LinphoneCore *lc, + LinphoneOnlineStatus presence_mode) +{ + const MSList *elem; + for (elem=linphone_core_get_proxy_config_list(lc);elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; + if (cfg->publish) linphone_proxy_config_send_publish(cfg,presence_mode); + } + return 0; +} + +void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds){ + lc->sip_conf.inc_timeout=seconds; +} + +int linphone_core_get_inc_timeout(LinphoneCore *lc){ + return lc->sip_conf.inc_timeout; +} + +void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away, + const char *contact, + LinphoneOnlineStatus presence_mode) +{ + int contactok=-1; + if (minutes_away>0) lc->minutes_away=minutes_away; + if (contact!=NULL) { + osip_from_t *url; + osip_from_init(&url); + contactok=osip_from_parse(url,contact); + if (contactok>=0) { + ms_message("contact url is correct."); + } + osip_from_free(url); + + } + if (contactok>=0){ + if (lc->alt_contact!=NULL) ms_free(lc->alt_contact); + lc->alt_contact=ms_strdup(contact); + } + if (lc->presence_mode!=presence_mode){ + linphone_core_notify_all_friends(lc,presence_mode); + /* + Improve the use of all LINPHONE_STATUS available. + !TODO Do not mix "presence status" with "answer status code".. + Use correct parameter to follow sip_if_match/sip_etag. + */ + linphone_core_send_publish(lc,presence_mode); + } + lc->prev_mode=lc->presence_mode; + lc->presence_mode=presence_mode; + +} + +LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc){ + return lc->presence_mode; +} + +/* sound functions */ +int linphone_core_get_play_level(LinphoneCore *lc) +{ + return lc->sound_conf.play_lev; +} +int linphone_core_get_ring_level(LinphoneCore *lc) +{ + return lc->sound_conf.ring_lev; +} +int linphone_core_get_rec_level(LinphoneCore *lc){ + return lc->sound_conf.rec_lev; +} +void linphone_core_set_ring_level(LinphoneCore *lc, int level){ + MSSndCard *sndcard; + lc->sound_conf.ring_lev=level; + sndcard=lc->sound_conf.ring_sndcard; + if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_PLAYBACK,level); +} + +void linphone_core_set_play_level(LinphoneCore *lc, int level){ + MSSndCard *sndcard; + lc->sound_conf.play_lev=level; + sndcard=lc->sound_conf.play_sndcard; + if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_PLAYBACK,level); +} + +void linphone_core_set_rec_level(LinphoneCore *lc, int level) +{ + MSSndCard *sndcard; + lc->sound_conf.rec_lev=level; + sndcard=lc->sound_conf.capt_sndcard; + if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_CAPTURE,level); +} + +static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap){ + MSSndCard *sndcard=NULL; + if (devid!=NULL){ + sndcard=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),devid); + if (sndcard!=NULL && + (ms_snd_card_get_capabilities(sndcard) & cap)==0 ){ + ms_warning("%s card does not have the %s capability, ignoring.", + devid, + cap==MS_SND_CARD_CAP_CAPTURE ? "capture" : "playback"); + sndcard=NULL; + } + } + if (sndcard==NULL) { + /* get a card that has read+write capabilities */ + sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()); + /* otherwise refine to the first card having the right capability*/ + if (sndcard==NULL){ + const MSList *elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get()); + for(;elem!=NULL;elem=elem->next){ + sndcard=(MSSndCard*)elem->data; + if (ms_snd_card_get_capabilities(sndcard) & cap) break; + } + } + if (sndcard==NULL){/*looks like a bug! take the first one !*/ + const MSList *elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get()); + sndcard=(MSSndCard*)elem->data; + } + } + if (sndcard==NULL) ms_error("Could not find a suitable soundcard !"); + return sndcard; +} + +int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){ + lc->sound_conf.ring_sndcard=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK); + return 0; +} + +int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){ + lc->sound_conf.play_sndcard=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK); + return 0; +} + +int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid){ + lc->sound_conf.capt_sndcard=get_card_from_string_id(devid,MS_SND_CARD_CAP_CAPTURE); + return 0; +} + +const char * linphone_core_get_ringer_device(LinphoneCore *lc) +{ + return ms_snd_card_get_string_id(lc->sound_conf.ring_sndcard); +} + +const char * linphone_core_get_playback_device(LinphoneCore *lc) +{ + return ms_snd_card_get_string_id(lc->sound_conf.play_sndcard); +} + +const char * linphone_core_get_capture_device(LinphoneCore *lc) +{ + return ms_snd_card_get_string_id(lc->sound_conf.capt_sndcard); +} + +/* returns a static array of string describing the sound devices */ +const char** linphone_core_get_sound_devices(LinphoneCore *lc){ + return lc->sound_conf.cards; +} + +const char** linphone_core_get_video_devices(const LinphoneCore *lc){ + return lc->video_conf.cams; +} + +char linphone_core_get_sound_source(LinphoneCore *lc) +{ + return lc->sound_conf.source; +} + +void linphone_core_set_sound_source(LinphoneCore *lc, char source) +{ + MSSndCard *sndcard=lc->sound_conf.capt_sndcard; + lc->sound_conf.source=source; + if (!sndcard) return; + switch(source){ + case 'm': + ms_snd_card_set_capture(sndcard,MS_SND_CARD_MIC); + break; + case 'l': + ms_snd_card_set_capture(sndcard,MS_SND_CARD_LINE); + break; + } + +} + +void linphone_core_set_ring(LinphoneCore *lc,const char *path){ + if (lc->sound_conf.local_ring!=0){ + ms_free(lc->sound_conf.local_ring); + } + lc->sound_conf.local_ring=ms_strdup(path); +} + +const char *linphone_core_get_ring(LinphoneCore *lc){ + return lc->sound_conf.local_ring; +} + +static void notify_end_of_ring(void *ud ,unsigned int event, void * arg){ + LinphoneCore *lc=(LinphoneCore*)ud; + lc->preview_finished=1; +} + +int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata) +{ + if (lc->ringstream!=0){ + ms_warning("Cannot start ring now,there's already a ring being played"); + return -1; + } + lc_callback_obj_init(&lc->preview_finished_cb,func,userdata); + lc->preview_finished=0; + if (lc->sound_conf.ring_sndcard!=NULL){ + lc->ringstream=ring_start_with_cb(ring,2000,lc->sound_conf.ring_sndcard,notify_end_of_ring,(void *)lc); + } + return 0; +} + + +void linphone_core_set_ringback(LinphoneCore *lc,RingBackType type){ + switch(type){ + case RINGBACK_TYPE_FR: + lc->sound_conf.remote_ring=PACKAGE_SOUND_DIR "/" REMOTE_RING_FR; + break; + case RINGBACK_TYPE_US: + lc->sound_conf.remote_ring=PACKAGE_SOUND_DIR "/" REMOTE_RING_US; + break; + } +} +RingBackType linphone_core_get_ringback(LinphoneCore *lc); + +void linphone_core_enable_echo_cancelation(LinphoneCore *lc, bool_t val){ + lc->sound_conf.ec=val; +} + +bool_t linphone_core_echo_cancelation_enabled(LinphoneCore *lc){ + return lc->sound_conf.ec; +} + + +void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf) +{ + if (linphone_core_get_use_info_for_dtmf(lc)==0){ + /* In Band DTMF */ + if (lc->audiostream!=NULL){ + audio_stream_send_dtmf(lc->audiostream,dtmf); + } + }else{ + char dtmf_body[1000]; + char clen[10]; + osip_message_t *msg=NULL; + /* Out of Band DTMF (use INFO method) */ + LinphoneCall *call=lc->call; + if (call==NULL){ + return; + } + eXosip_call_build_info(call->did,&msg); + snprintf(dtmf_body, 999, "Signal=%c\r\nDuration=250\r\n", dtmf); + osip_message_set_body(msg,dtmf_body,strlen(dtmf_body)); + osip_message_set_content_type(msg,"application/dtmf-relay"); + snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body)); + osip_message_set_content_length(msg,clen); + + eXosip_lock(); + eXosip_call_send_request(call->did,msg); + eXosip_unlock(); + } +} + +void linphone_core_set_stun_server(LinphoneCore *lc, const char *server){ + if (lc->net_conf.stun_server!=NULL) + ms_free(lc->net_conf.stun_server); + if (server) + lc->net_conf.stun_server=ms_strdup(server); + else lc->net_conf.stun_server=NULL; + lc->apply_nat_settings=TRUE; +} + +const char * linphone_core_get_stun_server(const LinphoneCore *lc){ + return lc->net_conf.stun_server; +} + +const char * linphone_core_get_relay_addr(const LinphoneCore *lc){ + return lc->net_conf.relay; +} + +int linphone_core_set_relay_addr(LinphoneCore *lc, const char *addr){ + if (lc->net_conf.relay!=NULL){ + ms_free(lc->net_conf.relay); + lc->net_conf.relay=NULL; + } + if (addr){ + lc->net_conf.relay=ms_strdup(addr); + } + return 0; +} + +static void apply_nat_settings(LinphoneCore *lc){ + char *wmsg; + char *tmp=NULL; + int err; + struct addrinfo hints,*res; + const char *addr=lc->net_conf.nat_address; + + if (lc->net_conf.firewall_policy==LINPHONE_POLICY_USE_NAT_ADDRESS){ + if (addr==NULL || strlen(addr)==0){ + lc->vtable.display_warning(lc,_("No nat/firewall address supplied !")); + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_NO_FIREWALL); + } + /*check the ip address given */ + memset(&hints,0,sizeof(struct addrinfo)); + if (lc->sip_conf.ipv6_enabled) + hints.ai_family=AF_INET6; + else + hints.ai_family=AF_INET; + hints.ai_socktype = SOCK_DGRAM; + err=getaddrinfo(addr,NULL,&hints,&res); + if (err!=0){ + wmsg=ortp_strdup_printf(_("Invalid nat address '%s' : %s"), + addr, gai_strerror(err)); + ms_warning(wmsg); // what is this for ? + lc->vtable.display_warning(lc, wmsg); + ms_free(wmsg); + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_NO_FIREWALL); + return; + } + /*now get it as an numeric ip address */ + tmp=ms_malloc0(50); + err=getnameinfo(res->ai_addr,res->ai_addrlen,tmp,50,NULL,0,NI_NUMERICHOST); + if (err!=0){ + wmsg=ortp_strdup_printf(_("Invalid nat address '%s' : %s"), + addr, gai_strerror(err)); + ms_warning(wmsg); // what is this for ? + lc->vtable.display_warning(lc, wmsg); + ms_free(wmsg); + ms_free(tmp); + freeaddrinfo(res); + linphone_core_set_firewall_policy(lc,LINPHONE_POLICY_NO_FIREWALL); + return; + } + freeaddrinfo(res); + } + + if (lc->net_conf.firewall_policy==LINPHONE_POLICY_USE_NAT_ADDRESS){ + if (tmp!=NULL){ + if (!lc->net_conf.nat_sdp_only) + eXosip_masquerade_contact(tmp,lc->sip_conf.sip_port); + ms_free(tmp); + } + else + eXosip_masquerade_contact("",0); + } + else { + eXosip_masquerade_contact("",0); + } +} + + +void linphone_core_set_nat_address(LinphoneCore *lc, const char *addr) +{ + if (lc->net_conf.nat_address!=NULL){ + ms_free(lc->net_conf.nat_address); + } + if (addr!=NULL) lc->net_conf.nat_address=ms_strdup(addr); + else lc->net_conf.nat_address=NULL; + lc->apply_nat_settings=TRUE; +} + +const char *linphone_core_get_nat_address(const LinphoneCore *lc) +{ + return lc->net_conf.nat_address; +} + +void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy pol){ + lc->net_conf.firewall_policy=pol; + lc->apply_nat_settings=TRUE; +} + +LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc){ + return lc->net_conf.firewall_policy; +} + +MSList * linphone_core_get_call_logs(LinphoneCore *lc){ + lc->missed_calls=0; + return lc->call_logs; +} + +static void toggle_video_preview(LinphoneCore *lc, bool_t val){ +#ifdef VIDEO_ENABLED + if (lc->videostream==NULL){ + if (val){ + if (lc->previewstream==NULL){ + lc->previewstream=video_preview_start(lc->video_conf.device); + } + }else{ + if (lc->previewstream!=NULL){ + video_preview_stop(lc->previewstream); + lc->previewstream=NULL; + } + } + } +#endif +} + +void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled){ +#ifndef VIDEO_ENABLED + if (vcap_enabled || display_enabled) + ms_warning("This version of linphone was built without video support."); +#endif + lc->video_conf.capture=vcap_enabled; + lc->video_conf.display=display_enabled; + if (vcap_enabled && display_enabled) + lc->video_conf.show_local=1; + else + lc->video_conf.show_local=0; + + /* need to re-apply network bandwidth settings*/ + linphone_core_set_download_bandwidth(lc, + linphone_core_get_download_bandwidth(lc)); + linphone_core_set_upload_bandwidth(lc, + linphone_core_get_upload_bandwidth(lc)); +} + +bool_t linphone_core_video_enabled(LinphoneCore *lc){ + return (lc->video_conf.display || lc->video_conf.capture); +} + +void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val){ + lc->video_conf.show_local=val; +} + +bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc){ + return lc->video_conf.show_local; +} + +int linphone_core_set_video_device(LinphoneCore *lc, const char *id){ + MSWebCam *olddev=lc->video_conf.device; + if (id!=NULL){ + lc->video_conf.device=ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),id); + if (lc->video_conf.device==NULL){ + ms_warning("Could not found video device %s",id); + } + } + if (lc->video_conf.device==NULL) + lc->video_conf.device=ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get()); + if (olddev!=NULL && olddev!=lc->video_conf.device){ + toggle_video_preview(lc,FALSE);/*restart the video local preview*/ + } + return 0; +} + +const char *linphone_core_get_video_device(const LinphoneCore *lc){ + if (lc->video_conf.device) return ms_web_cam_get_string_id(lc->video_conf.device); + return NULL; +} + +void linphone_core_use_files(LinphoneCore *lc, bool_t yesno){ + lc->use_files=yesno; +} + +void linphone_core_set_play_file(LinphoneCore *lc, const char *file){ + if (lc->play_file!=NULL){ + ms_free(lc->play_file); + lc->play_file=NULL; + } + if (file!=NULL) { + lc->play_file=ms_strdup(file); + if (lc->audiostream) + audio_stream_play(lc->audiostream,file); + } +} + +void linphone_core_set_record_file(LinphoneCore *lc, const char *file){ + if (lc->rec_file!=NULL){ + ms_free(lc->rec_file); + lc->rec_file=NULL; + } + if (file!=NULL) { + lc->rec_file=ms_strdup(file); + if (lc->audiostream) + audio_stream_record(lc->audiostream,file); + } +} + + +void *linphone_core_get_user_data(LinphoneCore *lc){ + return lc->data; +} + +int linphone_core_get_mtu(const LinphoneCore *lc){ + return lc->net_conf.mtu; +} + +void linphone_core_set_mtu(LinphoneCore *lc, int mtu){ + lc->net_conf.mtu=mtu; + if (mtu>0){ + if (mtu<500){ + ms_error("MTU too small !"); + mtu=500; + } + ms_set_mtu(mtu); + ms_message("MTU is supposed to be %i, rtp payload max size will be %i",mtu, ms_get_payload_max_size()); + }else ms_set_mtu(0);//use mediastreamer2 default value +} + +void net_config_uninit(LinphoneCore *lc) +{ + net_config_t *config=&lc->net_conf; + lp_config_set_int(lc->config,"net","download_bw",config->download_bw); + lp_config_set_int(lc->config,"net","upload_bw",config->upload_bw); + + if (config->stun_server!=NULL) + lp_config_set_string(lc->config,"net","stun_server",config->stun_server); + if (config->nat_address!=NULL) + lp_config_set_string(lc->config,"net","nat_address",config->nat_address); + lp_config_set_int(lc->config,"net","firewall_policy",config->firewall_policy); + lp_config_set_int(lc->config,"net","mtu",config->mtu); +} + + +void sip_config_uninit(LinphoneCore *lc) +{ + MSList *elem; + int i; + sip_config_t *config=&lc->sip_conf; + lp_config_set_int(lc->config,"sip","sip_port",config->sip_port); + lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname); + lp_config_set_string(lc->config,"sip","contact",config->contact); + lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout); + lp_config_set_int(lc->config,"sip","use_info",config->use_info); + lp_config_set_int(lc->config,"sip","use_ipv6",config->ipv6_enabled); + for(elem=config->proxies,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data); + linphone_proxy_config_write_to_config_file(lc->config,cfg,i); + linphone_proxy_config_edit(cfg); /* to unregister */ + } + + if (exosip_running) + { + int i; + for (i=0;i<20;i++) + { + eXosip_event_t *ev; + while((ev=eXosip_event_wait(0,0))!=NULL){ + linphone_core_process_event(lc,ev); + } + eXosip_automatic_action(); +#ifndef WIN32 + usleep(100000); +#else + Sleep(100); +#endif + } + } + + linphone_proxy_config_write_to_config_file(lc->config,NULL,i); /*mark the end */ + + for(elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ + LinphoneAuthInfo *ai=(LinphoneAuthInfo*)(elem->data); + linphone_auth_info_write_config(lc->config,ai,i); + } + linphone_auth_info_write_config(lc->config,NULL,i); /* mark the end */ +} + +void rtp_config_uninit(LinphoneCore *lc) +{ + rtp_config_t *config=&lc->rtp_conf; + lp_config_set_int(lc->config,"rtp","audio_rtp_port",config->audio_rtp_port); + lp_config_set_int(lc->config,"rtp","video_rtp_port",config->video_rtp_port); + lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp); + lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->audio_jitt_comp); + lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout); +} + +void sound_config_uninit(LinphoneCore *lc) +{ + /*char tmpbuf[2];*/ + sound_config_t *config=&lc->sound_conf; + lp_config_set_string(lc->config,"sound","playback_dev_id",ms_snd_card_get_string_id(config->play_sndcard)); + lp_config_set_string(lc->config,"sound","ringer_dev_id",ms_snd_card_get_string_id(config->ring_sndcard)); + lp_config_set_string(lc->config,"sound","capture_dev_id",ms_snd_card_get_string_id(config->capt_sndcard)); + ms_free(config->cards); + /* + lp_config_set_int(lc->config,"sound","rec_lev",config->rec_lev); + lp_config_set_int(lc->config,"sound","play_lev",config->play_lev); + lp_config_set_int(lc->config,"sound","ring_lev",config->ring_lev); + tmpbuf[0]=config->source; + tmpbuf[1]='\0'; + lp_config_set_string(lc->config,"sound","source",tmpbuf); + */ + lp_config_set_string(lc->config,"sound","local_ring",config->local_ring); + lp_config_set_string(lc->config,"sound","remote_ring",config->remote_ring); + lp_config_set_int(lc->config,"sound","echocancelation",config->ec); +} + +void video_config_uninit(LinphoneCore *lc) +{ + video_config_t *config=&lc->video_conf; + const char *vd=linphone_core_get_video_device(lc); + if (vd && strstr(vd,"Static picture")!=NULL){ + vd=NULL; + } + lp_config_set_string(lc->config,"video","device",vd); + lp_config_set_int(lc->config,"video","display",config->display); + lp_config_set_int(lc->config,"video","capture",config->capture); + lp_config_set_int(lc->config,"video","show_local",config->show_local); +} + +void codecs_config_uninit(LinphoneCore *lc) +{ + PayloadType *pt; + codecs_config_t *config=&lc->codecs_conf; + MSList *node; + char key[50]; + int index; + index=0; + for(node=config->audio_codecs;node!=NULL;node=ms_list_next(node)){ + pt=(PayloadType*)(node->data); + sprintf(key,"audio_codec_%i",index); + lp_config_set_string(lc->config,key,"mime",pt->mime_type); + lp_config_set_int(lc->config,key,"rate",pt->clock_rate); + lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt)); + index++; + } + index=0; + for(node=config->video_codecs;node!=NULL;node=ms_list_next(node)){ + pt=(PayloadType*)(node->data); + sprintf(key,"video_codec_%i",index); + lp_config_set_string(lc->config,key,"mime",pt->mime_type); + lp_config_set_int(lc->config,key,"rate",pt->clock_rate); + lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt)); + lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp); + index++; + } +} + +void ui_config_uninit(LinphoneCore* lc) +{ + MSList *elem; + int i; + for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ + linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i); + linphone_friend_destroy(elem->data); + } + linphone_friend_write_to_config_file(lc->config,NULL,i); /* set the end */ + ms_list_free(lc->friends); + lc->friends=NULL; +} + +LpConfig *linphone_core_get_config(LinphoneCore *lc){ + return lc->config; +} + +void linphone_core_uninit(LinphoneCore *lc) +{ + gstate_new_state(lc, GSTATE_POWER_SHUTDOWN, NULL); +#ifdef VIDEO_ENABLED + if (lc->previewstream!=NULL){ + video_preview_stop(lc->previewstream); + lc->previewstream=NULL; + } +#endif + /* save all config */ + net_config_uninit(lc); + sip_config_uninit(lc); + lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL)); + rtp_config_uninit(lc); + sound_config_uninit(lc); + video_config_uninit(lc); + codecs_config_uninit(lc); + ui_config_uninit(lc); + lp_config_sync(lc->config); + lp_config_destroy(lc->config); + +#ifdef VIDEO_ENABLED + if (payload_type_h264_packetization_mode_1!=NULL) + payload_type_destroy(payload_type_h264_packetization_mode_1); +#endif + + ortp_exit(); + eXosip_quit(); + exosip_running=FALSE; + gstate_new_state(lc, GSTATE_POWER_OFF, NULL); +} + +void linphone_core_destroy(LinphoneCore *lc){ + linphone_core_uninit(lc); + ms_free(lc); +} diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h new file mode 100644 index 000000000..aa0216a43 --- /dev/null +++ b/linphone/coreapi/linphonecore.h @@ -0,0 +1,715 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef LINPHONECORE_H +#define LINPHONECORE_H + + +#include +#include "ortp/ortp.h" +#include "ortp/payloadtype.h" +#include "mediastreamer2/mscommon.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct _MSSndCard; +struct _LinphoneCore; + +bool_t payload_type_enabled(struct _PayloadType *pt); +void payload_type_set_enable(struct _PayloadType *pt,int value); +const char *payload_type_get_description(struct _PayloadType *pt); +int payload_type_get_bitrate(PayloadType *pt); +const char *payload_type_get_mime(PayloadType *pt); +int payload_type_get_rate(PayloadType *pt); + + +struct _LpConfig; + +typedef struct sip_config +{ + char *contact; + char *guessed_contact; + int sip_port; + MSList *proxies; + MSList *deleted_proxies; + int inc_timeout; /*timeout after an un-answered incoming call is rejected*/ + bool_t use_info; + bool_t guess_hostname; + bool_t loopback_only; + bool_t ipv6_enabled; + bool_t sdp_200_ack; +} sip_config_t; + +typedef struct rtp_config +{ + int audio_rtp_port; + int video_rtp_port; + int audio_jitt_comp; /*jitter compensation*/ + int video_jitt_comp; /*jitter compensation*/ + int nortp_timeout; +}rtp_config_t; + + + +typedef struct net_config +{ + char *nat_address; + char *stun_server; + char *relay; + int download_bw; + int upload_bw; + int firewall_policy; + int mtu; + bool_t nat_sdp_only; +}net_config_t; + + +typedef struct sound_config +{ + struct _MSSndCard * ring_sndcard; /* the playback sndcard currently used */ + struct _MSSndCard * play_sndcard; /* the playback sndcard currently used */ + struct _MSSndCard * capt_sndcard; /* the capture sndcard currently used */ + const char **cards; + int latency; /* latency in samples of the current used sound device */ + char rec_lev; + char play_lev; + char ring_lev; + char source; + char pad; + char *local_ring; + char *remote_ring; + bool_t ec; +} sound_config_t; + +typedef struct codecs_config +{ + MSList *audio_codecs; /* list of audio codecs in order of preference*/ + MSList *video_codecs; /* for later use*/ +}codecs_config_t; + +typedef struct video_config{ + struct _MSWebCam *device; + const char **cams; + bool_t capture; + bool_t show_local; + bool_t display; +}video_config_t; + +typedef struct ui_config +{ + int is_daemon; + int is_applet; + unsigned int timer_id; /* the timer id for registration */ +}ui_config_t; + + + +typedef struct autoreplier_config +{ + int enabled; + int after_seconds; /* accept the call after x seconds*/ + int max_users; /* maximum number of user that can call simultaneously */ + int max_rec_time; /* the max time of incoming voice recorded */ + int max_rec_msg; /* maximum number of recorded messages */ + const char *message; /* the path of the file to be played */ +}autoreplier_config_t; + + +struct _LinphoneCore; +struct _sdp_context; + +typedef struct _StreamParams +{ + int initialized; + int line; + int localport; + int remoteport; + int remotertcpport; + char *remoteaddr; + int pt; + char *relay_session_id; +} StreamParams; + +typedef enum _LCState{ + LCStateInit, + LCStateRinging, + LCStateAVRunning +}LCState; + +typedef enum _LinphoneCallDir {LinphoneCallOutgoing, LinphoneCallIncoming} LinphoneCallDir; + + +typedef struct _LinphoneCall +{ + struct _LinphoneCore *core; + StreamParams audio_params; + StreamParams video_params; + LinphoneCallDir dir; + struct _RtpProfile *profile; /*points to the local_profile or to the remote "guessed" profile*/ + struct _LinphoneCallLog *log; + int cid; /*call id */ + int did; /*dialog id */ + int tid; /*last transaction id*/ + struct _sdp_context *sdpctx; + time_t start_time; + LCState state; + bool_t auth_pending; +} LinphoneCall; + +LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_from_t *from, const osip_to_t *to); +LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const char *from, const char *to, int cid, int did , int tid); +#define linphone_call_set_state(lcall,st) (lcall)->state=(st) +void linphone_call_destroy(struct _LinphoneCall *obj); + + +typedef enum _LinphoneCallStatus { + LinphoneCallSuccess, + LinphoneCallAborted, + LinphoneCallMissed +} LinphoneCallStatus; + +typedef struct _LinphoneCallLog{ + LinphoneCallDir dir; + LinphoneCallStatus status; + char *from; + char *to; + char start_date[128]; + int duration; + +} LinphoneCallLog; + +/* private: */ +LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, char *local, char * remote); +void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call); +void linphone_call_log_destroy(LinphoneCallLog *cl); + +/*public: */ +char * linphone_call_log_to_str(LinphoneCallLog *cl); + +typedef enum{ + LinphoneSPWait, + LinphoneSPDeny, + LinphoneSPAccept +}LinphoneSubscribePolicy; + +typedef enum _LinphoneOnlineStatus{ + LINPHONE_STATUS_UNKNOWN, + LINPHONE_STATUS_ONLINE, + LINPHONE_STATUS_BUSY, + LINPHONE_STATUS_BERIGHTBACK, + LINPHONE_STATUS_AWAY, + LINPHONE_STATUS_ONTHEPHONE, + LINPHONE_STATUS_OUTTOLUNCH, + LINPHONE_STATUS_NOT_DISTURB, + LINPHONE_STATUS_MOVED, + LINPHONE_STATUS_ALT_SERVICE, + LINPHONE_STATUS_OFFLINE, + LINPHONE_STATUS_PENDING, + LINPHONE_STATUS_CLOSED, + LINPHONE_STATUS_END +}LinphoneOnlineStatus; + +const char *linphone_online_status_to_string(LinphoneOnlineStatus ss); + +typedef struct _LinphoneFriend{ + osip_from_t *url; + int in_did; + int out_did; + int sid; + int nid; + LinphoneSubscribePolicy pol; + LinphoneOnlineStatus status; + struct _LinphoneProxyConfig *proxy; + struct _LinphoneCore *lc; + bool_t subscribe; + bool_t inc_subscribe_pending; +}LinphoneFriend; + +LinphoneFriend * linphone_friend_new(); +LinphoneFriend *linphone_friend_new_with_addr(const char *addr); +int linphone_friend_set_sip_addr(LinphoneFriend *fr, const char *uri); +int linphone_friend_set_name(LinphoneFriend *fr, const char *name); +int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val); +int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol); +int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg); +void linphone_friend_edit(LinphoneFriend *fr); +void linphone_friend_done(LinphoneFriend *fr); +void linphone_friend_destroy(LinphoneFriend *lf); +/* memory returned by those 3 functions must be freed */ +char *linphone_friend_get_name(LinphoneFriend *lf); +char *linphone_friend_get_addr(LinphoneFriend *lf); +char *linphone_friend_get_url(LinphoneFriend *lf); /* name */ +bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf); +LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf); +LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf); + +#define linphone_friend_url(lf) ((lf)->url) + +void linphone_friend_write_to_config_file(struct _LpConfig *config, LinphoneFriend *lf, int index); +LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, int index); + +typedef struct _LinphoneProxyConfig +{ + struct _LinphoneCore *lc; + char *reg_proxy; + char *reg_identity; + char *reg_route; + char *realm; + int expires; + int reg_time; + int rid; + bool_t frozen; + bool_t reg_sendregister; + bool_t auth_pending; + bool_t registered; + bool_t publish; +} LinphoneProxyConfig; + +LinphoneProxyConfig *linphone_proxy_config_new(void); +int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr); +void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity); +void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route); +void linphone_proxy_config_expires(LinphoneProxyConfig *obj, const int expires); +void linphone_proxy_config_enable_register(LinphoneProxyConfig *obj, bool_t val); +#define linphone_proxy_config_enableregister linphone_proxy_config_enable_register +void linphone_proxy_config_edit(LinphoneProxyConfig *obj); +int linphone_proxy_config_done(LinphoneProxyConfig *obj); +void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val); +#define linphone_proxy_config_get_route(obj) ((obj)->reg_route) +#define linphone_proxy_config_get_identity(obj) ((obj)->reg_identity) +#define linphone_proxy_config_publish_enabled(obj) ((obj)->publish) +#define linphone_proxy_config_get_addr(obj) ((obj)->reg_proxy) +#define linphone_proxy_config_get_expires(obj) ((obj)->expires) +#define linphone_proxy_config_register_enabled(obj) ((obj)->reg_sendregister) + +/* destruction is called automatically when removing the proxy config */ +void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg); +LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index); +void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index); + +typedef struct _LinphoneAuthInfo +{ + char *username; + char *realm; + char *userid; + char *passwd; + char *ha1; + bool_t works; + bool_t first_time; +}LinphoneAuthInfo; + +LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid, + const char *passwd, const char *ha1,const char *realm); +void linphone_auth_info_set_passwd(LinphoneAuthInfo *info, const char *passwd); +/* you don't need those function*/ +void linphone_auth_info_destroy(LinphoneAuthInfo *info); +LinphoneAuthInfo * linphone_auth_info_new_from_config_file(struct _LpConfig *config, int pos); + +struct _LinphoneChatRoom{ + struct _LinphoneCore *lc; + char *peer; + char *route; + osip_from_t *peer_url; + void * user_data; +}; +typedef struct _LinphoneChatRoom LinphoneChatRoom; + +LinphoneChatRoom * linphone_core_create_chat_room(struct _LinphoneCore *lc, const char *to); +void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg); +void linphone_chat_room_destroy(LinphoneChatRoom *cr); +void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); +void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); + +/* describes the different groups of states */ +typedef enum _gstate_group { + GSTATE_GROUP_POWER, + GSTATE_GROUP_REG, + GSTATE_GROUP_CALL +} gstate_group_t; + +typedef enum _gstate { + /* states for GSTATE_GROUP_POWER */ + GSTATE_POWER_OFF = 0, /* initial state */ + GSTATE_POWER_STARTUP, + GSTATE_POWER_ON, + GSTATE_POWER_SHUTDOWN, + /* states for GSTATE_GROUP_REG */ + GSTATE_REG_NONE = 10, /* initial state */ + GSTATE_REG_OK, + GSTATE_REG_FAILED, + /* states for GSTATE_GROUP_CALL */ + GSTATE_CALL_IDLE = 20, /* initial state */ + GSTATE_CALL_OUT_INVITE, + GSTATE_CALL_OUT_CONNECTED, + GSTATE_CALL_IN_INVITE, + GSTATE_CALL_IN_CONNECTED, + GSTATE_CALL_END, + GSTATE_CALL_ERROR +} gstate_t; + +struct _LinphoneGeneralState { + gstate_t old_state; + gstate_t new_state; + gstate_group_t group; + const char *message; +}; +typedef struct _LinphoneGeneralState LinphoneGeneralState; + +/* retrieve the current state of the specified state group */ +gstate_t gstate_get_state(gstate_group_t group); + +/* private: set the initial states */ +void gstate_initialize(void); + +/* private: set a new state */ +void gstate_new_state(struct _LinphoneCore *lc, gstate_t new_state, const char *message); + +typedef void (*ShowInterfaceCb)(struct _LinphoneCore *lc); +typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, const char *from); +typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, const char *from); +typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message); +typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, const char *message); +typedef void (*DisplayUrlCb)(struct _LinphoneCore *lc, const char *message, const char *url); +typedef void (*DisplayQuestionCb)(struct _LinphoneCore *lc, const char *message); +typedef void (*LinphoneCoreCbFunc)(struct _LinphoneCore *lc,void * user_data); +typedef void (*NotifyReceivedCb)(struct _LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img); +typedef void (*NewUnknownSubscriberCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url); +typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, const char *username); +typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl); +typedef void (*TextMessageReceived)(struct _LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message); +typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate); + +typedef struct _LinphoneVTable +{ + ShowInterfaceCb show; + InviteReceivedCb inv_recv; + ByeReceivedCb bye_recv; + NotifyReceivedCb notify_recv; + NewUnknownSubscriberCb new_unknown_subscriber; + AuthInfoRequested auth_info_requested; + DisplayStatusCb display_status; + DisplayMessageCb display_message; +#ifdef VINCENT_MAURY_RSVP + /* the yes/no dialog box */ + DisplayMessageCb display_yes_no; +#endif + DisplayMessageCb display_warning; + DisplayUrlCb display_url; + DisplayQuestionCb display_question; + CallLogUpdated call_log_updated; + TextMessageReceived text_received; + GeneralStateChange general_state; +} LinphoneCoreVTable; + +typedef struct _LCCallbackObj +{ + LinphoneCoreCbFunc _func; + void * _user_data; +}LCCallbackObj; + + + +typedef enum _LinphoneFirewallPolicy{ + LINPHONE_POLICY_NO_FIREWALL, + LINPHONE_POLICY_USE_NAT_ADDRESS, + LINPHONE_POLICY_USE_STUN +} LinphoneFirewallPolicy; + +typedef struct _LinphoneCore +{ + LinphoneCoreVTable vtable; + struct _LpConfig *config; + net_config_t net_conf; + sip_config_t sip_conf; + rtp_config_t rtp_conf; + sound_config_t sound_conf; + video_config_t video_conf; + codecs_config_t codecs_conf; + ui_config_t ui_conf; + autoreplier_config_t autoreplier_conf; + LinphoneProxyConfig *default_proxy; + MSList *friends; + MSList *auth_info; + struct _RingStream *ringstream; + LCCallbackObj preview_finished_cb; + bool_t preview_finished; + LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/ + int rid; /*registration id*/ + MSList *queued_calls; /* used by the autoreplier */ + MSList *call_logs; + MSList *chatrooms; + int max_call_logs; + int missed_calls; + struct _AudioStream *audiostream; /**/ + struct _VideoStream *videostream; + struct _VideoStream *previewstream; + struct _RtpProfile *local_profile; + MSList *subscribers; /* unknown subscribers */ + int minutes_away; + LinphoneOnlineStatus presence_mode; + LinphoneOnlineStatus prev_mode; + char *alt_contact; + void *data; + ms_mutex_t lock; + char *play_file; + char *rec_file; + time_t prevtime; + int dw_audio_bw; + int up_audio_bw; + int dw_video_bw; + int up_video_bw; + int audio_bw; + int automatic_action; + bool_t use_files; + bool_t apply_nat_settings; +#ifdef VINCENT_MAURY_RSVP + /* QoS parameters*/ + int rsvp_enable; + int rpc_enable; +#endif +} LinphoneCore; + +#define LINPHONE_IPADDR_SIZE 64 + +/* THE main API */ + +void linphone_core_enable_logs(FILE *file); +void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc); +void linphone_core_disable_logs(void); + +const char *linphone_core_get_version(void); + +LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, + const char *config_path, void* userdata); + +void linphone_core_init(LinphoneCore *lc, const LinphoneCoreVTable *vtable, + const char *config_path, void * userdata); + +/* function to be periodically called in a main loop */ +void linphone_core_iterate(LinphoneCore *lc); + +int linphone_core_invite(LinphoneCore *lc, const char *url); + +int linphone_core_refer(LinphoneCore *lc, const char *url); + +bool_t linphone_core_inc_invite_pending(LinphoneCore*lc); + +bool_t linphone_core_in_call(const LinphoneCore *lc); + +int linphone_core_accept_call(LinphoneCore *lc, const char *url); + +int linphone_core_terminate_call(LinphoneCore *lc, const char *url); + +void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf); + +int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact); + +const char *linphone_core_get_primary_contact(LinphoneCore *lc); + +void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val); +bool_t linphone_core_get_guess_hostname(LinphoneCore *lc); + +bool_t linphone_core_ipv6_enabled(LinphoneCore *lc); +void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val); + +osip_from_t *linphone_core_get_primary_contact_parsed(LinphoneCore *lc); + +/*0= no bandwidth limit*/ +void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw); +void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw); + +int linphone_core_get_download_bandwidth(const LinphoneCore *lc); +int linphone_core_get_upload_bandwidth(const LinphoneCore *lc); + + +#ifdef VINCENT_MAURY_RSVP +/* QoS functions */ +int linphone_core_set_rpc_mode(LinphoneCore *lc, int on); /* on = 1 (RPC_ENABLE = 1) */ +int linphone_core_set_rsvp_mode(LinphoneCore *lc, int on); /* on = 1 (RSVP_ENABLE = 1) */ +int linphone_core_change_qos(LinphoneCore *lc, int answer); /* answer = 1 for yes, 0 for no */ +#endif + +/* returns a MSList of PayloadType */ +const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc); + +int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs); +/* returns a MSList of PayloadType */ +const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc); + +int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs); + +bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt); + +int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); + +void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); + +const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc); + +void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config); + +void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index); + +int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config); + +void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info); + +void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info); + +void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info); + +void linphone_core_clear_all_auth_info(LinphoneCore *lc); + +int linphone_core_get_audio_jittcomp(LinphoneCore *lc); + +void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value); + +int linphone_core_get_audio_port(const LinphoneCore *lc); + +int linphone_core_get_video_port(const LinphoneCore *lc); + +int linphone_core_get_nortp_timeout(const LinphoneCore *lc); + +void linphone_core_set_audio_port(LinphoneCore *lc, int port); + +void linphone_core_set_video_port(LinphoneCore *lc, int port); + +void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port); + +void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info); + +bool_t linphone_core_get_use_info_for_dtmf(LinphoneCore *lc); + +int linphone_core_get_sip_port(LinphoneCore *lc); + +void linphone_core_set_sip_port(LinphoneCore *lc,int port); + +void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds); + +int linphone_core_get_inc_timeout(LinphoneCore *lc); + +void linphone_core_set_stun_server(LinphoneCore *lc, const char *server); + +const char * linphone_core_get_stun_server(const LinphoneCore *lc); + +void linphone_core_set_nat_address(LinphoneCore *lc, const char *addr); + +const char *linphone_core_get_nat_address(const LinphoneCore *lc); + +void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy pol); + +LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc); + +const char * linphone_core_get_relay_addr(const LinphoneCore *lc); + +int linphone_core_set_relay_addr(LinphoneCore *lc, const char *addr); + +/* sound functions */ +/* returns a null terminated static array of string describing the sound devices */ +const char** linphone_core_get_sound_devices(LinphoneCore *lc); +int linphone_core_get_ring_level(LinphoneCore *lc); +int linphone_core_get_play_level(LinphoneCore *lc); +int linphone_core_get_rec_level(LinphoneCore *lc); +void linphone_core_set_ring_level(LinphoneCore *lc, int level); +void linphone_core_set_play_level(LinphoneCore *lc, int level); +void linphone_core_set_rec_level(LinphoneCore *lc, int level); +const char * linphone_core_get_ringer_device(LinphoneCore *lc); +const char * linphone_core_get_playback_device(LinphoneCore *lc); +const char * linphone_core_get_capture_device(LinphoneCore *lc); +int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid); +int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid); +int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid); +char linphone_core_get_sound_source(LinphoneCore *lc); +void linphone_core_set_sound_source(LinphoneCore *lc, char source); +void linphone_core_set_ring(LinphoneCore *lc, const char *path); +const char *linphone_core_get_ring(LinphoneCore *lc); +int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata); +typedef enum {RINGBACK_TYPE_FR,RINGBACK_TYPE_US} RingBackType; +void linphone_core_set_ringback(LinphoneCore *lc,RingBackType type); +RingBackType linphone_core_get_ringback(LinphoneCore *lc); +void linphone_core_enable_echo_cancelation(LinphoneCore *lc, bool_t val); +bool_t linphone_core_echo_cancelation_enabled(LinphoneCore *lc); + +void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away,const char *contact,LinphoneOnlineStatus os); + +LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc); + +void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr); +void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr); +void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf); +/* a list of LinphoneFriend */ +const MSList * linphone_core_get_friend_list(LinphoneCore *lc); +/* notify all friends that have subscribed */ +void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os); + +/* returns a list of LinphoneCallLog */ +MSList * linphone_core_get_call_logs(LinphoneCore *lc); + +/* video support */ +void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled); +bool_t linphone_core_video_enabled(LinphoneCore *lc); + +/*play/record support: use files instead of soundcard*/ +void linphone_core_use_files(LinphoneCore *lc, bool_t yesno); +void linphone_core_set_play_file(LinphoneCore *lc, const char *file); +void linphone_core_set_record_file(LinphoneCore *lc, const char *file); + + + +void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val); +bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc); + + + +/* returns a null terminated static array of string describing the webcams */ +const char** linphone_core_get_video_devices(const LinphoneCore *lc); +int linphone_core_set_video_device(LinphoneCore *lc, const char *id); +const char *linphone_core_get_video_device(const LinphoneCore *lc); + +int linphone_core_get_mtu(const LinphoneCore *lc); +void linphone_core_set_mtu(LinphoneCore *lc, int mtu); + +bool_t linphone_core_is_in_main_thread(LinphoneCore *lc); + +void *linphone_core_get_user_data(LinphoneCore *lc); + +/* returns LpConfig object to read/write to the config file: usefull if you wish to extend +the config file with your own sections */ +struct _LpConfig *linphone_core_get_config(LinphoneCore *lc); + +void linphone_core_uninit(LinphoneCore *lc); +void linphone_core_destroy(LinphoneCore *lc); + +/* end of lecacy api */ + +/*internal use only */ +#define linphone_core_lock(lc) ms_mutex_lock(&(lc)->lock) +#define linphone_core_unlock(lc) ms_mutex_unlock((&lc)->lock) +void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call); +void linphone_core_stop_media_streams(LinphoneCore *lc); +const char * linphone_core_get_identity(LinphoneCore *lc); +const char * linphone_core_get_route(LinphoneCore *lc); +bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, char **real_url, osip_to_t **real_parsed_url, char **route); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/coreapi/lpconfig.c b/linphone/coreapi/lpconfig.c new file mode 100644 index 000000000..c7d1a6049 --- /dev/null +++ b/linphone/coreapi/lpconfig.c @@ -0,0 +1,354 @@ +/*************************************************************************** + * lpconfig.c + * + * Thu Mar 10 11:13:44 2005 + * Copyright 2005 Simon Morlat + * Email simon.morlat@linphone.org + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define MAX_LEN 1024 + +#include "linphonecore.h" + +#include +#include +#include +#include +#include +#include +#include + +#define lp_new0(type,n) (type*)calloc(sizeof(type),n) + +#include "lpconfig.h" + +#define LISTNODE(_struct_) \ + struct _struct_ *_prev;\ + struct _struct_ *_next; + +typedef struct _ListNode{ + LISTNODE(_ListNode) +} ListNode; + +typedef void (*ListNodeForEachFunc)(ListNode *); + +ListNode * list_node_append(ListNode *head,ListNode *elem){ + ListNode *e=head; + while(e->_next!=NULL) e=e->_next; + e->_next=elem; + elem->_prev=e; + return head; +} + +ListNode * list_node_remove(ListNode *head, ListNode *elem){ + ListNode *before,*after; + before=elem->_prev; + after=elem->_next; + if (before!=NULL) before->_next=after; + if (after!=NULL) after->_prev=before; + elem->_prev=NULL; + elem->_next=NULL; + if (head==elem) return after; + return head; +} + +void list_node_foreach(ListNode *head, ListNodeForEachFunc func){ + for (;head!=NULL;head=head->_next){ + func(head); + } +} + + +#define LIST_PREPEND(e1,e2) ( (e2)->_prev=NULL,(e2)->_next=(e1),(e1)->_prev=(e2),(e2) ) +#define LIST_APPEND(head,elem) ((head)==0 ? (elem) : (list_node_append((ListNode*)(head),(ListNode*)(elem)), (head)) ) +#define LIST_REMOVE(head,elem) + +/* returns void */ +#define LIST_FOREACH(head) list_node_foreach((ListNode*)head) + +typedef struct _LpItem{ + char *key; + char *value; +} LpItem; + +typedef struct _LpSection{ + char *name; + MSList *items; +} LpSection; + +struct _LpConfig{ + FILE *file; + char *filename; + MSList *sections; +}; + +LpItem * lp_item_new(const char *key, const char *value){ + LpItem *item=lp_new0(LpItem,1); + item->key=strdup(key); + item->value=strdup(value); + return item; +} + +LpSection *lp_section_new(const char *name){ + LpSection *sec=lp_new0(LpSection,1); + sec->name=strdup(name); + return sec; +} + +void lp_item_destroy(void *pitem){ + LpItem *item=(LpItem*)pitem; + free(item->key); + free(item->value); + free(item); +} + +void lp_section_destroy(LpSection *sec){ + free(sec->name); + ms_list_for_each(sec->items,lp_item_destroy); + ms_list_free(sec->items); + free(sec); +} + +void lp_section_add_item(LpSection *sec,LpItem *item){ + sec->items=ms_list_append(sec->items,(void *)item); +} + +void lp_config_add_section(LpConfig *lpconfig, LpSection *section){ + lpconfig->sections=ms_list_append(lpconfig->sections,(void *)section); +} + +void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){ + lpconfig->sections=ms_list_remove(lpconfig->sections,(void *)section); + lp_section_destroy(section); +} + +static bool_t is_first_char(const char *start, const char *pos){ + const char *p; + for(p=start;pfile==NULL) return; + + while(fgets(tmp,MAX_LEN,lpconfig->file)!=NULL){ + char *pos1,*pos2; + pos1=strchr(tmp,'['); + if (pos1!=NULL && is_first_char(tmp,pos1) ){ + pos2=strchr(pos1,']'); + if (pos2!=NULL){ + int nbs; + char secname[MAX_LEN]; + secname[0]='\0'; + /* found section */ + *pos2='\0'; + nbs = sscanf(pos1+1,"%s",secname); + if (nbs == 1 ){ + if (strlen(secname)>0){ + cur=lp_section_new(secname); + lp_config_add_section(lpconfig,cur); + } + }else{ + ms_warning("parse error!"); + } + } + }else { + pos1=strchr(tmp,'='); + if (pos1!=NULL){ + char key[MAX_LEN]; + key[0]='\0'; + + *pos1='\0'; + if (sscanf(tmp,"%s",key)>0){ + + pos1++; + pos2=strchr(pos1,'\n'); + if (pos2==NULL) pos2=pos1+strlen(pos2); + else { + *pos2='\0'; /*replace the '\n' */ + pos2--; + } + /* remove ending white spaces */ + for (; pos2>pos1 && *pos2==' ';pos2--) *pos2='\0'; + if (pos2-pos1>=0){ + /* found a pair key,value */ + if (cur!=NULL){ + lp_section_add_item(cur,lp_item_new(key,pos1)); + /*printf("Found %s %s=%s\n",cur->name,key,pos1);*/ + }else{ + ms_warning("found key,item but no sections"); + } + } + } + } + } + } +} + +LpConfig * lp_config_new(const char *filename){ + LpConfig *lpconfig=lp_new0(LpConfig,1); + if (filename!=NULL){ + lpconfig->filename=strdup(filename); + lpconfig->file=fopen(filename,"rw"); + if (lpconfig->file!=NULL){ + lp_config_parse(lpconfig); + fclose(lpconfig->file); + /* make existing configuration files non-group/world-accessible */ + if (chmod(filename, S_IRUSR | S_IWUSR) == -1) + ms_warning("unable to correct permissions on " + "configuration file: %s", + strerror(errno)); + lpconfig->file=NULL; + } + } + return lpconfig; +} + +void lp_item_set_value(LpItem *item, const char *value){ + free(item->value); + item->value=strdup(value); +} + + +void lp_config_destroy(LpConfig *lpconfig){ + if (lpconfig->filename!=NULL) free(lpconfig->filename); + ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy); + ms_list_free(lpconfig->sections); + free(lpconfig); +} + +LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){ + LpSection *sec; + MSList *elem; + /*printf("Looking for section %s\n",name);*/ + for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){ + sec=(LpSection*)elem->data; + if (strcmp(sec->name,name)==0){ + /*printf("Section %s found\n",name);*/ + return sec; + } + } + return NULL; +} + +LpItem *lp_section_find_item(LpSection *sec, const char *name){ + MSList *elem; + LpItem *item; + /*printf("Looking for item %s\n",name);*/ + for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){ + item=(LpItem*)elem->data; + if (strcmp(item->key,name)==0) { + /*printf("Item %s found\n",name);*/ + return item; + } + } + return NULL; +} + +void lp_section_remove_item(LpSection *sec, LpItem *item){ + sec->items=ms_list_remove(sec->items,(void *)item); + lp_item_destroy(item); +} + +const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string){ + LpSection *sec; + LpItem *item; + sec=lp_config_find_section(lpconfig,section); + if (sec!=NULL){ + item=lp_section_find_item(sec,key); + if (item!=NULL) return item->value; + } + return default_string; +} + +int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){ + const char *str=lp_config_get_string(lpconfig,section,key,NULL); + if (str!=NULL) return atoi(str); + else return default_value; +} + +void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){ + LpItem *item; + LpSection *sec=lp_config_find_section(lpconfig,section); + if (sec!=NULL){ + item=lp_section_find_item(sec,key); + if (item!=NULL){ + if (value!=NULL) + lp_item_set_value(item,value); + else lp_section_remove_item(sec,item); + }else{ + if (value!=NULL) + lp_section_add_item(sec,lp_item_new(key,value)); + } + }else if (value!=NULL){ + sec=lp_section_new(section); + lp_config_add_section(lpconfig,sec); + lp_section_add_item(sec,lp_item_new(key,value)); + } +} + +void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){ + char tmp[30]; + snprintf(tmp,30,"%i",value); + lp_config_set_string(lpconfig,section,key,tmp); +} + +void lp_item_write(LpItem *item, FILE *file){ + fprintf(file,"%s=%s\n",item->key,item->value); +} + +void lp_section_write(LpSection *sec, FILE *file){ + fprintf(file,"[%s]\n",sec->name); + ms_list_for_each2(sec->items,(void (*)(void*, void*))lp_item_write,(void *)file); + fprintf(file,"\n"); +} + +int lp_config_sync(LpConfig *lpconfig){ + FILE *file; + if (lpconfig->filename==NULL) return -1; +#ifndef WIN32 + /* don't create group/world-accessible files */ + (void) umask(S_IRWXG | S_IRWXO); +#endif + file=fopen(lpconfig->filename,"w"); + if (file==NULL){ + ms_warning("Could not write %s !",lpconfig->filename); + return -1; + } + ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file); + fclose(file); + return 0; +} + +int lp_config_has_section(LpConfig *lpconfig, const char *section){ + if (lp_config_find_section(lpconfig,section)!=NULL) return 1; + return 0; +} + +void lp_config_clean_section(LpConfig *lpconfig, const char *section){ + LpSection *sec=lp_config_find_section(lpconfig,section); + if (sec!=NULL){ + lp_config_remove_section(lpconfig,sec); + } +} diff --git a/linphone/coreapi/lpconfig.h b/linphone/coreapi/lpconfig.h new file mode 100644 index 000000000..2bf18b95e --- /dev/null +++ b/linphone/coreapi/lpconfig.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * lpconfig.h + * + * Thu Mar 10 15:02:49 2005 + * Copyright 2005 Simon Morlat + * Email simon.morlat@linphone.org + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef LPCONFIG_H +#define LPCONFIG_H + +typedef struct _LpConfig LpConfig; + +#ifdef __cplusplus +extern "C" { +#endif + +LpConfig * lp_config_new(const char *filename); +const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string); +int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value); +void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value); +void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value); +int lp_config_sync(LpConfig *lpconfig); +int lp_config_has_section(LpConfig *lpconfig, const char *section); +void lp_config_clean_section(LpConfig *lpconfig, const char *section); +void lp_config_destroy(LpConfig *cfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/coreapi/misc.c b/linphone/coreapi/misc.c new file mode 100644 index 000000000..418e01c99 --- /dev/null +++ b/linphone/coreapi/misc.c @@ -0,0 +1,450 @@ + +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "private.h" +#include "mediastreamer2/mediastream.h" +#include +#include +#include +#include +#include +#include +#include + + +#ifndef WIN32 + +static char lock_name[80]; +static char lock_set=0; +/* put a lock file in /tmp. this is called when linphone runs as a daemon*/ +int set_lock_file() +{ + FILE *lockfile; + + snprintf(lock_name,80,"/tmp/linphone.%i",getuid()); + lockfile=fopen(lock_name,"w"); + if (lockfile==NULL) + { + printf("Failed to create lock file.\n"); + return(-1); + } + fprintf(lockfile,"%i",getpid()); + fclose(lockfile); + lock_set=1; + return(0); +} + +/* looks if there is a lock file. If presents return its content (the pid of the already running linphone), if not found, returns -1*/ +int get_lock_file() +{ + int pid; + FILE *lockfile; + + snprintf(lock_name,80,"/tmp/linphone.%i",getuid()); + lockfile=fopen(lock_name,"r"); + if (lockfile==NULL) + return(-1); + if (fscanf(lockfile,"%i",&pid)!=1){ + ms_warning("Could not read pid in lock file."); + fclose(lockfile); + return -1; + } + fclose(lockfile); + return pid; +} + +/* remove the lock file if it was set*/ +int remove_lock_file() +{ + int err=0; + if (lock_set) + { + err=unlink(lock_name); + lock_set=0; + } + return(err); +} + +#endif + +char *int2str(int number) +{ + char *numstr=ms_malloc(10); + snprintf(numstr,10,"%i",number); + return numstr; +} + +void check_sound_device(LinphoneCore *lc) +{ + int fd,len; + int a; + char *file=NULL; + char *i810_audio=NULL; + char *snd_pcm_oss=NULL; + char *snd_mixer_oss=NULL; + char *snd_pcm=NULL; + + fd=open("/proc/modules",O_RDONLY); + if (fd>0){ + /* read the entire /proc/modules file and check if sound conf seems correct */ + /*a=fstat(fd,&statbuf); + if (a<0) ms_warning("Can't stat /proc/modules:%s.",strerror(errno)); + len=statbuf.st_size; + if (len==0) ms_warning("/proc/modules has zero size!"); + */ + /***** fstat does not work on /proc/modules for unknown reason *****/ + len=6000; + file=ms_malloc(len+1); + a=read(fd,file,len); + if (avtable.display_warning(lc,_("You are currently using the i810_audio driver.\nThis driver is buggy and so does not work with Linphone.\nWe suggest that you replace it by its equivalent ALSA driver,\neither with packages from your distribution, or by downloading\nALSA drivers at http://www.alsa-project.org."));*/ + goto end; + } + snd_pcm=strstr(file,"snd-pcm"); + if (snd_pcm!=NULL){ + snd_pcm_oss=strstr(file,"snd-pcm-oss"); + snd_mixer_oss=strstr(file,"snd-mixer-oss"); + if (snd_pcm_oss==NULL){ + lc->vtable.display_warning(lc,_("Your computer appears to be using ALSA sound drivers.\nThis is the best choice. However the pcm oss emulation module\nis missing and linphone needs it. Please execute\n'modprobe snd-pcm-oss' as root to load it.")); + } + if (snd_mixer_oss==NULL){ + lc->vtable.display_warning(lc,_("Your computer appears to be using ALSA sound drivers.\nThis is the best choice. However the mixer oss emulation module\nis missing and linphone needs it. Please execute\n 'modprobe snd-mixer-oss' as root to load it.")); + } + } + }else { +#ifdef __linux + ms_warning("Could not open /proc/modules."); +#endif + } + /* now check general volume. Some user forget to rise it and then complain that linphone is + not working */ + /* but some other users complain that linphone should not change levels... + if (lc->sound_conf.sndcard!=NULL){ + a=snd_card_get_level(lc->sound_conf.sndcard,SND_CARD_LEVEL_GENERAL); + if (a<50){ + ms_warning("General level is quite low (%i). Linphone rises it up for you.",a); + snd_card_set_level(lc->sound_conf.sndcard,SND_CARD_LEVEL_GENERAL,80); + } + } + */ + end: + if (file!=NULL) ms_free(file); + if (fd>0) close(fd); +} + +#define UDP_HDR_SZ 8 +#define RTP_HDR_SZ 12 +#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/ + +const char *payload_type_get_description(PayloadType *pt){ + return (const char *)pt->user_data; +} + +void payload_type_set_enable(PayloadType *pt,int value) +{ + if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \ + else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED); +} + + +bool_t payload_type_enabled(PayloadType *pt) { + return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0); +} + +int payload_type_get_bitrate(PayloadType *pt) +{ + return pt->normal_bitrate; +} +const char *payload_type_get_mime(PayloadType *pt){ + return pt->mime_type; +} + +int payload_type_get_rate(PayloadType *pt){ + return pt->clock_rate; +} + +static double get_audio_payload_bandwidth(const PayloadType *pt){ + double npacket=50; + double packet_size; + int bitrate; + bitrate=pt->normal_bitrate; + packet_size=(double)(bitrate/(50*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; + return packet_size*8.0*npacket; +} + +void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc, const PayloadType *pt){ + lc->audio_bw=(int)(get_audio_payload_bandwidth(pt)/1000.0); + /*update*/ + linphone_core_set_upload_bandwidth(lc,lc->net_conf.upload_bw); +} + +static void update_allocated_audio_bandwidth(LinphoneCore *lc){ + const MSList *elem; + PayloadType *max=NULL; + for(elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ + PayloadType *pt=(PayloadType*)elem->data; + if (payload_type_enabled(pt)){ + if (max==NULL) max=pt; + else if (max->normal_bitratenormal_bitrate){ + max=pt; + } + } + } + if (max) { + linphone_core_update_allocated_audio_bandwidth(lc,max); + } +} + +/* return TRUE if codec can be used with bandwidth, FALSE else*/ +bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt) +{ + double codec_band; + int min_audio_bw; + int min_video_bw; + bool_t ret=FALSE; + /* + update allocated audio bandwidth to allocate the remaining to video. + This must be done outside calls, because after sdp negociation + the audio bandwidth is refined to the selected codec + */ + if (!linphone_core_in_call(lc)) update_allocated_audio_bandwidth(lc); + min_audio_bw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + if (min_audio_bw==0) min_audio_bw=-1; + min_video_bw=get_min_bandwidth(lc->dw_video_bw,lc->up_video_bw); + + switch (pt->type){ + case PAYLOAD_AUDIO_CONTINUOUS: + case PAYLOAD_AUDIO_PACKETIZED: + codec_band=get_audio_payload_bandwidth(pt); + ret=bandwidth_is_greater(min_audio_bw*1000,codec_band); + //ms_message("Payload %s: %g",pt->mime_type,codec_band); + break; + case PAYLOAD_VIDEO: + if (min_video_bw!=0) {/* infinite (-1) or strictly positive*/ + /*let the video use all the bandwidth minus the maximum bandwidth used by audio */ + if (min_video_bw>0) + pt->normal_bitrate=min_video_bw*1000; + else + pt->normal_bitrate=512000; + ret=TRUE; + } + else ret=FALSE; + break; + } + /*if (!ret) ms_warning("Payload %s is not usable with your internet connection.",pt->mime_type);*/ + + return ret; +} + +static PayloadType * find_payload(RtpProfile *prof, PayloadType *pt /*from config*/){ + PayloadType *candidate=NULL; + int i; + PayloadType *it; + for(i=0;i<127;++i){ + it=rtp_profile_get_payload(prof,i); + if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0 + && (pt->clock_rate==it->clock_rate || pt->clock_rate<=0) + && payload_type_get_user_data(it)==NULL ){ + if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) || + (pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){ + /*exact match*/ + return it; + }else candidate=it; + } + } + return candidate; +} + +static MSList *fix_codec_list(RtpProfile *prof, MSList *conflist) +{ + MSList *elem; + MSList *newlist=NULL; + PayloadType *payload,*confpayload; + + for (elem=conflist;elem!=NULL;elem=ms_list_next(elem)) + { + confpayload=(PayloadType*)elem->data; + payload=find_payload(prof,confpayload); + if (payload!=NULL){ + if (ms_filter_codec_supported(confpayload->mime_type)){ + MSFilterDesc *desc=ms_filter_get_encoder(confpayload->mime_type); + payload_type_set_user_data(payload,(void*)desc->text); + payload_type_set_enable(payload,payload_type_enabled(confpayload)); + newlist=ms_list_append(newlist,payload); + } + } + else{ + ms_warning("Cannot support %s/%i: does not exist.",confpayload->mime_type, + confpayload->clock_rate); + } + } + return newlist; +} + + +void linphone_core_setup_local_rtp_profile(LinphoneCore *lc) +{ + int i; + MSList *audiopt,*videopt; + PayloadType *payload; + bool_t prepend; + lc->local_profile=rtp_profile_clone_full(&av_profile); + + /* first look at the list given by configuration file to see if + it is correct */ + audiopt=fix_codec_list(lc->local_profile,lc->codecs_conf.audio_codecs); + videopt=fix_codec_list(lc->local_profile,lc->codecs_conf.video_codecs); + + /* now find and add payloads that are not listed in the configuration + codec list */ + for (i=0;i<127;i++) + { + payload=rtp_profile_get_payload(lc->local_profile,i); + if (payload!=NULL){ + if (payload_type_get_user_data(payload)!=NULL) continue; + /* find a mediastreamer codec for this payload type */ + if (ms_filter_codec_supported(payload->mime_type)){ + MSFilterDesc *desc=ms_filter_get_encoder(payload->mime_type); + ms_message("Adding new codec %s/%i",payload->mime_type,payload->clock_rate); + payload_type_set_enable(payload,1); + payload_type_set_user_data(payload,(void *)desc->text); + prepend=FALSE; + /* by default, put speex, mpeg4, or h264 on top of list*/ + if (strcmp(payload->mime_type,"speex")==0) + prepend=TRUE; + if (strcmp(payload->mime_type,"MP4V-ES")==0) + prepend=TRUE; + if (strcmp(payload->mime_type,"H264")==0) + prepend=TRUE; + switch (payload->type){ + case PAYLOAD_AUDIO_CONTINUOUS: + case PAYLOAD_AUDIO_PACKETIZED: + if (prepend) + audiopt=ms_list_prepend(audiopt,(void *)payload); + else + audiopt=ms_list_append(audiopt,(void *)payload); + break; + case PAYLOAD_VIDEO: + if (prepend) + videopt=ms_list_prepend(videopt,(void *)payload); + else + videopt=ms_list_append(videopt,(void *)payload); + break; + default: + ms_error("Unsupported rtp media type."); + } + } + } + } + ms_list_for_each(lc->codecs_conf.audio_codecs,(void (*)(void*))payload_type_destroy); + ms_list_for_each(lc->codecs_conf.video_codecs,(void (*)(void *))payload_type_destroy); + ms_list_free(lc->codecs_conf.audio_codecs); + ms_list_free(lc->codecs_conf.video_codecs); + /* set the fixed lists instead:*/ + lc->codecs_conf.audio_codecs=audiopt; + lc->codecs_conf.video_codecs=videopt; +} + +int from_2char_without_params(osip_from_t *from,char **str) +{ + osip_from_t *tmpfrom=NULL; + osip_from_clone(from,&tmpfrom); + if (tmpfrom!=NULL){ + while(!osip_list_eol(&tmpfrom->gen_params,0)){ + osip_generic_param_t *param=(osip_generic_param_t*)osip_list_get(&tmpfrom->gen_params,0); + osip_generic_param_free(param); + osip_list_remove(&tmpfrom->gen_params,0); + } + }else return -1; + osip_from_to_str(tmpfrom,str); + osip_from_free(tmpfrom); + return 0; +} + +bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){ + FILE *f=popen(command,"r"); + if (f!=NULL){ + int err; + *result=ms_malloc(4096); + err=fread(*result,1,4096-1,f); + if (err<0){ + ms_warning("Error reading command output:%s",strerror(errno)); + ms_free(result); + return FALSE; + } + (*result)[err]=0; + err=pclose(f); + if (command_ret!=NULL) *command_ret=err; + return TRUE; + } + return FALSE; +} + +#if defined(HAVE_GETIFADDRS) && defined(INET6) +#include +#include +#include +bool_t host_has_ipv6_network() +{ + struct ifaddrs *ifp; + struct ifaddrs *ifpstart; + bool_t ipv6_present=FALSE; + + if (getifaddrs (&ifpstart) < 0) + { + return FALSE; + } + + for (ifp=ifpstart; ifp != NULL; ifp = ifp->ifa_next) + { + if (!ifp->ifa_addr) + continue; + + switch (ifp->ifa_addr->sa_family) { + case AF_INET: + + break; + case AF_INET6: + ipv6_present=TRUE; + break; + default: + continue; + } + } + + freeifaddrs (ifpstart); + + return ipv6_present; +} +#else + +bool_t host_has_ipv6_network() +{ + return FALSE; +} + + +#endif diff --git a/linphone/coreapi/presence.c b/linphone/coreapi/presence.c new file mode 100644 index 000000000..0664fbee7 --- /dev/null +++ b/linphone/coreapi/presence.c @@ -0,0 +1,208 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include +#include +#include "private.h" + + +extern const char *__policy_enum_to_str(LinphoneSubscribePolicy pol); + + +void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, int did, int nid){ + LinphoneFriend *fl=linphone_friend_new_with_addr(subscriber); + if (fl==NULL) return ; + fl->in_did=did; + linphone_friend_set_nid(fl,nid); + linphone_friend_set_inc_subscribe_policy(fl,LinphoneSPAccept); + fl->inc_subscribe_pending=TRUE; + lc->subscribers=ms_list_append(lc->subscribers,(void *)fl); + if (lc->vtable.new_unknown_subscriber!=NULL) { + char *clean_subscriber; /* we need to remove tags...*/ + from_2char_without_params(fl->url,&clean_subscriber); + lc->vtable.new_unknown_subscriber(lc,fl,clean_subscriber); + ms_free(clean_subscriber); + } +} + +void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){ + linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPDeny); +} + +static void __do_notify(void * data, void * user_data){ + int *tab=(int*)user_data; + LinphoneFriend *lf=(LinphoneFriend*)data; + linphone_friend_notify(lf,tab[0],tab[1]); +} + +void __linphone_core_notify_all_friends(LinphoneCore *lc, int ss, int os){ + int tab[2]; + tab[0]=ss; + tab[1]=os; + ms_list_for_each2(lc->friends,__do_notify,(void *)tab); +} + +void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os){ + ms_message("Notifying all friends that we are in status %i",os); + __linphone_core_notify_all_friends(lc,EXOSIP_SUBCRSTATE_ACTIVE,os); +} + +/* check presence state before answering to call; returns TRUE if we can proceed, else answer the appropriate answer +to close the dialog*/ +bool_t linphone_core_check_presence(LinphoneCore *lc){ + return TRUE; +} + +void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev){ + LinphoneFriend *lf=NULL; + osip_from_t *from=ev->request->from; + char *tmp; + osip_message_t *msg=NULL; + + osip_from_to_str(ev->request->from,&tmp); + + ms_message("Receiving new subscription from %s.",tmp); + /* check if we answer to this subscription */ + if (find_friend(lc->friends,from,&lf)!=NULL){ + lf->in_did=ev->did; + linphone_friend_set_nid(lf,ev->nid); + eXosip_insubscription_build_answer(ev->tid,202,&msg); + eXosip_insubscription_send_answer(ev->tid,202,msg); + __eXosip_wakeup_event(); + linphone_friend_done(lf); /*this will do all necessary actions */ + }else{ + /* check if this subscriber is in our black list */ + if (find_friend(lc->subscribers,from,&lf)){ + if (lf->pol==LinphoneSPDeny){ + ms_message("Rejecting %s because we already rejected it once.",from); + eXosip_insubscription_send_answer(ev->tid,401,NULL); + } + else { + /* else it is in wait for approval state, because otherwise it is in the friend list.*/ + ms_message("New subscriber found in friend list, in %s state.",__policy_enum_to_str(lf->pol)); + } + }else { + eXosip_insubscription_build_answer(ev->tid,202,&msg); + eXosip_insubscription_send_answer(ev->tid,202,msg); + linphone_core_add_subscriber(lc,tmp,ev->did,ev->nid); + } + } + osip_free(tmp); +} + +void linphone_notify_recv(LinphoneCore *lc, eXosip_event_t *ev) +{ + const char *status=_("Gone"); + const char *img="sip-closed.png"; + char *tmp; + LinphoneFriend *lf; + osip_from_t *friend=NULL; + osip_from_t *from=NULL; + osip_body_t *body=NULL; + LinphoneOnlineStatus estatus=LINPHONE_STATUS_UNKNOWN; + ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid); + if (ev->request!=NULL){ + from=ev->request->from; + osip_message_get_body(ev->request,0,&body); + if (body==NULL){ + ms_error("No body in NOTIFY"); + return; + } + if (strstr(body->body,"pending")!=NULL){ + status=_("Waiting for Approval"); + img="sip-wfa.png"; + estatus=LINPHONE_STATUS_PENDING; + }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) { + status=_("Online"); + img="sip-online.png"; + estatus=LINPHONE_STATUS_ONLINE; + }else if (strstr(body->body,"busy")!=NULL){ + status=_("Busy"); + img="sip-busy.png"; + estatus=LINPHONE_STATUS_BUSY; + }else if (strstr(body->body,"berightback")!=NULL + || strstr(body->body,"in-transit")!=NULL ){ + status=_("Be Right Back"); + img="sip-bifm.png"; + estatus=LINPHONE_STATUS_BERIGHTBACK; + }else if (strstr(body->body,"away")!=NULL){ + status=_("Away"); + img="sip-away.png"; + estatus=LINPHONE_STATUS_AWAY; + }else if (strstr(body->body,"onthephone")!=NULL + || strstr(body->body,"on-the-phone")!=NULL){ + status=_("On The Phone"); + img="sip-otp.png"; + estatus=LINPHONE_STATUS_ONTHEPHONE; + }else if (strstr(body->body,"outtolunch")!=NULL + || strstr(body->body,"meal")!=NULL){ + status=_("Out To Lunch"); + img="sip-otl.png"; + estatus=LINPHONE_STATUS_OUTTOLUNCH; + }else if (strstr(body->body,"closed")!=NULL){ + status=_("Closed"); + img="sip-away.png"; + estatus=LINPHONE_STATUS_CLOSED; + }else{ + status=_("Gone"); + img="sip-closed.png"; + estatus=LINPHONE_STATUS_OFFLINE; + } + ms_message("We are notified that sip:%s@%s has online status %s",from->url->username,from->url->host,status); + } + lf=linphone_find_friend_by_sid(lc->friends,ev->sid); + if (lf!=NULL){ + friend=lf->url; + from_2char_without_params(friend,&tmp); + lf->status=estatus; + lc->vtable.notify_recv(lc,(LinphoneFriend*)lf,tmp,status,img); + ms_free(tmp); + if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) { + lf->sid=-1; + lf->out_did=-1; + ms_message("Outgoing subscription terminated by remote."); + } + }else{ + ms_message("But this person is not part of our friend list, so we don't care."); + } +} + +void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev){ + LinphoneFriend *lf; + osip_from_t *from=ev->response->to; + find_friend(lc->friends,from,&lf); + if (lf!=NULL){ + lf->out_did=ev->did; + linphone_friend_set_sid(lf,ev->sid); + }else{ + ms_warning("Receiving answer for unknown subscribe sip:%s@%s", from->url->username,from->url->host); + } +} +void linphone_subscription_closed(LinphoneCore *lc,eXosip_event_t *ev){ + LinphoneFriend *lf; + osip_from_t *from=ev->request->from; + lf=linphone_find_friend_by_nid(lc->friends,ev->nid); + if (lf!=NULL){ + lf->in_did=-1; + linphone_friend_set_nid(lf,-1); + }else{ + ms_warning("Receiving unsuscribe for unknown in-subscribtion from sip:%s@%s", from->url->username, from->url->host); + } +} diff --git a/linphone/coreapi/private.h b/linphone/coreapi/private.h new file mode 100644 index 000000000..bbb06a39b --- /dev/null +++ b/linphone/coreapi/private.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * private.h + * + * Mon Jun 13 14:23:23 2005 + * Copyright 2005 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _PRIVATE_H +#define _PRIVATE_H + +#include "linphonecore.h" +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef LINPHONE_VERSION +#define LINPHONE_VERSION "2.99.4" +#endif + +#ifndef LIBLINPHONE_VERSION +#define LIBLINPHONE_VERSION LINPHONE_VERSION +#endif + +#ifndef PACKAGE_SOUND_DIR +#define PACKAGE_SOUND_DIR "." +#endif + +#ifdef WIN32 +#include /* for access() */ +#endif + +#ifdef HAVE_GETTEXT +#include +#ifndef _ +#define _(String) gettext(String) +#endif +#else +#define _(something) (something) +#endif + +void linphone_core_init_media_streams(LinphoneCore *lc); + +void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos); + +void linphone_core_update_proxy_register(LinphoneCore *lc); +void linphone_core_refresh_subscribes(LinphoneCore *lc); + +int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineStatus os); + +int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); + +void linphone_friend_set_sid(LinphoneFriend *lf, int sid); +void linphone_friend_set_nid(LinphoneFriend *lf, int nid); +void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os); + +int set_lock_file(); +int get_lock_file(); +int remove_lock_file(); +int do_registration(LinphoneCore *lc, bool_t doit); +void check_for_registration(LinphoneCore *lc); +char *int2str(int number); +int from_2char_without_params(osip_from_t *from,char **str); +void check_sound_device(LinphoneCore *lc); +void linphone_core_setup_local_rtp_profile(LinphoneCore *lc); +void linphone_core_get_local_ip(LinphoneCore *lc, const char *to, char *result); +bool_t host_has_ipv6_network(); +bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret); + +static inline int get_min_bandwidth(int dbw, int ubw){ + if (dbw<0) return ubw; + if (ubw<0) return dbw; + return MIN(dbw,ubw); +} + +static inline bool_t bandwidth_is_greater(int bw1, int bw2){ + if (bw1<0) return TRUE; + else if (bw2<0) return FALSE; + else return bw1>=bw2; +} + +#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 + +void linphone_process_authentication(LinphoneCore* lc, eXosip_event_t *ev); +void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev); +void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev); +void linphone_notify_recv(LinphoneCore *lc,eXosip_event_t *ev); +LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid); + +void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev); +void linphone_subscription_closed(LinphoneCore *lc, eXosip_event_t *ev); + +void linphone_call_init_media_params(LinphoneCall *call); + +void linphone_set_sdp(osip_message_t *sip, const char *sdp); + +MSList *find_friend(MSList *fl, const osip_from_t *friend, LinphoneFriend **lf); +LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid); +LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid); + +void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc, const PayloadType *pt); + +#endif /* _PRIVATE_H */ diff --git a/linphone/coreapi/proxy.c b/linphone/coreapi/proxy.c new file mode 100644 index 000000000..458cbadcf --- /dev/null +++ b/linphone/coreapi/proxy.c @@ -0,0 +1,512 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) +*/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "linphonecore.h" +#include +#include +#include "lpconfig.h" +#include "private.h" + + +void linphone_proxy_config_init(LinphoneProxyConfig *obj){ + memset(obj,0,sizeof(LinphoneProxyConfig)); + obj->rid=-1; + obj->expires=3600; +} + +LinphoneProxyConfig *linphone_proxy_config_new(){ + LinphoneProxyConfig *obj=NULL; + obj=ms_new(LinphoneProxyConfig,1); + linphone_proxy_config_init(obj); + return obj; +} + +void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ + if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); + if (obj->reg_identity!=NULL) ms_free(obj->reg_identity); + if (obj->reg_route!=NULL) ms_free(obj->reg_route); +} + +static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ + osip_message_t *msg; + eXosip_lock(); + eXosip_register_build_register(obj->rid,obj->expires,&msg); + eXosip_register_send_register(obj->rid,msg); + eXosip_unlock(); +} + + +int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr){ + int err; + osip_from_t *url; + if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); + obj->reg_proxy=NULL; + if (server_addr!=NULL && strlen(server_addr)>0){ + osip_from_init(&url); + err=osip_from_parse(url,server_addr); + if (err==0 && url->url->host!=NULL){ + obj->reg_proxy=ms_strdup(server_addr); + }else{ + ms_warning("Could not parse %s",server_addr); + } + osip_from_free(url); + } + return 0; +} + +void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity){ + int err=0; + osip_from_t *url; + if (identity!=NULL && strlen(identity)>0){ + osip_from_init(&url); + err=osip_from_parse(url,identity); + if (err<0 || url->url->host==NULL || url->url->username==NULL){ + ms_warning("Could not parse %s",identity); + osip_from_free(url); + return; + } + osip_from_free(url); + } else err=-2; + if (obj->reg_identity!=NULL) { + ms_free(obj->reg_identity); + obj->reg_identity=NULL; + } + if (err==-2) obj->reg_identity=NULL; + else obj->reg_identity=ms_strdup(identity); +} + +void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route) +{ + int err; + osip_uri_param_t *lr_param=NULL; + osip_route_t *rt=NULL; + char *tmproute=NULL; + if (route!=NULL && strlen(route)>0){ + osip_route_init(&rt); + err=osip_route_parse(rt,route); + if (err<0){ + ms_warning("Could not parse %s",route); + osip_route_free(rt); + return ; + } + if (obj->reg_route!=NULL) { + ms_free(obj->reg_route); + obj->reg_route=NULL; + } + + /* check if the lr parameter is set , if not add it */ + osip_uri_uparam_get_byname(rt->url, "lr", &lr_param); + if (lr_param==NULL){ + osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL); + osip_route_to_str(rt,&tmproute); + obj->reg_route=ms_strdup(tmproute); + osip_free(tmproute); + }else obj->reg_route=ms_strdup(route); + }else{ + if (obj->reg_route!=NULL) ms_free(obj->reg_route); + obj->reg_route=NULL; + } +} + +bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){ + if (obj->reg_proxy==NULL){ + if (lc->vtable.display_warning) + lc->vtable.display_warning(lc,_("The sip proxy address you entered is invalid, it must start with \"sip:\"" + " followed by a hostname.")); + return FALSE; + } + if (obj->reg_identity==NULL){ + if (lc->vtable.display_warning) + lc->vtable.display_warning(lc,_("The sip identity you entered is invalid.\nIt should look like " + "sip:username@proxydomain, such as sip:alice@example.net")); + return FALSE; + } + return TRUE; +} + +void linphone_proxy_config_enableregister(LinphoneProxyConfig *obj, bool_t val){ + obj->reg_sendregister=val; +} + +void linphone_proxy_config_expires(LinphoneProxyConfig *obj, int val){ + if (val<=0) val=600; + obj->expires=val; +} + +void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){ + obj->publish=val; +} + +void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ + obj->frozen=TRUE; + if (obj->reg_sendregister){ + /* unregister */ + if (obj->registered) { + osip_message_t *msg; + eXosip_lock(); + eXosip_register_build_register(obj->rid,0,&msg); + eXosip_register_send_register(obj->rid,msg); + eXosip_unlock(); + obj->registered=FALSE; + } + } +} + +void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc) +{ + obj->lc=lc; + linphone_proxy_config_done(obj); +} + +int linphone_proxy_config_done(LinphoneProxyConfig *obj) +{ + const char *id_str; + if (!linphone_proxy_config_check(obj->lc,obj)) return -1; + if (obj->reg_identity!=NULL) id_str=obj->reg_identity; + else id_str=linphone_core_get_primary_contact(obj->lc); + obj->frozen=FALSE; + if (obj->reg_sendregister){ + char *ct=NULL; + osip_message_t *msg=NULL; + obj->rid=eXosip_register_build_initial_register(id_str,obj->reg_proxy,NULL,obj->expires,&msg); + eXosip_register_send_register(obj->rid,msg); + if (ct!=NULL) osip_free(ct); + } + return 0; +} + +void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm) +{ + if (cfg->realm!=NULL) { + ms_free(cfg->realm); + cfg->realm=NULL; + } + if (realm!=NULL) cfg->realm=ms_strdup(realm); +} + +int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, + LinphoneOnlineStatus presence_mode) +{ + osip_message_t *pub; + int i; + const char *from=NULL; + char buf[5000]; + + if (proxy->publish==FALSE) return 0; + + if (proxy!=NULL) { + from=linphone_proxy_config_get_identity(proxy); + } + if (from==NULL) from=linphone_core_get_primary_contact(proxy->lc); + + if (presence_mode==LINPHONE_STATUS_ONLINE) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ +%s\n\ +online\n\ +\n\ +", + from, from); + } + else if (presence_mode==LINPHONE_STATUS_BUSY + ||presence_mode==LINPHONE_STATUS_NOT_DISTURB) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + busy\n\ +\n\ +\n\ +%s\n\ +busy\n\ +\n\ +", + from, from); + } + else if (presence_mode==LINPHONE_STATUS_BERIGHTBACK) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + in-transit\n\ +\n\ +\n\ +%s\n\ +be right back\n\ +\n\ +", + from,from); + } + else if (presence_mode==LINPHONE_STATUS_AWAY + ||presence_mode==LINPHONE_STATUS_MOVED + ||presence_mode==LINPHONE_STATUS_ALT_SERVICE) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + away\n\ +\n\ +\n\ +%s\n\ +away\n\ +\n\ +", + from, from); + } + else if (presence_mode==LINPHONE_STATUS_ONTHEPHONE) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + on-the-phone\n\ +\n\ +\n\ +%s\n\ +on the phone\n\ +\n\ +", + from, from); + } + else if (presence_mode==LINPHONE_STATUS_OUTTOLUNCH) + { + snprintf(buf, 5000, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + meal\n\ +\n\ +\n\ +%s\n\ +out to lunch\n\ +\n\ +", + from, from); + } + else if (presence_mode==LINPHONE_STATUS_OFFLINE) + { + /* */ + snprintf(buf, 5000, "\n\ +\n%s", + from, +"\n\ +\n\ +closed\n\ +\n\ + permanent-absence\n\ +\n\ +\n\ +\n\ +\n\n"); + } + + i = eXosip_build_publish(&pub, (char *)from, (char *)from, NULL, "presence", "1800", "application/pidf+xml", buf); + + if (i<0) + { + ms_message("Failed to build publish request."); + return -1; + } + + eXosip_lock(); + i = eXosip_publish(pub, from); /* should update the sip-if-match parameter + from sip-etag from last 200ok of PUBLISH */ + eXosip_unlock(); + if (i<0) + { + ms_message("Failed to send publish request."); + return -1; + } + return 0; +} + +int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ + if (!linphone_proxy_config_check(lc,cfg)) return -1; + lc->sip_conf.proxies=ms_list_append(lc->sip_conf.proxies,(void *)cfg); + linphone_proxy_config_apply(cfg,lc); + return 0; +} + +extern void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg); + +void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ + MSList *elem; + lc->sip_conf.proxies=ms_list_remove(lc->sip_conf.proxies,(void *)cfg); + /* add to the list of destroyed proxies, so that the possible unREGISTER request can succeed authentication */ + lc->sip_conf.deleted_proxies=ms_list_append(lc->sip_conf.deleted_proxies,(void *)cfg); + /* this will unREGISTER */ + linphone_proxy_config_edit(cfg); + if (lc->default_proxy==cfg){ + lc->default_proxy=NULL; + } + /* invalidate all references to this proxy in our friend list */ + for (elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){ + linphone_friend_check_for_removed_proxy((LinphoneFriend*)elem->data,cfg); + } + +} + +void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config){ + /* check if this proxy is in our list */ + if (config!=NULL){ + if (ms_list_find(lc->sip_conf.proxies,config)==NULL){ + ms_warning("Bad proxy address: it is not in the list !"); + lc->default_proxy=NULL; + return ; + } + } + lc->default_proxy=config; + +} + + +void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){ + if (index<0) linphone_core_set_default_proxy(lc,NULL); + else linphone_core_set_default_proxy(lc,ms_list_nth_data(lc->sip_conf.proxies,index)); +} + +int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config){ + int pos=-1; + if (config!=NULL) *config=lc->default_proxy; + if (lc->default_proxy!=NULL){ + pos=ms_list_position(lc->sip_conf.proxies,ms_list_find(lc->sip_conf.proxies,(void *)lc->default_proxy)); + } + return pos; +} + +static int rid_compare(const void *pcfg,const void *prid){ + const LinphoneProxyConfig *cfg=(const LinphoneProxyConfig*)pcfg; + const int *rid=(const int*)prid; + ms_message("cfg= %s, cfg->rid=%i, rid=%i",cfg->reg_proxy, cfg->rid, *rid); + return cfg->rid-(*rid); +} + +LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid){ + MSList *elem=ms_list_find_custom(lc->sip_conf.proxies,rid_compare, &rid); + if (elem==NULL){ + ms_message("linphone_core_get_proxy_config_from_rid: searching in deleted proxies..."); + elem=ms_list_find_custom(lc->sip_conf.deleted_proxies,rid_compare, &rid); + } + if (elem==NULL) return NULL; + else return (LinphoneProxyConfig*)elem->data; +} + +void linphone_core_retry_proxy_register(LinphoneCore *lc, const char *realm) +{ + MSList *elem; + for (elem=lc->sip_conf.proxies;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; + /*ms_message("linphone_core_retry_proxy_register: cfg->auth_pending=%i, cfg->realm=%s, realm=%s", + cfg->auth_pending,cfg->realm,realm);*/ + if (cfg->auth_pending && cfg->realm!=NULL && strcmp(cfg->realm,realm)==0){ + ms_message("Restarting REGISTER request for %s.",cfg->reg_proxy); + linphone_proxy_config_register(cfg); + } + } +} + +const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc){ + return lc->sip_conf.proxies; +} + + +void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyConfig *obj, int index) +{ + char key[50]; + + sprintf(key,"proxy_%i",index); + lp_config_clean_section(config,key); + if (obj==NULL){ + return; + } + if (obj->reg_proxy!=NULL){ + lp_config_set_string(config,key,"reg_proxy",obj->reg_proxy); + } + if (obj->reg_route!=NULL){ + lp_config_set_string(config,key,"reg_route",obj->reg_route); + } + if (obj->reg_identity!=NULL){ + lp_config_set_string(config,key,"reg_identity",obj->reg_identity); + } + lp_config_set_int(config,key,"reg_expires",obj->expires); + lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister); + lp_config_set_int(config,key,"publish",obj->publish); +} + +LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config, int index) +{ + const char *tmp; + LinphoneProxyConfig *cfg; + char key[50]; + + sprintf(key,"proxy_%i",index); + + if (!lp_config_has_section(config,key)){ + return NULL; + } + tmp=lp_config_get_string(config,key,"reg_proxy",NULL); + if (tmp==NULL) return NULL; + cfg=linphone_proxy_config_new(); + linphone_proxy_config_set_server_addr(cfg,tmp); + + tmp=lp_config_get_string(config,key,"reg_route",NULL); + if (tmp!=NULL) linphone_proxy_config_set_route(cfg,tmp); + + tmp=lp_config_get_string(config,key,"reg_identity",NULL); + if (tmp!=NULL) linphone_proxy_config_set_identity(cfg,tmp); + + linphone_proxy_config_expires(cfg,lp_config_get_int(config,key,"reg_expires",600)); + linphone_proxy_config_enableregister(cfg,lp_config_get_int(config,key,"reg_sendregister",0)); + + linphone_proxy_config_enable_publish(cfg,lp_config_get_int(config,key,"publish",0)); + + return cfg; +} diff --git a/linphone/coreapi/sdphandler.c b/linphone/coreapi/sdphandler.c new file mode 100644 index 000000000..e83af1a17 --- /dev/null +++ b/linphone/coreapi/sdphandler.c @@ -0,0 +1,682 @@ +/* + * Linphone is sip (RFC3261) compatible internet phone. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "sdphandler.h" +#include +#include +#include +#include "linphonecore.h" +#include "ortp/b64.h" + +#define keywordcmp(key,str) strncmp(key,str,strlen(key)) + + +#define sstrdup_sprintf ms_strdup_printf + +#define eXosip_trace(loglevel,args) do \ +{ \ + char *__strmsg; \ + __strmsg=ms_strdup_printf args ; \ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,(loglevel),NULL,"%s\n",__strmsg)); \ + osip_free (__strmsg); \ +}while (0); + + +static char *make_relay_session_id(const char *username, const char *relay){ + /*ideally this should be a hash of the parameters with a random part*/ + char tmp[128]; + int s1=(int)random(); + int s2=(int)random(); + long long int res=((long long int)s1)<<32 | (long long int) s2; + void *src=&res; + b64_encode(src, sizeof(long long int), tmp, sizeof(tmp)); + return osip_strdup(tmp); +} + +char * int_2char(int a){ + char *p=osip_malloc(16); + snprintf(p,16,"%i",a); + return p; +} + +/* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/ +char *sdp_message_a_attr_value_get_with_pt(sdp_message_t *sdp,int pos,int pt,const char *field) +{ + int i,tmppt=0,scanned=0; + char *tmp; + sdp_attribute_t *attr; + for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){ + if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){ + int nb = sscanf(attr->a_att_value,"%i %n",&tmppt,&scanned); + /* the return value may depend on how %n is interpreted by the libc: see manpage*/ + if (nb == 1 || nb==2 ){ + if (pt==tmppt){ + tmp=attr->a_att_value+scanned; + if (strlen(tmp)>0) + return tmp; + } + }else eXosip_trace(OSIP_WARNING,("sdp has a strange a= line (%s) nb=%i",attr->a_att_value,nb)); + } + } + return NULL; +} + +/* return the value of attr "field" */ +char *sdp_message_a_attr_value_get(sdp_message_t *sdp,int pos,const char *field) +{ + int i; + sdp_attribute_t *attr; + for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){ + if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){ + return attr->a_att_value; + } + } + return NULL; +} + +static int _sdp_message_get_a_ptime(sdp_message_t *sdp, int mline){ + int i,ret; + sdp_attribute_t *attr; + for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){ + if (keywordcmp("ptime",attr->a_att_field)==0){ + int nb = sscanf(attr->a_att_value,"%i",&ret); + /* the return value may depend on how %n is interpreted by the libc: see manpage*/ + if (nb == 1){ + return ret; + }else eXosip_trace(OSIP_WARNING,("sdp has a strange a=ptime line (%s) ",attr->a_att_value)); + } + } + return 0; +} + +int +sdp_payload_init (sdp_payload_t * payload) +{ + memset (payload, 0, sizeof (sdp_payload_t)); + return 0; +} + +sdp_context_t *sdp_handler_create_context(sdp_handler_t *handler, const char *localip, const char *username, const char *relay){ + sdp_context_t *ctx=osip_malloc(sizeof(sdp_context_t)); + memset(ctx,0,sizeof(sdp_context_t)); + if (localip!=NULL) ctx->localip=osip_strdup(localip); + ctx->username=osip_strdup(username); + ctx->handler=handler; + if (relay){ + ctx->relay=osip_strdup(relay); + ctx->relay_session_id=make_relay_session_id(username,relay); + } + return ctx; +} + +void sdp_context_set_user_pointer(sdp_context_t * ctx, void* up){ + ctx->reference=up; +} + +void *sdp_context_get_user_pointer(sdp_context_t * ctx){ + return ctx->reference; +} + +int sdp_context_get_status(sdp_context_t* ctx){ + return ctx->negoc_status; +} + +/* generate a template sdp */ +sdp_message_t * +sdp_context_generate_template (sdp_context_t * ctx) +{ + sdp_message_t *local; + int inet6; + + sdp_message_init (&local); + if (strchr(ctx->localip,':')!=NULL){ + inet6=1; + }else inet6=0; + if (!inet6){ + sdp_message_v_version_set (local, osip_strdup ("0")); + sdp_message_o_origin_set (local, osip_strdup (ctx->username), + osip_strdup ("123456"), osip_strdup ("654321"), + osip_strdup ("IN"), osip_strdup ("IP4"), + osip_strdup (ctx->localip)); + sdp_message_s_name_set (local, osip_strdup ("A conversation")); + sdp_message_c_connection_add (local, -1, + osip_strdup ("IN"), osip_strdup ("IP4"), + osip_strdup (ctx->localip), NULL, NULL); + sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0")); + }else{ + sdp_message_v_version_set (local, osip_strdup ("0")); + sdp_message_o_origin_set (local, osip_strdup (ctx->username), + osip_strdup ("123456"), osip_strdup ("654321"), + osip_strdup ("IN"), osip_strdup ("IP6"), + osip_strdup (ctx->localip)); + sdp_message_s_name_set (local, osip_strdup ("A conversation")); + sdp_message_c_connection_add (local, -1, + osip_strdup ("IN"), osip_strdup ("IP6"), + osip_strdup (ctx->localip), NULL, NULL); + sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0")); + } + return local; +} + +static void add_relay_info(sdp_message_t *sdp, int mline, const char *relay, const char *relay_session_id){ + + if (relay) sdp_message_a_attribute_add(sdp, mline, + osip_strdup ("relay-addr"),osip_strdup(relay)); + if (relay_session_id) sdp_message_a_attribute_add(sdp, mline, + osip_strdup ("relay-session-id"), osip_strdup(relay_session_id)); +} + +/* to add payloads to the offer, must be called inside the write_offer callback */ +void +sdp_context_add_payload (sdp_context_t * ctx, sdp_payload_t * payload, char *media) +{ + sdp_message_t *offer = ctx->offer; + char *attr_field; + if (!ctx->incb) + { + eXosip_trace (OSIP_ERROR, + ("You must not call sdp_context_add_*_payload outside the write_offer callback\n")); + abort (); + } + if (payload->proto == NULL) + payload->proto = "RTP/AVP"; + /*printf("payload->line=%i payload->pt=%i\n",payload->line, payload->pt);*/ + if (sdp_message_m_media_get (offer, payload->line) == NULL) + { + /*printf("Adding new mline %s \n",media);*/ + /* need a new line */ + sdp_message_m_media_add (offer, osip_strdup (media), + int_2char (payload->localport), NULL, + osip_strdup (payload->proto)); + if (ctx->relay){ + add_relay_info(offer,payload->line,ctx->relay,ctx->relay_session_id); + } + } + sdp_message_m_payload_add (offer, payload->line, int_2char (payload->pt)); + if (payload->a_rtpmap != NULL) + { + attr_field = + sstrdup_sprintf ("%i %s", payload->pt, + payload->a_rtpmap); + sdp_message_a_attribute_add (offer, payload->line, + osip_strdup ("rtpmap"), attr_field); + } + if (payload->a_fmtp != NULL) + { + attr_field = + sstrdup_sprintf ("%i %s", payload->pt, + payload->a_fmtp); + sdp_message_a_attribute_add (offer, payload->line, osip_strdup ("fmtp"), + attr_field); + } + if (payload->b_as_bandwidth != 0) + { + if (sdp_message_bandwidth_get(offer,payload->line,0)==NULL){ + attr_field = + sstrdup_sprintf ("%i", payload->b_as_bandwidth); + sdp_message_b_bandwidth_add (offer, payload->line, osip_strdup ("AS"), + attr_field); + } + } +} + +void +sdp_context_add_audio_payload (sdp_context_t * ctx, sdp_payload_t * payload) +{ + sdp_context_add_payload (ctx, payload, "audio"); +} + +void +sdp_context_add_video_payload (sdp_context_t * ctx, sdp_payload_t * payload) +{ + sdp_context_add_payload (ctx, payload, "video"); +} + +char * +sdp_context_get_offer ( sdp_context_t * ctx) +{ + sdp_message_t *offer; + sdp_handler_t *sdph=ctx->handler; + char *tmp; + + offer = sdp_context_generate_template (ctx); + /* add audio codecs */ + ctx->offer = offer; + ctx->incb = 1; + if (sdph->set_audio_codecs != NULL) + sdph->set_audio_codecs (ctx); + if (sdph->set_video_codecs != NULL) + sdph->set_video_codecs (ctx); + ctx->incb = 0; + sdp_message_to_str(offer,&tmp); + ctx->offerstr=tmp; + return tmp; +} + + +/* refuse the line */ +static void refuse_mline(sdp_message_t *answer,char *mtype,char *proto, int mline) +{ + sdp_message_m_media_add (answer, + osip_strdup (mtype), + int_2char (0), NULL, + osip_strdup (proto)); + /* add a payload just to comply with sdp RFC.*/ + sdp_message_m_payload_add(answer,mline,int_2char(0)); +} + +static char * parse_relay_addr(char *addr, int *port) +{ + char *semicolon=NULL; + char *p; + + *port=56789; + semicolon=strchr(addr,':'); + for (p=addr+strlen(addr)-1;p>addr;p--){ + if (*p==':') { + semicolon=p; + break; + } + } + if (semicolon){ + *port=atoi(semicolon+1); + *semicolon='\0'; + } + return addr; +} + + +char * +sdp_context_get_answer ( sdp_context_t *ctx,sdp_message_t *remote) +{ + sdp_message_t *answer=NULL; + char *mtype=NULL, *tmp=NULL; + char *proto=NULL, *port=NULL, *pt=NULL; + int i, j, ncodec, m_lines_accepted = 0; + int err; + sdp_payload_t payload; + sdp_handler_t *sdph=ctx->handler; + sdp_bandwidth_t *sbw=NULL; + char *relay; + + tmp = sdp_message_c_addr_get (remote, 0, 0); + if (tmp == NULL) + tmp = sdp_message_c_addr_get (remote, -1, 0); + if (ctx->localip==NULL) { + /* NULL means guess, otherwise we use the address given as localip */ + ctx->localip=osip_malloc(128); + eXosip_guess_localip(strchr(tmp,':') ? AF_INET6 : AF_INET,ctx->localip,128); + } + else eXosip_trace(OSIP_INFO1,("Using firewall address in sdp.")); + + answer = sdp_context_generate_template (ctx); + + /* for each m= line */ + for (i = 0; !sdp_message_endof_media (remote, i); i++) + { + sdp_payload_init(&payload); + mtype = sdp_message_m_media_get (remote, i); + proto = sdp_message_m_proto_get (remote, i); + port = sdp_message_m_port_get (remote, i); + payload.remoteport = osip_atoi (port); + payload.proto = proto; + payload.line = i; + payload.c_addr = sdp_message_c_addr_get (remote, i, 0); + if (payload.c_addr == NULL) + payload.c_addr = sdp_message_c_addr_get (remote, -1, 0); + /*parse relay address if given*/ + relay=sdp_message_a_attr_value_get(remote,i,"relay-addr"); + if (relay){ + payload.relay_host=parse_relay_addr(relay,&payload.relay_port); + } + payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id"); + /* get application specific bandwidth, if any */ + for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;j++){ + if (strcasecmp(sbw->b_bwtype,"AS")==0) payload.b_as_bandwidth=atoi(sbw->b_bandwidth); + } + payload.a_ptime=_sdp_message_get_a_ptime(remote,i); + if (keywordcmp ("audio", mtype) == 0) + { + if (sdph->accept_audio_codecs != NULL) + { + ncodec = 0; + /* for each payload type */ + for (j = 0; + ((pt = + sdp_message_m_payload_get (remote, i, + j)) != NULL); j++) + { + payload.pt = osip_atoi (pt); + /* get the rtpmap associated to this codec, if any */ + payload.a_rtpmap = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "rtpmap"); + /* get the fmtp, if any */ + payload.a_fmtp = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "fmtp"); + + /* ask the application if this codec is supported */ + err = sdph->accept_audio_codecs (ctx, + &payload); + if (err == 0 && payload.localport > 0) + { + ncodec++; + /* codec accepted */ + if (ncodec == 1) + { + /* first codec accepted, setup the line */ + sdp_message_m_media_add + (answer, + osip_strdup + (mtype), + int_2char + (payload. + localport), + NULL, + osip_strdup + (proto)); + /* and accept the remote relay addr if we planned to use our own */ + if (ctx->relay!=NULL && relay){ + add_relay_info(answer,i,relay,payload.relay_session_id); + } + } + /* add the payload, rtpmap, fmtp */ + sdp_message_m_payload_add (answer, i, + int_2char + (payload. + pt)); + if (payload.a_rtpmap != NULL) + { + sdp_message_a_attribute_add + (answer, i, + osip_strdup + ("rtpmap"), + sstrdup_sprintf + ("%i %s", + payload.pt, + payload. + a_rtpmap)); + } + if (payload.a_fmtp != NULL) + { + sdp_message_a_attribute_add + (answer, i, + osip_strdup + ("fmtp"), + sstrdup_sprintf + ("%i %s", + payload.pt, + payload. + a_fmtp)); + } + if (payload.b_as_bandwidth != + 0) + { + if (sdp_message_bandwidth_get(answer,i,0)==NULL) + sdp_message_b_bandwidth_add + (answer, i, + osip_strdup + ("AS"), + sstrdup_sprintf + ("%i", + payload. + b_as_bandwidth)); + } + } + } + if (ncodec == 0) + { + /* refuse the line */ + refuse_mline(answer,mtype,proto,i); + + } + else + m_lines_accepted++; + } + else + { + /* refuse this line (leave port to 0) */ + refuse_mline(answer,mtype,proto,i); + } + + } + else if (keywordcmp ("video", mtype) == 0) + { + if (sdph->accept_video_codecs != NULL) + { + ncodec = 0; + /* for each payload type */ + for (j = 0; + ((pt = + sdp_message_m_payload_get (remote, i, + j)) != NULL); j++) + { + payload.pt = osip_atoi (pt); + /* get the rtpmap associated to this codec, if any */ + payload.a_rtpmap = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "rtpmap"); + /* get the fmtp, if any */ + payload.a_fmtp = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "fmtp"); + /* ask the application if this codec is supported */ + err = sdph->accept_video_codecs (ctx, + &payload); + if (err == 0 && payload.localport > 0) + { + ncodec++; + /* codec accepted */ + if (ncodec == 1) + { + /* first codec accepted, setup the line */ + sdp_message_m_media_add + (answer, + osip_strdup + (mtype), + int_2char + (payload.localport), NULL, + osip_strdup + (proto)); + /* and accept the remote relay addr if we planned to use our own */ + if (ctx->relay!=NULL && relay){ + add_relay_info(answer,i,relay,payload.relay_session_id); + } + } + /* add the payload, rtpmap, fmtp */ + sdp_message_m_payload_add (answer, i, + int_2char + (payload. + pt)); + if (payload.a_rtpmap != NULL) + { + sdp_message_a_attribute_add + (answer, i, + osip_strdup + ("rtpmap"), + sstrdup_sprintf + ("%i %s", + payload.pt, + payload. + a_rtpmap)); + } + if (payload.a_fmtp != NULL) + { + sdp_message_a_attribute_add + (answer, i, + osip_strdup + ("fmtp"), + sstrdup_sprintf + ("%i %s", + payload.pt, + payload. + a_fmtp)); + } + if (payload.b_as_bandwidth !=0) + { + if (sdp_message_bandwidth_get(answer,i,0)==NULL) + sdp_message_b_bandwidth_add + (answer, i, + osip_strdup + ("AS"), + sstrdup_sprintf + ("%i", + payload. + b_as_bandwidth)); + } + } + } + if (ncodec == 0) + { + /* refuse the line */ + refuse_mline(answer,mtype,proto,i); + } + else + m_lines_accepted++; + } + else + { + /* refuse the line */ + refuse_mline(answer,mtype,proto,i); + } + } + } + if (ctx->answer!=NULL) + sdp_message_free(ctx->answer); + ctx->answer = answer; + if (m_lines_accepted > 0){ + ctx->negoc_status = 200; + sdp_message_to_str(answer,&tmp); + if (ctx->answerstr!=NULL) + osip_free(ctx->answerstr); + ctx->answerstr=tmp; + return tmp; + }else{ + ctx->negoc_status = 415; + return NULL; + } +} + +void +sdp_context_read_answer (sdp_context_t *ctx, sdp_message_t *remote) +{ + char *mtype; + char *proto, *port, *pt; + int i, j,err; + char *relay; + sdp_payload_t payload,arg_payload; + sdp_handler_t *sdph=ctx->handler; + sdp_bandwidth_t *sbw=NULL; + /* for each m= line */ + for (i = 0; !sdp_message_endof_media (remote, i); i++) + { + sdp_payload_init(&payload); + mtype = sdp_message_m_media_get (remote, i); + proto = sdp_message_m_proto_get (remote, i); + port = sdp_message_m_port_get (remote, i); + payload.remoteport = osip_atoi (port); + payload.localport = osip_atoi (sdp_message_m_port_get (ctx->offer, i)); + payload.proto = proto; + payload.line = i; + payload.c_addr = sdp_message_c_addr_get (remote, i, 0); + if (payload.c_addr == NULL) + payload.c_addr = sdp_message_c_addr_get (remote, -1, 0); + /*parse relay address if given*/ + relay=sdp_message_a_attr_value_get(remote,i,"relay-addr"); + if (relay){ + payload.relay_host=parse_relay_addr(relay,&payload.relay_port); + } + payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id"); + for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;++j){ + if (strcasecmp(sbw->b_bwtype,"AS")==0) payload.b_as_bandwidth=atoi(sbw->b_bandwidth); + } + payload.a_ptime=_sdp_message_get_a_ptime(remote,i); + if (keywordcmp ("audio", mtype) == 0) + { + if (sdph->get_audio_codecs != NULL) + { + /* for each payload type */ + for (j = 0; + ((pt = + sdp_message_m_payload_get (remote, i, + j)) != NULL); j++) + { + payload.pt = osip_atoi (pt); + /* get the rtpmap associated to this codec, if any */ + payload.a_rtpmap = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "rtpmap"); + /* get the fmtp, if any */ + payload.a_fmtp = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "fmtp"); + /* ask the application if this codec is supported */ + memcpy(&arg_payload,&payload,sizeof(payload)); + err = sdph->get_audio_codecs (ctx, + &arg_payload); + } + } + } + else if (keywordcmp ("video", mtype) == 0) + { + if (sdph->get_video_codecs != NULL) + { + /* for each payload type */ + for (j = 0; + ((pt = + sdp_message_m_payload_get (remote, i, + j)) != NULL); j++) + { + payload.pt = osip_atoi (pt); + /* get the rtpmap associated to this codec, if any */ + payload.a_rtpmap = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "rtpmap"); + /* get the fmtp, if any */ + payload.a_fmtp = + sdp_message_a_attr_value_get_with_pt + (remote, i, payload.pt, + "fmtp"); + /* ask the application if this codec is supported */ + memcpy(&arg_payload,&payload,sizeof(payload)); + err = sdph->get_video_codecs (ctx, + &arg_payload); + } + } + } + } +} +void sdp_context_free(sdp_context_t *ctx){ + osip_free(ctx->localip); + osip_free(ctx->username); + if (ctx->offer!=NULL) sdp_message_free(ctx->offer); + if (ctx->answer!=NULL) sdp_message_free(ctx->answer); + if (ctx->offerstr!=NULL) osip_free(ctx->offerstr); + if (ctx->answerstr!=NULL) osip_free(ctx->answerstr); + if (ctx->relay!=NULL) osip_free(ctx->relay); + if (ctx->relay_session_id!=NULL) osip_free(ctx->relay_session_id); + osip_free(ctx); +} diff --git a/linphone/coreapi/sdphandler.h b/linphone/coreapi/sdphandler.h new file mode 100644 index 000000000..b3e811b70 --- /dev/null +++ b/linphone/coreapi/sdphandler.h @@ -0,0 +1,101 @@ + /* + * Linphone is sip (RFC3261) compatible internet phone. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SDP_HANDLER_H +#define SDP_HANDLER_H + +#include +#include "linphonecore.h" + +typedef struct _sdp_payload +{ + int line; /* the index of the m= line */ + int pt; /*payload type */ + int localport; + int remoteport; + int b_as_bandwidth; /* application specific bandwidth */ + char *proto; + char *c_nettype; + char *c_addrtype; + char *c_addr; + char *c_addr_multicast_ttl; + char *c_addr_multicast_int; + char *a_rtpmap; + char *a_fmtp; + char *relay_host; + int relay_port; + char *relay_session_id; + int a_ptime; +} sdp_payload_t; + +typedef struct _sdp_context sdp_context_t; + +typedef int (*sdp_handler_read_codec_func_t) (struct _sdp_context *, + sdp_payload_t *); +typedef int (*sdp_handler_write_codec_func_t) (struct _sdp_context *); + +typedef struct _sdp_handler +{ + sdp_handler_read_codec_func_t accept_audio_codecs; /*from remote sdp */ + sdp_handler_read_codec_func_t accept_video_codecs; /*from remote sdp */ + sdp_handler_write_codec_func_t set_audio_codecs; /*to local sdp */ + sdp_handler_write_codec_func_t set_video_codecs; /*to local sdp */ + sdp_handler_read_codec_func_t get_audio_codecs; /*from incoming answer */ + sdp_handler_read_codec_func_t get_video_codecs; /*from incoming answer */ +} sdp_handler_t; + + +typedef enum _sdp_context_state +{ + SDP_CONTEXT_STATE_INIT, + SDP_CONTEXT_STATE_NEGOCIATION_OPENED, + SDP_CONTEXT_STATE_NEGOCIATION_CLOSED +} sdp_context_state_t; + +struct _sdp_context +{ + sdp_handler_t *handler; + char *localip; + char *username; + void *reference; + sdp_message_t *offer; /* the local sdp to be used for outgoing request */ + char *offerstr; + sdp_message_t *answer; /* the local sdp generated from an inc request */ + char *answerstr; + char *relay; + char *relay_session_id; + int negoc_status; /* in sip code */ + int incb; + sdp_context_state_t state; +}; + +/* create a context for a sdp negociation: localip is the ip address to be used in the sdp message, can +be a firewall address. +It can be null when negociating for an incoming offer; In that case it will be guessed. */ +sdp_context_t *sdp_handler_create_context(sdp_handler_t *handler, const char *localip, const char *username, const char *relay); +void sdp_context_set_user_pointer(sdp_context_t * ctx, void* up); +void *sdp_context_get_user_pointer(sdp_context_t * ctx); +void sdp_context_add_audio_payload( sdp_context_t * ctx, sdp_payload_t * payload); +void sdp_context_add_video_payload( sdp_context_t * ctx, sdp_payload_t * payload); +char * sdp_context_get_offer(sdp_context_t *ctx); +char * sdp_context_get_answer(sdp_context_t* ctx, sdp_message_t *remote_offer); +int sdp_context_get_status(sdp_context_t* ctx); +void sdp_context_read_answer(sdp_context_t *ctx, sdp_message_t *remote_answer); +void sdp_context_free(sdp_context_t *ctx); + +int sdp_payload_init (sdp_payload_t * payload); +#endif diff --git a/linphone/debian/.cvsignore b/linphone/debian/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/debian/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/debian/Makefile.am b/linphone/debian/Makefile.am new file mode 100644 index 000000000..6c6eb29bc --- /dev/null +++ b/linphone/debian/Makefile.am @@ -0,0 +1,15 @@ +EXTRA_DIST= copyright dirs manpage.sgml.ex rules \ + control docs manpage.1.ex menu watch.ex changelog + + +changelog: changelog.stamp + echo -n -e "linphone (">changelog + echo -n -e $(VERSION)>>changelog + echo -n -e "-1) unstable; urgency=low\n\n">>changelog + echo -n -e " * New Release.\n\n">>changelog + echo -n -e " -- Simon Morlat ">>changelog + date -R >>changelog + touch changelog.stamp + +changelog.stamp: + touch changelog.stamp diff --git a/linphone/debian/control b/linphone/debian/control new file mode 100644 index 000000000..fef2eba9d --- /dev/null +++ b/linphone/debian/control @@ -0,0 +1,14 @@ +Source: linphone +Section: sound +Priority: optional +Maintainer: Uwe Steinmann +Build-Depends: debhelper (>> 3.0.0), libosip0-dev (>= 0.9.6), libasound2-dev (>=0.9.4) +Standards-Version: 3.5.2 + +Package: linphone +Architecture: any +Depends: ${shlibs:Depends}, libosip0 (>= 0.9.6), libspeex1, libasound2 (>=0.9.4) +Description: A sip phone + Linphone is a web phone: it let you phone to your friends anywhere in the + whole world, freely, simply by using the internet. It is compatible with the + well known SIP protocol. diff --git a/linphone/debian/copyright b/linphone/debian/copyright new file mode 100644 index 000000000..da0129d9f --- /dev/null +++ b/linphone/debian/copyright @@ -0,0 +1,10 @@ +This package was debianized by Uwe Steinmann on +Thu, 28 Feb 2002 08:29:57 +0100. + +It was downloaded from http://www.linphone.org + +Upstream Author(s): Simon Morlat + +Copyright: + +GPL diff --git a/linphone/debian/dirs b/linphone/debian/dirs new file mode 100644 index 000000000..ca882bbb7 --- /dev/null +++ b/linphone/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/linphone/debian/docs b/linphone/debian/docs new file mode 100644 index 000000000..5203c2307 --- /dev/null +++ b/linphone/debian/docs @@ -0,0 +1,3 @@ +BUGS +NEWS +README diff --git a/linphone/debian/manpage.1.ex b/linphone/debian/manpage.1.ex new file mode 100644 index 000000000..f872c3353 --- /dev/null +++ b/linphone/debian/manpage.1.ex @@ -0,0 +1,60 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH LINPHONE SECTION "February 28, 2002" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +linphone \- program to do something +.SH SYNOPSIS +.B linphone +.RI [ options ] " files" ... +.br +.B bar +.RI [ options ] " files" ... +.SH DESCRIPTION +This manual page documents briefly the +.B linphone +and +.B bar +commands. +This manual page was written for the Debian distribution +because the original program does not have a manual page. +Instead, it has documentation in the GNU Info format; see below. +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBlinphone\fP is a program that... +.SH OPTIONS +These programs follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options is included below. +For a complete description, see the Info files. +.TP +.B \-h, \-\-help +Show summary of options. +.TP +.B \-v, \-\-version +Show version of program. +.SH SEE ALSO +.BR bar (1), +.BR baz (1). +.br +The programs are documented fully by +.IR "The Rise and Fall of a Fooish Bar" , +available via the Info system. +.SH AUTHOR +This manual page was written by Uwe Steinmann , +for the Debian GNU/Linux system (but may be used by others). diff --git a/linphone/debian/manpage.sgml.ex b/linphone/debian/manpage.sgml.ex new file mode 100644 index 000000000..0b97c1700 --- /dev/null +++ b/linphone/debian/manpage.sgml.ex @@ -0,0 +1,152 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + FIRSTNAME"> + SURNAME"> + + February 28, 2002"> + + SECTION"> + uwe@steinmann.cx"> + + LINPHONE"> + + + Debian"> + GNU"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2001 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + program to do something + + + + &dhpackage; + + + + + + + + DESCRIPTION + + This manual page documents briefly the + &dhpackage; and bar + commands. + + This manual page was written for the &debian; distribution + because the original program does not have a manual page. + Instead, it has documentation in the &gnu; + Info format; see below. + + &dhpackage; is a program that... + + + + OPTIONS + + These programs follow the usual GNU command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. For a complete description, see the + Info files. + + + + + + + + Show summary of options. + + + + + + + + Show version of program. + + + + + + SEE ALSO + + bar (1), baz (1). + + The programs are documented fully by The Rise and + Fall of a Fooish Bar available via the + Info system. + + + AUTHOR + + This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation + License, Version 1.1 or any later version published by the Free + Software Foundation; with no Invariant Sections, no Front-Cover + Texts and no Back-Cover Texts. + + +
+ + + + diff --git a/linphone/debian/menu b/linphone/debian/menu new file mode 100644 index 000000000..b21a3934a --- /dev/null +++ b/linphone/debian/menu @@ -0,0 +1,3 @@ +?package(linphone):needs=X11 section=Apps/Net \ + title="Linphone" command="/usr/bin/linphone" hints="Telephony"\ + icon="/usr/share/pixmaps/linphone/linphone2.xpm" diff --git a/linphone/debian/rules b/linphone/debian/rules new file mode 100755 index 000000000..621932a43 --- /dev/null +++ b/linphone/debian/rules @@ -0,0 +1,107 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatibility version to use. +export DH_COMPAT=3 + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) + CFLAGS += -g +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --disable-static --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --sysconfdir=/etc + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #/usr/bin/docbook-to-man debian/linphone.sgml > linphone.1 + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -make clean + -make distclean + -test -r /usr/share/misc/config.sub && \ + -cp -f /usr/share/misc/config.sub config.sub + -test -r /usr/share/misc/config.guess && \ + -cp -f /usr/share/misc/config.guess config.guess + + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/linphone. + $(MAKE) install PIXDESTDIR=$(CURDIR)/debian/linphone prefix=$(CURDIR)/debian/linphone/usr sysconfdir=$(CURDIR)/debian/linphone/etc + # remove speex libs, in order to not to conflict with speex debian package. + rm -f $(CURDIR)/debian/linphone/usr/lib/libspeex* \ + $(CURDIR)/debian/linphone/usr/bin/speex* \ + $(CURDIR)/debian/linphone/usr/include/speex* \ + $(CURDIR)/debian/linphone/usr/share/man/man1/speex* + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit + dh_installcron + dh_installman + dh_installinfo +# dh_undocumented + dh_installchangelogs ChangeLog + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/linphone/debian/watch.ex b/linphone/debian/watch.ex new file mode 100644 index 000000000..2002b0f76 --- /dev/null +++ b/linphone/debian/watch.ex @@ -0,0 +1,5 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# Site Directory Pattern Version Script +sunsite.unc.edu /pub/Linux/Incoming linphone-(.*)\.tar\.gz debian uupdate diff --git a/linphone/developer-docs/.cvsignore b/linphone/developer-docs/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/developer-docs/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/developer-docs/mediastreamer/.cvsignore b/linphone/developer-docs/mediastreamer/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/developer-docs/mediastreamer/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/exosip/.cvsignore b/linphone/exosip/.cvsignore new file mode 100644 index 000000000..09980ae6b --- /dev/null +++ b/linphone/exosip/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la diff --git a/linphone/exosip/Makefile.am b/linphone/exosip/Makefile.am new file mode 100644 index 000000000..067b1eebd --- /dev/null +++ b/linphone/exosip/Makefile.am @@ -0,0 +1,16 @@ +noinst_LTLIBRARIES = libeXosip.la + + +AM_CFLAGS = $(EXOSIP_CFLAGS) + +libeXosip_la_SOURCES = eXosip.c \ +jrequest.c jresponse.c jcallback.c jdialog.c udp.c \ +jcall.c jreg.c jfreinds.c jidentity.c eXutils.c \ +jnotify.c jsubscribers.c jsubscribe.c jevents.c \ +sdp_offans.c misc.c eXosip2.h \ +jpipe.c jpipe.h jauth.c jpublish.c \ +eXosip.h eXosip_cfg.h + +libeXosip_la_LIBADD = $(EXOSIP_LIBS) + +INCLUDES = -I$(top_srcdir) diff --git a/linphone/exosip/eXosip.c b/linphone/exosip/eXosip.c new file mode 100644 index 000000000..729927b48 --- /dev/null +++ b/linphone/exosip/eXosip.c @@ -0,0 +1,3192 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include +#include + +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include +#endif + +/* Private functions */ +static int eXosip_create_transaction(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_message_t *request); +static int eXosip_create_cancel_transaction(eXosip_call_t *jc, + eXosip_dialog_t *jd, + osip_message_t *request); +static jauthinfo_t *eXosip_find_authentication_info(const char *username, + const char *realm); +static int eXosip_add_authentication_information(osip_message_t *req, + osip_message_t *last_response); +static void *eXosip_thread(void *arg); +static int eXosip_execute(void); +static osip_message_t *eXosip_prepare_request_for_auth(osip_message_t *msg); + +static int eXosip_update_top_via(osip_message_t *sip); + + +eXosip_t eXosip; + +void eXosip_set_firewallip(const char *firewall_address) +{ + if (firewall_address==NULL) return; + snprintf(eXosip.j_firewall_ip,50, "%s", firewall_address); +} + +void eXosip_set_nattype(const char *nat_type) +{ + osip_strncpy(eXosip.nat_type, (nat_type ? nat_type : ""), sizeof(eXosip.nat_type)-1); +} + +void eXosip_force_proxy(const char *proxyurl) +{ + osip_strncpy(eXosip.forced_proxy, (proxyurl ? proxyurl : ""), sizeof(eXosip.forced_proxy)-1); +} + +int eXosip_guess_localip(int family, char *address, int size) +{ + return eXosip_guess_ip_for_via(family, address, size); +} + +void eXosip_get_localip(char *ip) +{ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip_get_localip IS DEPRECATED. Use eXosip_guess_localip!\n")); + eXosip_guess_ip_for_via(AF_INET, ip, 15); +} + +int +eXosip_is_public_address(const char *c_address) +{ + return (0!=strncmp(c_address, "192.168",7) + && 0!=strncmp(c_address, "10.",3) + && 0!=strncmp(c_address, "172.16.",7) + && 0!=strncmp(c_address, "172.17.",7) + && 0!=strncmp(c_address, "172.18.",7) + && 0!=strncmp(c_address, "172.19.",7) + && 0!=strncmp(c_address, "172.20.",7) + && 0!=strncmp(c_address, "172.21.",7) + && 0!=strncmp(c_address, "172.22.",7) + && 0!=strncmp(c_address, "172.23.",7) + && 0!=strncmp(c_address, "172.24.",7) + && 0!=strncmp(c_address, "172.25.",7) + && 0!=strncmp(c_address, "172.26.",7) + && 0!=strncmp(c_address, "172.27.",7) + && 0!=strncmp(c_address, "172.28.",7) + && 0!=strncmp(c_address, "172.29.",7) + && 0!=strncmp(c_address, "172.30.",7) + && 0!=strncmp(c_address, "172.31.",7) + && 0!=strncmp(c_address, "169.254",7)); +} + + +void __eXosip_wakeup(void) +{ + jpipe_write(eXosip.j_socketctl, "w", 1); +} + +void __eXosip_wakeup_event(void) +{ + jpipe_write(eXosip.j_socketctl_event, "w", 1); +} + + +int +eXosip_lock(void) +{ + return osip_mutex_lock((struct osip_mutex*)eXosip.j_mutexlock); +} + +int +eXosip_unlock(void) +{ + return osip_mutex_unlock((struct osip_mutex*)eXosip.j_mutexlock); +} + + +jfriend_t *jfriend_get(void) +{ + return eXosip.j_friends; +} + +void jfriend_remove(jfriend_t *fr) +{ + REMOVE_ELEMENT(eXosip.j_friends, fr); +} + +jsubscriber_t *jsubscriber_get(void) +{ + return eXosip.j_subscribers; +} + +jidentity_t *jidentity_get(void) +{ + return eXosip.j_identitys; +} + +void +eXosip_kill_transaction (osip_list_t * transactions) +{ + osip_transaction_t *transaction; + + if (!osip_list_eol (transactions, 0)) + { + /* some transaction are still used by osip, + transaction should be released by modules! */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "module sfp: _osip_kill_transaction transaction should be released by modules!\n")); + } + + while (!osip_list_eol (transactions, 0)) + { + transaction = osip_list_get (transactions, 0); + + __eXosip_delete_jinfo(transaction); + osip_transaction_free (transaction); + } +} + +void eXosip_quit(void) +{ + jauthinfo_t *jauthinfo; + eXosip_call_t *jc; + eXosip_notify_t *jn; + eXosip_subscribe_t *js; + eXosip_reg_t *jreg; + eXosip_pub_t *jpub; + int i; + + eXosip.j_stop_ua = 1; /* ask to quit the application */ + __eXosip_wakeup(); + __eXosip_wakeup_event(); + + i = osip_thread_join((struct osip_thread*)eXosip.j_thread); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: can't terminate thread!")); + } + osip_free((struct osip_thread*)eXosip.j_thread); + + jpipe_close(eXosip.j_socketctl); + jpipe_close(eXosip.j_socketctl_event); + + osip_free(eXosip.localip); + osip_free(eXosip.localport); + osip_free(eXosip.user_agent); + + eXosip.j_input = 0; + eXosip.j_output = 0; + + for (jc = eXosip.j_calls; jc!=NULL;jc = eXosip.j_calls) + { + REMOVE_ELEMENT(eXosip.j_calls, jc); + eXosip_call_free(jc); + } + + for (js = eXosip.j_subscribes; js!=NULL;js = eXosip.j_subscribes) + { + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + } + + for (jn = eXosip.j_notifies; jn!=NULL;jn = eXosip.j_notifies) + { + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + } + + osip_mutex_destroy((struct osip_mutex*)eXosip.j_mutexlock); + osip_cond_destroy((struct osip_cond*)eXosip.j_cond); + + eXosip_sdp_negotiation_free(eXosip.osip_negotiation); + + if (eXosip.j_input) + fclose(eXosip.j_input); + if (eXosip.j_output) + osip_free(eXosip.j_output); + if (eXosip.j_socket) + close(eXosip.j_socket); + + for (jreg = eXosip.j_reg; jreg!=NULL; jreg = eXosip.j_reg) + { + REMOVE_ELEMENT(eXosip.j_reg, jreg); + eXosip_reg_free(jreg); + } + + for (jpub = eXosip.j_pub; jpub!=NULL; jpub = eXosip.j_pub) + { + REMOVE_ELEMENT(eXosip.j_pub, jpub); + _eXosip_pub_free(jpub); + } + + /* should be moved to method with an argument */ + jfriend_unload(); + jidentity_unload(); + jsubscriber_unload(); + + /* + for (jid = eXosip.j_identitys; jid!=NULL; jid = eXosip.j_identitys) + { + REMOVE_ELEMENT(eXosip.j_identitys, jid); + eXosip_friend_free(jid); + } + + for (jfr = eXosip.j_friends; jfr!=NULL; jfr = eXosip.j_friends) + { + REMOVE_ELEMENT(eXosip.j_friends, jfr); + eXosip_reg_free(jfr); + } + */ + + while (!osip_list_eol(eXosip.j_transactions, 0)) + { + osip_transaction_t *tr = (osip_transaction_t*) osip_list_get(eXosip.j_transactions, 0); + if (tr->state==IST_TERMINATED || tr->state==ICT_TERMINATED + || tr->state== NICT_TERMINATED || tr->state==NIST_TERMINATED) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Release a terminated transaction\n")); + osip_list_remove(eXosip.j_transactions, 0); + __eXosip_delete_jinfo(tr); + osip_transaction_free(tr); + } + else + { + osip_list_remove(eXosip.j_transactions, 0); + __eXosip_delete_jinfo(tr); + osip_transaction_free(tr); + } + } + + osip_free(eXosip.j_transactions); + + eXosip_kill_transaction (eXosip.j_osip->osip_ict_transactions); + eXosip_kill_transaction (eXosip.j_osip->osip_nict_transactions); + eXosip_kill_transaction (eXosip.j_osip->osip_ist_transactions); + eXosip_kill_transaction (eXosip.j_osip->osip_nist_transactions); + osip_release (eXosip.j_osip); + + if (eXosip.j_events!=NULL) + { + eXosip_event_t *ev; + for(ev=osip_fifo_tryget(eXosip.j_events);ev!=NULL; + ev=osip_fifo_tryget(eXosip.j_events)) + eXosip_event_free(ev); + } + + osip_fifo_free(eXosip.j_events); + + for (jauthinfo = eXosip.authinfos; jauthinfo!=NULL; + jauthinfo = eXosip.authinfos) + { + REMOVE_ELEMENT(eXosip.authinfos, jauthinfo); + osip_free(jauthinfo); + } + + return ; +} + +static int eXosip_execute ( void ) +{ + struct timeval lower_tv; + int i; + + osip_timers_gettimeout(eXosip.j_osip, &lower_tv); + if (lower_tv.tv_sec>15) + { + lower_tv.tv_sec = 15; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: Reseting timer to 15s before waking up!\n")); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: timer sec:%i usec:%i!\n", + lower_tv.tv_sec, lower_tv.tv_usec)); + } + i = eXosip_read_message(1, lower_tv.tv_sec, lower_tv.tv_usec); + + if (i==-2) + { + return -2; + } + + eXosip_lock(); + osip_timers_ict_execute(eXosip.j_osip); + osip_timers_nict_execute(eXosip.j_osip); + osip_timers_ist_execute(eXosip.j_osip); + osip_timers_nist_execute(eXosip.j_osip); + + osip_ict_execute(eXosip.j_osip); + osip_nict_execute(eXosip.j_osip); + osip_ist_execute(eXosip.j_osip); + osip_nist_execute(eXosip.j_osip); + + /* free all Calls that are in the TERMINATED STATE? */ + eXosip_release_terminated_calls(); + + eXosip_unlock(); + + return 0; +} + +void *eXosip_thread ( void *arg ) +{ + int i; + while (eXosip.j_stop_ua==0) + { + i = eXosip_execute(); + if (i==-2) + osip_thread_exit(); + } + osip_thread_exit(); + return NULL; +} + +static int ipv6_enable = 0; + +void eXosip_enable_ipv6(int _ipv6_enable) +{ + ipv6_enable = _ipv6_enable; +} + +int eXosip_init(FILE *input, FILE *output, int port) +{ + osip_t *osip; + int i; + if (port<=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: port must be higher than 0!\n")); + return -1; + } + memset(&eXosip, 0, sizeof(eXosip)); + eXosip.localip = (char *) osip_malloc(50); + memset(eXosip.localip, '\0', 50); + + if (ipv6_enable == 0) + eXosip.ip_family = AF_INET; + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "IPv6 is enabled. Pls report bugs\n")); + eXosip.ip_family = AF_INET6; + } + + eXosip_guess_localip(eXosip.ip_family, eXosip.localip, 49); + if (eXosip.localip[0]=='\0') + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No ethernet interface found!\n")); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: using 127.0.0.1 (debug mode)!\n")); + strcpy(eXosip.localip, "127.0.0.1"); + /* we should always fallback on something. The linphone user will surely + start linphone BEFORE setting its dial up connection.*/ + } + eXosip.user_agent = osip_strdup("eXosip/" EXOSIP_VERSION); + + eXosip_set_mode(EVENT_MODE); + eXosip.j_input = input; + eXosip.j_output = output; + eXosip.j_calls = NULL; + eXosip.j_stop_ua = 0; + eXosip.j_thread = NULL; + eXosip.j_transactions = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(eXosip.j_transactions); + eXosip.j_reg = NULL; + + eXosip.j_cond = (struct osip_cond*)osip_cond_init(); + + eXosip.j_mutexlock = (struct osip_mutex*)osip_mutex_init(); + + if (-1==osip_init(&osip)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: Cannot initialize osip!\n")); + return -1; + } + + eXosip_sdp_negotiation_init(&(eXosip.osip_negotiation)); + + eXosip_sdp_negotiation_add_codec(osip_strdup("0"), + NULL, + osip_strdup("RTP/AVP"), + NULL, NULL, NULL, + NULL,NULL, + osip_strdup("0 PCMU/8000")); + + eXosip_sdp_negotiation_add_codec(osip_strdup("8"), + NULL, + osip_strdup("RTP/AVP"), + NULL, NULL, NULL, + NULL,NULL, + osip_strdup("8 PCMA/8000")); + + osip_set_application_context(osip, &eXosip); + + eXosip_set_callbacks(osip); + + eXosip.j_osip = osip; + +#ifdef WIN32 + /* Initializing windows socket library */ + { + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(1,1); + if(i = WSAStartup(wVersionRequested, &wsaData)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: Unable to initialize WINSOCK, reason: %d\n",i)); + /* return -1; It might be already initilized?? */ + } + } +#endif + + /* open a TCP socket to wake up the application when needed. */ + eXosip.j_socketctl = jpipe(); + if (eXosip.j_socketctl==NULL) + return -1; + + eXosip.j_socketctl_event = jpipe(); + if (eXosip.j_socketctl_event==NULL) + return -1; + if (ipv6_enable == 0) + { + eXosip.j_socket = (int)socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (eXosip.j_socket==-1) + return -1; + + { + struct sockaddr_in raddr; + raddr.sin_addr.s_addr = htons(INADDR_ANY); + raddr.sin_port = htons((short)port); + raddr.sin_family = AF_INET; + + i = bind(eXosip.j_socket, (struct sockaddr *)&raddr, sizeof(raddr)); + if (i < 0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: Cannot bind on port: %i!\n", i)); + return -1; + } + } + } + else + { + eXosip.j_socket = (int)socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (eXosip.j_socket==-1) + return -1; + + { + struct sockaddr_in6 raddr; + memset(&raddr, 0, sizeof(raddr)); + raddr.sin6_port = htons((short)port); + raddr.sin6_family = AF_INET6; + + i = bind(eXosip.j_socket, (struct sockaddr *)&raddr, sizeof(raddr)); + if (i < 0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: Cannot bind on port: %i!\n", i)); + return -1; + } + } + } + + + eXosip.localport = (char*)osip_malloc(10); + sprintf(eXosip.localport, "%i", port); + + eXosip.j_thread = (void*) osip_thread_create(20000,eXosip_thread, NULL); + if (eXosip.j_thread==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: Cannot start thread!\n")); + return -1; + } + + /* To be changed in osip! */ + eXosip.j_events = (osip_fifo_t*) osip_malloc(sizeof(osip_fifo_t)); + osip_fifo_init(eXosip.j_events); + + jfriend_load(); + jidentity_load(); + jsubscriber_load(); + return 0; +} + +int eXosip_force_localip(const char *localip){ + if (localip!=NULL){ + strcpy(eXosip.localip,localip); + eXosip.forced_localip=1; + }else { + eXosip_guess_ip_for_via(eXosip.ip_family, eXosip.localip, 49); + eXosip.forced_localip=0; + } + return 0; +} + +void +eXosip_set_mode(int mode) +{ + eXosip.j_runtime_mode = mode; +} + +void +eXosip_set_user_agent(const char *user_agent) +{ + osip_free(eXosip.user_agent); + eXosip.user_agent = osip_strdup(user_agent); +} + +void +eXosip_automatic_refresh() +{ +#if 0 + eXosip_call_t *jc; + eXosip_notify_t *jn; +#endif + eXosip_subscribe_t *js; + eXosip_dialog_t *jd; + eXosip_reg_t *jr; + int now; + + now = time(NULL); + +#if 0 + for (jc=eXosip.j_calls; jc!=NULL; jc=jc->next) + { + if (jc->c_id<1) + { + } + for (jd=jc->c_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + /* sending update for keep-alive mechanism could be done here! */ + } + } + } +#endif + + for (js=eXosip.j_subscribes; js!=NULL; js=js->next) + { + for (jd=js->s_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + if (jd->d_id>=1) + { + if (eXosip_subscribe_need_refresh(js, now)==0) + { + int i; +#ifdef LOW_EXPIRE + i = eXosip_subscribe_send_subscribe(js, jd, "120"); +#else + i = eXosip_subscribe_send_subscribe(js, jd, "3600"); +#endif + } + } + } + } + } + +#if 0 + for (jn=eXosip.j_notifies; jn!=NULL; jn=jn->next) + { + if (jn->n_id<1) + { + jn->n_id = static_id; + static_id++; + } + for (jd=jn->n_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + if (jd->d_id>=1) + { + /* keep-alive of dialog should be done by subscribe */ + /* may be we can decide to close the subscribption + if it is expired */ + } + } + } + } +#endif + + for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) + { + if (jr->r_id >=1 || jr->r_last_tr!=NULL) + { + if (jr->r_reg_period==0) + { + /* skip refresh! */ + } + else if (now-jr->r_last_tr->birth_time>300) + { + /* automatic refresh */ + eXosip_register(jr->r_id, jr->r_reg_period); + } + else if (now-jr->r_last_tr->birth_time>jr->r_reg_period-60) + { + /* automatic refresh */ + eXosip_register(jr->r_id, jr->r_reg_period); + } + else if (now-jr->r_last_tr->birth_time>120 && + (jr->r_last_tr->last_response==NULL + || (!MSG_IS_STATUS_2XX(jr->r_last_tr->last_response)))) + { + /* automatic refresh */ + eXosip_register(jr->r_id, jr->r_reg_period); + } + } + } +} + +void +eXosip_update() +{ + static int static_id = 1; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + eXosip_dialog_t *jd; + int now; + + if (static_id>100000) + static_id = 1; /* loop */ + + now = time(NULL); + for (jc=eXosip.j_calls; jc!=NULL; jc=jc->next) + { + if (jc->c_id<1) + { + jc->c_id = static_id; + static_id++; + } + for (jd=jc->c_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + if (jd->d_id<1) + { + jd->d_id = static_id; + static_id++; + } + } + else jd->d_id = -1; + } + } + + for (js=eXosip.j_subscribes; js!=NULL; js=js->next) + { + if (js->s_id<1) + { + js->s_id = static_id; + static_id++; + } + for (jd=js->s_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + if (jd->d_id<1) + { + jd->d_id = static_id; + static_id++; + } + } + else + jd->d_id = -1; + } + } + + for (jn=eXosip.j_notifies; jn!=NULL; jn=jn->next) + { + if (jn->n_id<1) + { + jn->n_id = static_id; + static_id++; + } + for (jd=jn->n_dialogs; jd!=NULL; jd=jd->next) + { + if (jd->d_dialog!=NULL) /* finished call */ + { + if (jd->d_id<1) + { + jd->d_id = static_id; + static_id++; + } + } + else jd->d_id = -1; + } + } +} + +int eXosip_message (char *to, char *from, char *route, char *buff) +{ + /* eXosip_call_t *jc; + osip_header_t *subject; */ + osip_message_t *message; + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + + i = generating_message(&message, to, from, route, buff); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot send message (cannot build MESSAGE)! ")); + return -1; + } + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + message); + if (i!=0) + { + /* TODO: release the j_call.. */ + + osip_message_free(message); + return -1; + } + + osip_list_add(eXosip.j_transactions, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(message); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, NULL, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_info_call(int jid, char *content_type, char *body) +{ + osip_transaction_t *transaction; + osip_event_t *sipevent; + osip_message_t *info; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + int i; + + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (jd==NULL || jd->d_dialog==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No established dialog!")); + return -1; + } + + transaction = eXosip_find_last_options(jc, jd); + if (transaction!=NULL) + { + if (transaction->state!=NICT_TERMINATED && + transaction->state!=NIST_TERMINATED) + return -1; + transaction=NULL; + } + + i = generating_info_within_dialog(&info, jd->d_dialog); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot send info message! ")); + return -2; + } + + osip_message_set_content_type(info, content_type); + osip_message_set_body(info, body, strlen(body)); + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + info); + if (i!=0) + { + osip_message_free(info); + return -1; + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(info); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_initiate_call_with_body(osip_message_t *invite,const char *bodytype, const char*body, void *reference){ + eXosip_call_t *jc; + osip_header_t *subject; + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + char *size; + + if (body!=NULL){ + size= (char *)osip_malloc(7*sizeof(char)); + sprintf(size,"%i",strlen(body)); + osip_message_set_content_length(invite, size); + osip_free(size); + osip_message_set_body(invite, body, strlen(body)); + osip_message_set_content_type(invite,bodytype); + } + else osip_message_set_content_length(invite, "0"); + + eXosip_call_init(&jc); + i = osip_message_get_subject(invite, 0, &subject); + if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0') + snprintf(jc->c_subject, 99, "%s", subject->hvalue); + + jc->c_ack_sdp = 0; + + i = osip_transaction_init(&transaction, + ICT, + eXosip.j_osip, + invite); + if (i!=0) + { + eXosip_call_free(jc); + osip_message_free(invite); + return -1; + } + + jc->c_out_tr = transaction; + + sipevent = osip_new_outgoing_sipmessage(invite); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, NULL, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + + jc->external_reference = reference; + ADD_ELEMENT(eXosip.j_calls, jc); + + eXosip_update(); /* fixed? */ + __eXosip_wakeup(); + return jc->c_id; +} + +osip_message_t *eXosip_prepare_request_for_auth(osip_message_t *msg) +{ +#ifdef SM + char *locip; +#else + char locip[50]; +#endif + osip_message_t *newmsg; + int cseq; + char tmp[90]; + osip_via_t *via; + + osip_message_clone(msg,&newmsg); + if (newmsg==NULL){ + eXosip_trace(OSIP_INFO1,("eXosip_prepare_request_for_auth: could not clone msg.")); + return NULL; + } + via = (osip_via_t *) osip_list_get (newmsg->vias, 0); + if (via==NULL || newmsg->cseq==NULL || newmsg->cseq->number==NULL) { + osip_message_free(newmsg); + eXosip_trace(OSIP_INFO1,("eXosip_prepare_request_for_auth: Bad headers in previous request.")); + return NULL; + } + /* increment cseq */ + cseq=atoi(newmsg->cseq->number); + osip_free(newmsg->cseq->number); + newmsg->cseq->number=strdup_printf("%i",cseq+1); + + osip_list_remove(newmsg->vias, 0); + locip=osip_strdup(osip_via_get_host(via)); + osip_via_free(via); +#ifdef SM + +#else + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + if (eXosip.ip_family==AF_INET6) + sprintf(tmp, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u", + locip, + eXosip.localport, + via_branch_new_random()); + else + sprintf(tmp, "SIP/2.0/UDP %s:%s;rport;branch=z9hG4bK%u", + locip, + eXosip.localport, + via_branch_new_random()); + +#ifdef SM + osip_free(locip); +#endif + osip_via_init(&via); + osip_via_parse(via, tmp); + osip_list_add(newmsg->vias, via, 0); + + return newmsg; +} + +int eXosip_retry_call(int cid) +{ + eXosip_call_t *jc=NULL; + osip_transaction_t *tr,*newtr=NULL; + osip_message_t *inv=NULL; + int i; + osip_event_t *sipevent; + eXosip_call_find(cid,&jc); + if (jc==NULL) { + eXosip_trace(OSIP_INFO1,("eXosip_retry_last_invite: No such call.")); + return -1; + } + tr=eXosip_find_last_out_invite(jc,NULL); + if (tr==NULL){ + eXosip_trace(OSIP_INFO1,("eXosip_retry_last_invite: No such transaction.")); + return -1; + } + if (tr->last_response==NULL){ + eXosip_trace(OSIP_INFO1,("eXosip_retry_last_invite: transaction has not been answered.")); + return -1; + } + inv=eXosip_prepare_request_for_auth(tr->orig_request); + if (inv==NULL) return -1; + eXosip_add_authentication_information(inv,tr->last_response); + if (-1 == eXosip_update_top_via(inv)) + { + osip_message_free(inv); + return -1; + } + + + i = osip_transaction_init(&newtr, + ICT, + eXosip.j_osip, + inv); + if (i!=0) + { + osip_message_free(inv); + return -1; + } + jc->c_out_tr = newtr; + + sipevent = osip_new_outgoing_sipmessage(inv); + + osip_transaction_set_your_instance(newtr, __eXosip_new_jinfo(jc, NULL, NULL, NULL)); + osip_transaction_add_event(newtr, sipevent); + + eXosip_update(); /* fixed? */ + __eXosip_wakeup(); + return jc->c_id; +} + +extern int cb_udp_snd_message(osip_transaction_t *tr, osip_message_t *sip, + char *host, int port, int out_socket); + +int eXosip_send_ack(int did){ + eXosip_call_t *call; + eXosip_dialog_t *dialog; + eXosip_call_dialog_find(did,&call,&dialog); + if (dialog!=NULL){ + if (dialog->d_ack!=NULL){ + osip_route_t *route; + int port; + char *host; + osip_message_t *ack=dialog->d_ack; + osip_message_get_route(ack, 0, &route); + if (route!=NULL) + { + port = 5060; + if (route->url->port!=NULL) + port = osip_atoi(route->url->port); + host = route->url->host; + } + else + { + port = 5060; + if (ack->req_uri->port!=NULL) + port = osip_atoi(ack->req_uri->port); + host = ack->req_uri->host; + } + + cb_udp_snd_message(NULL, ack, host, port, eXosip.j_socket); + } + } + return 0; +} + +extern osip_list_t *supported_codec; + +int eXosip_initiate_call(osip_message_t *invite, void *reference, + void *sdp_context_reference, + char *local_sdp_port) +{ + eXosip_call_t *jc; + osip_header_t *subject; + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + sdp_message_t *sdp; + char *body; + char *size; + + if (invite==NULL || invite->req_uri==NULL || invite->req_uri->host==NULL ) return -1; + + if (local_sdp_port!=NULL) + { + osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, local_sdp_port, NULL); + + /* + if speex codec is supported, add bandwith attribute: + b=AS:110 20 + b=AS:111 20 + */ + if (sdp!=NULL) + { + int pos=0; + while (!sdp_message_endof_media (sdp, pos)) + { + int k = 0; + char *tmp = sdp_message_m_media_get (sdp, pos); + if (0 == osip_strncasecmp (tmp, "audio", 5)) + { + char *payload = NULL; + do { + payload = sdp_message_m_payload_get (sdp, pos, k); + if (payload == NULL) + { + } + else if (0==strcmp("110",payload)) + { + sdp_message_a_attribute_add (sdp, + pos, + osip_strdup ("AS"), + osip_strdup ("110 20")); + } + else if (0==strcmp("111",payload)) + { + sdp_message_a_attribute_add (sdp, + pos, + osip_strdup ("AS"), + osip_strdup ("111 20")); + } + k++; + } while (payload != NULL); + } + pos++; + } + } + + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = invite->req_uri->host; + int pos=0; + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, invite->req_uri->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + /* If remote message contains a Public IP, we have to replace the SDP + connection address */ + if (eXosip_is_public_address(c_address)) + { + /* replace the IP with our firewall ip */ + sdp_connection_t *conn = sdp_message_connection_get(sdp, -1, 0); + if (conn!=NULL && conn->c_addr!=NULL ) + { + osip_free(conn->c_addr); + conn->c_addr = osip_strdup(eXosip.j_firewall_ip); + } + pos=0; + conn = sdp_message_connection_get(sdp, pos, 0); + while (conn!=NULL) + { + if (conn!=NULL && conn->c_addr!=NULL ) + { + osip_free(conn->c_addr); + conn->c_addr = osip_strdup(eXosip.j_firewall_ip); + } + pos++; + conn = sdp_message_connection_get(sdp, pos, 0); + } + } + + } + + i = sdp_message_to_str(sdp, &body); + if (body!=NULL) + { + size= (char *)osip_malloc(7*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(body)); +#else + sprintf(size,"%i",strlen(body)); +#endif + osip_message_set_content_length(invite, size); + osip_free(size); + + osip_message_set_body(invite, body, strlen(body)); + osip_free(body); + osip_message_set_content_type(invite, "application/sdp"); + } + else + osip_message_set_content_length(invite, "0"); + } + + eXosip_call_init(&jc); + if (local_sdp_port!=NULL) + snprintf(jc->c_sdp_port,9, "%s", local_sdp_port); + i = osip_message_get_subject(invite, 0, &subject); + if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0') + snprintf(jc->c_subject, 99, "%s", subject->hvalue); + + if (sdp_context_reference==NULL) + osip_negotiation_ctx_set_mycontext(jc->c_ctx, jc); + else + osip_negotiation_ctx_set_mycontext(jc->c_ctx, sdp_context_reference); + + if (local_sdp_port!=NULL) + { + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, sdp); + jc->c_ack_sdp = 0; + } + else + jc->c_ack_sdp = 1; + + i = osip_transaction_init(&transaction, + ICT, + eXosip.j_osip, + invite); + if (i!=0) + { + eXosip_call_free(jc); + osip_message_free(invite); + return -1; + } + + jc->c_out_tr = transaction; + + sipevent = osip_new_outgoing_sipmessage(invite); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, NULL, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + + jc->external_reference = reference; + ADD_ELEMENT(eXosip.j_calls, jc); + + eXosip_update(); /* fixed? */ + __eXosip_wakeup(); + return jc->c_id; +} + + +int eXosip2_answer(int jid, int status, osip_message_t **answer){ + int i = -1; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (status>100 && status<200) + { + i = _eXosip2_answer_invite_1xx(jc, jd, status, answer); + } + else if (status>199 && status<300) + { + i = _eXosip2_answer_invite_2xx(jc, jd, status, answer); + } + else if (status>300 && status<699) + { + i = _eXosip2_answer_invite_3456xx(jc, jd, status, answer); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (1010) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + if (MSG_IS_STATUS_1XX(answer)) + { + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, answer); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + i = 0; + } + else + { + ADD_ELEMENT(jc->c_dialogs, jd); + } + } + } + else if (MSG_IS_STATUS_2XX(answer)) + { + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, answer); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + return -1; + } + ADD_ELEMENT(jc->c_dialogs, jd); + } + else i = 0; + + eXosip_dialog_set_200ok(jd, answer); + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + } + else if (answer->status_code>=300 && answer->status_code<=699) + { + i = 0; + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (101transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; +} + +int eXosip_answer_call_with_body(int jid, int status, const char *bodytype, const char *body){ + int i = -1; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (status>100 && status<200) + { + i = eXosip_answer_invite_1xx(jc, jd, status); + } + else if (status>199 && status<300) + { + i = eXosip_answer_invite_2xx_with_body(jc, jd, status,bodytype,body); + } + else if (status>300 && status<699) + { + i = eXosip_answer_invite_3456xx(jc, jd, status); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (1010) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (contact==NULL) + memset(jc->c_redirection, '\0', 1024); + else + snprintf(jc->c_redirection, 1024, "%s", contact); + return 0; +} + +int eXosip_answer_call (int jid, int status, char *local_sdp_port) +{ + int i = -1; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (status>100 && status<200) + { + i = eXosip_answer_invite_1xx(jc, jd, status); + } + else if (status>199 && status<300) + { +#if 0 /* this seems to be useless?? */ + if (jc->c_ctx!=NULL) + osip_negotiation_ctx_set_mycontext(jc->c_ctx, jc); + else + osip_negotiation_ctx_set_mycontext(jc->c_ctx, sdp_context_reference); +#endif + if (local_sdp_port!=NULL) + { + osip_negotiation_ctx_set_mycontext(jc->c_ctx, jc); + snprintf(jc->c_sdp_port,9, "%s", local_sdp_port); + } + + i = eXosip_answer_invite_2xx(jc, jd, status, local_sdp_port); + } + else if (status>300 && status<699) + { + i = eXosip_answer_invite_3456xx(jc, jd, status); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (1010) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + + pl = eXosip_retrieve_sdp_negotiation_result(jc->c_ctx, payload_name, pnsize); + + if (pl >= 0) + { + *payload = pl; + return 0; + } + + return -1; +} + +int eXosip_options_call (int jid) +{ + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + + osip_transaction_t *transaction; + osip_event_t *sipevent; + osip_message_t *options; + int i; + + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + + transaction = eXosip_find_last_options(jc, jd); + if (transaction!=NULL) + { + if (transaction->state!=NICT_TERMINATED && + transaction->state!=NIST_TERMINATED) + return -1; + transaction=NULL; + } + + i = _eXosip_build_request_within_dialog(&options, "OPTIONS", jd->d_dialog, "UDP"); + if (i!=0) + return -2; + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + options); + if (i!=0) + { + /* TODO: release the j_call.. */ + osip_message_free(options); + return -2; + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(options); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_answer_options (int cid, int jid, int status) +{ + int i = -1; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No dialog here?\n")); + return -1; + } + } + else + { + eXosip_call_find(cid, &jc); + if (jc==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + } + if (status>100 && status<200) + { + i = eXosip_answer_options_1xx(jc, jd, status); + } + else if (status>199 && status<300) + { + i = eXosip_answer_options_2xx(jc, jd, status); + } + else if (status>300 && status<699) + { + i = eXosip_answer_options_3456xx(jc, jd, status); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (1010) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jc==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + jc->external_reference = reference; + return 0; +} + +int eXosip_on_hold_call (int jid) +{ + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + + osip_transaction_t *transaction; + osip_event_t *sipevent; + osip_message_t *invite; + int i; + sdp_message_t *sdp; + char *body; + char *size; + + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + + transaction = eXosip_find_last_invite(jc, jd); + if (transaction==NULL) return -1; + if (transaction->state!=ICT_TERMINATED && + transaction->state!=IST_TERMINATED) + return -1; + + sdp = eXosip_get_local_sdp_info(transaction); + if (sdp==NULL) + return -1; + i = osip_negotiation_sdp_message_put_on_hold(sdp); + if (i!=0) + { + sdp_message_free(sdp); + return -2; + } + + i = _eXosip_build_request_within_dialog(&invite, "INVITE", jd->d_dialog, "UDP"); + if (i!=0) { + sdp_message_free(sdp); + return -2; + } + + i = sdp_message_to_str(sdp, &body); + if (body!=NULL) + { + size= (char *)osip_malloc(7*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(body)); +#else + sprintf(size,"%i",strlen(body)); +#endif + osip_message_set_content_length(invite, size); + osip_free(size); + + osip_message_set_body(invite, body, strlen(body)); + osip_free(body); + osip_message_set_content_type(invite, "application/sdp"); + } + else + osip_message_set_content_length(invite, "0"); + + if (jc->c_subject==NULL || jc->c_subject[0]=='\0') + { +#if 0 + osip_message_set_subject(invite, "New Call"); +#endif + } + else + osip_message_set_subject(invite, jc->c_subject); + + transaction=NULL; + i = osip_transaction_init(&transaction, + ICT, + eXosip.j_osip, + invite); + if (i!=0) + { + /* TODO: release the j_call.. */ + osip_message_free(invite); + return -2; + } + + { + sdp_message_t *old_sdp = osip_negotiation_ctx_get_local_sdp(jc->c_ctx); + sdp_message_free(old_sdp); + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, sdp); + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(invite); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_off_hold_call (int jid, char *rtp_ip, int port) +{ + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + + osip_transaction_t *transaction; + osip_event_t *sipevent; + osip_message_t *invite; + int i; + sdp_message_t *sdp; + char *body; + char *size; + + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + + transaction = eXosip_find_last_invite(jc, jd); + if (transaction==NULL) return -1; + if (transaction->state!=ICT_TERMINATED && + transaction->state!=IST_TERMINATED) + return -1; + + sdp = eXosip_get_local_sdp_info(transaction); + if (sdp==NULL) + return -1; + i = osip_negotiation_sdp_message_put_off_hold(sdp); + if (i!=0) + { + sdp_message_free(sdp); + return -2; + } + + i = _eXosip_build_request_within_dialog(&invite, "INVITE", jd->d_dialog, "UDP"); + if (i!=0) { + sdp_message_free(sdp); + return -2; + } + + if (rtp_ip!=NULL) + { + /* modify the connection address of host */ + sdp_connection_t *conn; + sdp_media_t *med; + int pos_media = 0; + conn = sdp_message_connection_get(sdp, -1, 0); + if (conn!=NULL && conn->c_addr!=NULL) + { + osip_free(conn->c_addr); + conn->c_addr = osip_strdup(rtp_ip); + } + med = (sdp_media_t *) osip_list_get (sdp->m_medias, pos_media); + while (med != NULL) + { + if (med->m_media!=NULL && 0==osip_strcasecmp(med->m_media, "audio")) + { + osip_free(med->m_port); + med->m_port=(char *)osip_malloc(15); + snprintf(med->m_port, 14, "%i", port); + break; + } + pos_media++; + med = (sdp_media_t *) osip_list_get (sdp->m_medias, pos_media); + } + } + + i = sdp_message_to_str(sdp, &body); + if (body!=NULL) + { + size= (char *)osip_malloc(7*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(body)); +#else + sprintf(size,"%i",strlen(body)); +#endif + osip_message_set_content_length(invite, size); + osip_free(size); + + osip_message_set_body(invite, body, strlen(body)); + osip_free(body); + osip_message_set_content_type(invite, "application/sdp"); + } + else + osip_message_set_content_length(invite, "0"); + + if (jc->c_subject==NULL || jc->c_subject[0]=='\0') + { +#if 0 + osip_message_set_subject(invite, "New Call"); +#endif + } + else + osip_message_set_subject(invite, jc->c_subject); + + transaction=NULL; + i = osip_transaction_init(&transaction, + ICT, + eXosip.j_osip, + invite); + if (i!=0) + { + /* TODO: release the j_call.. */ + osip_message_free(invite); + return -2; + } + + { + sdp_message_t *old_sdp = osip_negotiation_ctx_get_local_sdp(jc->c_ctx); + sdp_message_free(old_sdp); + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, sdp); + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(invite); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +static int eXosip_create_transaction(eXosip_call_t *jc, + eXosip_dialog_t *jd, + osip_message_t *request) +{ + osip_event_t *sipevent; + osip_transaction_t *tr; + int i; + i = osip_transaction_init(&tr, + NICT, + eXosip.j_osip, + request); + if (i!=0) + { + /* TODO: release the j_call.. */ + + osip_message_free(request); + return -1; + } + + if (jd!=NULL) + osip_list_add(jd->d_out_trs, tr, 0); + + sipevent = osip_new_outgoing_sipmessage(request); + sipevent->transactionid = tr->transactionid; + + osip_transaction_set_your_instance(tr, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(tr, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_transfer_call_out_of_dialog(char *refer_to, char *from, char *to, char *proxy) +{ + osip_message_t *refer; + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + i = generating_refer_outside_dialog(&refer, refer_to, from, to, proxy); + if (i!=0) return -1; + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + refer); + if (i!=0) + { + osip_message_free(refer); + return -1; + } + + osip_list_add(eXosip.j_transactions, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(refer); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, NULL, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_transfer_call(int jid, char *refer_to) +{ + int i; + osip_message_t *request; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid<=0) + return -1; + + eXosip_call_dialog_find(jid, &jc, &jd); + if (jd==NULL || jd->d_dialog==NULL || jd->d_dialog->state==DIALOG_EARLY) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No established call here!")); + return -1; + } + + i = generating_refer(&request, jd->d_dialog, refer_to); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot generate REFER for call!")); + return -2; + } + + i = eXosip_create_transaction(jc, jd, request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot initiate SIP transfer transaction!")); + return i; + } + return 0; +} + +static int eXosip_create_cancel_transaction(eXosip_call_t *jc, + eXosip_dialog_t *jd, + osip_message_t *request) +{ + osip_event_t *sipevent; + osip_transaction_t *tr; + int i; + i = osip_transaction_init(&tr, + NICT, + eXosip.j_osip, + request); + if (i!=0) + { + /* TODO: release the j_call.. */ + + osip_message_free(request); + return -2; + } + + osip_list_add(eXosip.j_transactions, tr, 0); + + sipevent = osip_new_outgoing_sipmessage(request); + sipevent->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_terminate_call(int cid, int jid) +{ + int i; + osip_transaction_t *tr; + osip_message_t *request; + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here? ")); + return -1; + } + } + else + { + eXosip_call_find(cid, &jc); + } + + if (jc==NULL) + { + return -1; + } + + tr=eXosip_find_last_out_invite(jc, jd); + if (tr!=NULL && tr->last_response!=NULL && MSG_IS_STATUS_1XX(tr->last_response)) + { + i = generating_cancel(&request, tr->orig_request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot terminate this call! ")); + return -2; + } + i = eXosip_create_cancel_transaction(jc, jd, request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot initiate SIP transaction! ")); + return i; + } + if (jd!=NULL) + { + osip_dialog_free(jd->d_dialog); + jd->d_dialog = NULL; + } + return 0; + } + + if (jd==NULL || jd->d_dialog==NULL) + { + /* Check if some dialog exists */ + jd = jc->c_dialogs; + if (jd!=NULL && jd->d_dialog!=NULL) + { + i = generating_bye(&request, jd->d_dialog); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot terminate this call! ")); + return -2; + } + + i = eXosip_create_transaction(jc, jd, request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot initiate SIP transaction! ")); + return -2; + } + + osip_dialog_free(jd->d_dialog); + jd->d_dialog = NULL; + return 0; + } + + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No established dialog!")); + return -1; + } + + if (tr==NULL) + { + /*this may not be enough if it's a re-INVITE! */ + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr!=NULL && tr->last_response!=NULL && + MSG_IS_STATUS_1XX(tr->last_response)) + { /* answer with 603 */ + i = eXosip_answer_call(jid, 603, 0); + return i; + } + } + + + i = generating_bye(&request, jd->d_dialog); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot terminate this call! ")); + return -2; + } + + i = eXosip_create_transaction(jc, jd, request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot initiate SIP transaction! ")); + return -2; + } + + osip_dialog_free(jd->d_dialog); + jd->d_dialog = NULL; + return 0; +} + +static jauthinfo_t * +eXosip_find_authentication_info(const char *username, const char *realm) +{ + jauthinfo_t *fallback = NULL; + jauthinfo_t *authinfo; + + for (authinfo = eXosip.authinfos; + authinfo!=NULL; + authinfo = authinfo->next) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "INFO: authinfo: %s %s\n", realm, authinfo->realm)); + if (0==strcmp(authinfo->username, username)) + { + if (authinfo->realm == NULL || authinfo->realm[0] == '\0') + { + fallback = authinfo; + } + else if (strcmp(realm,authinfo->realm)==0 || 0==strncmp(realm+1, authinfo->realm, strlen(realm)-2)) + { + return authinfo; + } + } + } + return fallback; +} + + +int eXosip_clear_authentication_info(){ + jauthinfo_t *jauthinfo; + for (jauthinfo = eXosip.authinfos; jauthinfo!=NULL; + jauthinfo = eXosip.authinfos) + { + REMOVE_ELEMENT(eXosip.authinfos, jauthinfo); + osip_free(jauthinfo); + } + return 0; +} + +int +eXosip_add_authentication_info(const char *username, const char *userid, + const char *passwd, const char *ha1, + const char *realm) +{ + jauthinfo_t *authinfos; + + if (username==NULL || username[0]=='\0') return -1; + if (userid==NULL || userid[0]=='\0') return -1; + + if ( passwd!=NULL && passwd[0]!='\0') {} + else if (ha1!=NULL && ha1[0]!='\0') {} + else return -1; + + authinfos = (jauthinfo_t *) osip_malloc(sizeof(jauthinfo_t)); + if (authinfos==NULL) + return -1; + memset(authinfos, 0, sizeof(jauthinfo_t)); + + snprintf(authinfos->username, 50, "%s", username); + snprintf(authinfos->userid, 50, "%s", userid); + if ( passwd!=NULL && passwd[0]!='\0') + snprintf(authinfos->passwd, 50, "%s", passwd); + else if (ha1!=NULL && ha1[0]!='\0') + snprintf(authinfos->ha1, 50, "%s", ha1); + if(realm!=NULL && realm[0]!='\0') + snprintf(authinfos->realm, 50, "%s", realm); + + ADD_ELEMENT(eXosip.authinfos, authinfos); + return 0; +} + +static int +eXosip_add_authentication_information(osip_message_t *req, + osip_message_t *last_response) +{ + osip_authorization_t *aut = NULL; + osip_www_authenticate_t *wwwauth = NULL; + osip_proxy_authorization_t *proxy_aut = NULL; + osip_proxy_authenticate_t *proxyauth = NULL; + jauthinfo_t *authinfo = NULL; + int pos; + int i; + + if (req==NULL + ||req->from==NULL + ||req->from->url==NULL + ||req->from->url->username==NULL) + return -1; + + pos=0; + osip_message_get_www_authenticate(last_response, pos, &wwwauth); + osip_message_get_proxy_authenticate(last_response, pos, &proxyauth); + if (wwwauth==NULL && proxyauth==NULL) return -1; + + while (wwwauth!=NULL) + { + char *uri; + authinfo = eXosip_find_authentication_info(req->from->url->username, + wwwauth->realm); + if (authinfo==NULL) return -1; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "authinfo: %s\n", authinfo->username)); + i = osip_uri_to_str (req->req_uri, &uri); + if (i!=0) return -1; + + i = __eXosip_create_authorization_header(last_response, uri, + authinfo->userid, + authinfo->passwd, + &aut); + osip_free(uri); + if (i!=0) return -1; + + if (aut != NULL) + { + osip_list_add (req->authorizations, aut, -1); + osip_message_force_update(req); + } + + pos++; + osip_message_get_www_authenticate(last_response, pos, &wwwauth); + } + + pos=0; + while (proxyauth!=NULL) + { + char *uri; + authinfo = eXosip_find_authentication_info(req->from->url->username, + proxyauth->realm); + if (authinfo==NULL) return -1; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "authinfo: %s\n", authinfo->username)); + i = osip_uri_to_str (req->req_uri, &uri); + if (i!=0) return -1; + + i = __eXosip_create_proxy_authorization_header(last_response, uri, + authinfo->userid, + authinfo->passwd, + &proxy_aut); + osip_free(uri); + if (i!=0) return -1; + + if (proxy_aut != NULL) + { + osip_list_add (req->proxy_authorizations, proxy_aut, -1); + osip_message_force_update(req); + } + + pos++; + osip_message_get_proxy_authenticate (last_response, pos, &proxyauth); + } + + return 0; +} + + +static int +eXosip_update_top_via(osip_message_t *sip) +{ +#ifdef SM + char *locip; +#else + char locip[50]; +#endif + char *tmp = (char *)osip_malloc(256*sizeof(char)); + osip_via_t *via = (osip_via_t *) osip_list_get (sip->vias, 0); + + + osip_list_remove(sip->vias, 0); + locip=osip_strdup(osip_via_get_host(via)); + osip_via_free(via); +#ifdef SM +#else + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + if (eXosip.ip_family==AF_INET6) + snprintf(tmp, 256, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u", + locip, + eXosip.localport, + via_branch_new_random()); + else + snprintf(tmp, 256, "SIP/2.0/UDP %s:%s;rport;branch=z9hG4bK%u", + locip, + eXosip.localport, + via_branch_new_random()); + + if (eXosip.nat_type[0]) + { + strncat(tmp, ";xxx-nat-type=", 256); + strncat(tmp, eXosip.nat_type, 256); + } + + +#ifdef SM + osip_free(locip); +#endif + osip_via_init(&via); + osip_via_parse(via, tmp); + osip_list_add(sip->vias, via, 0); + osip_free(tmp); + + return 0; +} + +static eXosip_reg_t * +eXosip_reg_find(int rid) +{ + eXosip_reg_t *jr; + + for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) + { + if (jr->r_id == rid) + { + return jr; + } + } + return NULL; +} + +int eXosip_register (int rid, int registration_period) +{ + osip_transaction_t *transaction; + osip_event_t *sipevent; + osip_message_t *reg; + eXosip_reg_t *jr; + int i; + + jr = eXosip_reg_find(rid); + if (jr==NULL) + { + /* fprintf(stderr, "eXosip: no registration info saved!\n"); */ + return -1; + } + if (registration_period>=0) + jr->r_reg_period = registration_period; + if (jr->r_reg_period==0) + {} /* unregistration */ + else if (jr->r_reg_period>3600) + jr->r_reg_period = 3600; + else if (jr->r_reg_period<200) /* too low */ + jr->r_reg_period = 200; + + reg = NULL; + if (jr->r_last_tr!=NULL) + { + if (jr->r_last_tr->state!=NICT_TERMINATED + && jr->r_last_tr->state!=NICT_COMPLETED) + { + /* fprintf(stderr, "eXosip: a registration is already pending!\n"); */ + return -1; + } + else + { + osip_message_t *last_response; + + reg = jr->r_last_tr->orig_request; + last_response = jr->r_last_tr->last_response; + + jr->r_last_tr->orig_request = NULL; + jr->r_last_tr->last_response = NULL; + __eXosip_delete_jinfo(jr->r_last_tr); + osip_transaction_free(jr->r_last_tr); + jr->r_last_tr = NULL; + + /* modify the REGISTER request */ + { + int osip_cseq_num = osip_atoi(reg->cseq->number); + int length = strlen(reg->cseq->number); + + + osip_authorization_t *aut; + osip_proxy_authorization_t *proxy_aut; + + aut = (osip_authorization_t *)osip_list_get(reg->authorizations, 0); + while (aut!=NULL) + { + osip_list_remove(reg->authorizations, 0); + osip_authorization_free(aut); + aut = (osip_authorization_t *)osip_list_get(reg->authorizations, 0); + } + + proxy_aut = (osip_proxy_authorization_t*)osip_list_get(reg->proxy_authorizations, 0); + while (proxy_aut!=NULL) + { + osip_list_remove(reg->proxy_authorizations, 0); + osip_proxy_authorization_free(proxy_aut); + proxy_aut = (osip_proxy_authorization_t*)osip_list_get(reg->proxy_authorizations, 0); + } + + + if (-1 == eXosip_update_top_via(reg)) + { + osip_message_free(reg); + return -1; + } + + osip_cseq_num++; + osip_free(reg->cseq->number); + reg->cseq->number = (char*)osip_malloc(length+2); /* +2 like for 9 to 10 */ + sprintf(reg->cseq->number, "%i", osip_cseq_num); + + { + osip_header_t *exp; + osip_message_header_get_byname(reg, "expires", 0, &exp); + osip_free(exp->hvalue); + exp->hvalue = (char*)osip_malloc(10); + snprintf(exp->hvalue, 9, "%i", jr->r_reg_period); + } + + osip_message_force_update(reg); + } + + if (last_response!=NULL) + { + if (MSG_IS_STATUS_4XX(last_response)) + { + eXosip_add_authentication_information(reg, last_response); + } + osip_message_free(last_response); + } + } + } + if (reg==NULL) + { + i = generating_register(®, jr->r_aor, jr->r_registrar, jr->r_contact, jr->r_reg_period); + if (i!=0) + { + /* fprintf(stderr, "eXosip: cannot register (cannot build REGISTER)! "); */ + return -2; + } + } + //!jinti! if exist outbound proxy setting ,register must use outboundproxy! + if (jr->r_route!=NULL) + { + osip_route_t *r=NULL; + osip_message_get_route(reg,0,&r); + if (r==NULL) + osip_message_set_route(reg, jr->r_route); + } + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + reg); + if (i!=0) + { + /* TODO: release the j_call.. */ + + osip_message_free(reg); + return -2; + } + + jr->r_last_tr = transaction; + + /* send REGISTER */ + sipevent = osip_new_outgoing_sipmessage(reg); + sipevent->transactionid = transaction->transactionid; + osip_message_force_update(reg); + + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int +eXosip_register_init(char *from, char *proxy, char *contact, char *route) +{ + eXosip_reg_t *jr; + int i; + + /* Avoid adding the same registration info twice to prevent mem leaks */ + for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) + { + if (strcmp(jr->r_aor, from) == 0 + && strcmp(jr->r_registrar, proxy) == 0) + { + return jr->r_id; + } + } + + /* Add new registration info */ + i = eXosip_reg_init(&jr, from, proxy, contact, route); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot register! ")); + return i; + } + ADD_ELEMENT(eXosip.j_reg, jr); + return jr->r_id; +} + + +int eXosip_build_publish(osip_message_t **message, + char *to, + char *from, + char *route, + const char *event, + const char *expires, + const char *ctype, + const char *body) +{ + int i; + if (to==NULL || to[0]=='\0') + return -1; + if (from==NULL || from[0]=='\0') + return -1; + if (event==NULL || event[0]=='\0') + return -1; + if (ctype==NULL || ctype[0]=='\0') + { + if (body!=NULL && body[0]!='\0') + return -1; + } + else + { + if (body==NULL || body[0]=='\0') + return -1; + } + + i = generating_publish(message, to, from, route); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot send message (cannot build PUBLISH)! ")); + return -1; + } + + if (body!=NULL && body[0]!='\0' && ctype!=NULL && ctype[0]!='\0') + { + osip_message_set_content_type(*message, ctype); + osip_message_set_body(*message, body, strlen(body)); + osip_message_set_header(*message, "Content-Disposition", "render;handling=required"); + } + if (expires!=NULL && expires[0]!='\0') + osip_message_set_expires(*message, expires); + else + osip_message_set_expires(*message, "3600"); + + osip_message_set_header(*message, "Event", event); + return 0; +} + +int eXosip_publish (osip_message_t *message, const char *to) +{ + /* eXosip_call_t *jc; + osip_header_t *subject; */ + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + eXosip_pub_t *pub=NULL; + + if (message==NULL) + return -1; + if (message->cseq==NULL||message->cseq->number==NULL) + return -1; + if (to==NULL) + { + osip_message_free(message); + return -1; + } + + i = _eXosip_pub_find_by_aor(&pub, to); + if (i!=0 || pub==NULL) + { + osip_header_t *expires; + osip_message_get_expires(message, 0, &expires); + if (expires==NULL || expires->hvalue==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: missing expires header in PUBLISH!")); + osip_message_free(message); + return -1; + } + else + { + /* start a new publication context */ + _eXosip_pub_init(&pub, to, expires->hvalue); + if (pub==NULL) return -1; + ADD_ELEMENT(eXosip.j_pub, pub); + } + } + else + { + if (pub->p_sip_etag!=NULL && pub->p_sip_etag[0]!='\0') + { + /* increase cseq */ + osip_message_set_header(message, "SIP-If-Match", pub->p_sip_etag); + } + + if (pub->p_last_tr!=NULL && pub->p_last_tr->cseq!=NULL + &&pub->p_last_tr->cseq->number!=NULL) + { + int osip_cseq_num = osip_atoi(pub->p_last_tr->cseq->number); + int length = strlen(pub->p_last_tr->cseq->number); + + osip_cseq_num++; + osip_free(message->cseq->number); + message->cseq->number = (char*)osip_malloc(length+2); /* +2 like for 9 to 10 */ + sprintf(message->cseq->number, "%i", osip_cseq_num); + } + } + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + message); + if (i!=0) + { + osip_message_free(message); + return -1; + } + + if (pub->p_last_tr!=NULL) + osip_list_add(eXosip.j_transactions, pub->p_last_tr, 0); + pub->p_last_tr = transaction; + + sipevent = osip_new_outgoing_sipmessage(message); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, NULL, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_subscribe (char *to, char *from, char *route) +{ + eXosip_subscribe_t *js; + osip_message_t *subscribe; + osip_transaction_t *transaction; + osip_event_t *sipevent; + int i; + + i = generating_initial_subscribe(&subscribe, to, from, route); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot subscribe (cannot build SUBSCRIBE)! ")); + return -1; + } + + i = eXosip_subscribe_init(&js, to); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot subscribe.")); + return -1; + } + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + subscribe); + if (i!=0) + { + osip_message_free(subscribe); + return -1; + } + + _eXosip_subscribe_set_refresh_interval(js, subscribe); + js->s_out_tr = transaction; + + sipevent = osip_new_outgoing_sipmessage(subscribe); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, NULL, js, NULL)); + osip_transaction_add_event(transaction, sipevent); + + ADD_ELEMENT(eXosip.j_subscribes, js); + eXosip_update(); /* fixed? */ + __eXosip_wakeup(); + return 0; +} + + +int eXosip_subscribe_refresh (int sid, char *expires) +{ + int i; + eXosip_dialog_t *jd = NULL; + eXosip_subscribe_t *js = NULL; + + if (sid>0) + { + eXosip_subscribe_dialog_find(sid, &js, &jd); + } + if (js==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No subscribe here?\n")); + return -1; + } + + if (jd==NULL) + { + osip_transaction_t *tr; + osip_transaction_t *newtr; + osip_message_t *sub; + osip_event_t *sipevent; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No subscribe dialog here?\n")); + + tr=eXosip_find_last_out_subscribe(js,NULL); + if (tr==NULL){ + eXosip_trace(OSIP_INFO1,("eXosip_retry_last_sub: No such transaction.")); + return -1; + } + if (tr->last_response==NULL){ + eXosip_trace(OSIP_INFO1,("eXosip_retry_last_sub: transaction has not been answered.")); + return -1; + } + sub=eXosip_prepare_request_for_auth(tr->orig_request); + if (sub==NULL) return -1; + eXosip_add_authentication_information(sub,tr->last_response); + + if (expires==NULL) + osip_message_set_expires(sub, "3600"); + else + osip_message_set_expires(sub, expires); + + osip_message_force_update(sub); + i = osip_transaction_init(&newtr, + NICT, + eXosip.j_osip, + sub); + if (i!=0) + { + osip_message_free(sub); + return -1; + } + + if (jd!=NULL) + osip_list_add(jd->d_out_trs, newtr, 0); + else + { + js->s_out_tr = newtr; + /* remove old transaction */ + osip_list_add(eXosip.j_transactions, tr, 0); + } + + sipevent = osip_new_outgoing_sipmessage(sub); + + osip_transaction_set_your_instance(newtr, tr->your_instance); + osip_transaction_set_your_instance(tr, NULL); + osip_transaction_add_event(newtr, sipevent); + + eXosip_update(); /* fixed? */ + __eXosip_wakeup(); + return -1; + } + +#ifdef LOW_EXPIRE + if (expires==NULL) + i = eXosip_subscribe_send_subscribe(js, jd, "60"); + else + i = eXosip_subscribe_send_subscribe(js, jd, expires); +#else + if (expires==NULL) + i = eXosip_subscribe_send_subscribe(js, jd, "3600"); + else + i = eXosip_subscribe_send_subscribe(js, jd, expires); +#endif + return i; +} + +int eXosip_subscribe_close(int sid) +{ + int i; + eXosip_dialog_t *jd = NULL; + eXosip_subscribe_t *js = NULL; + + if (sid>0) + { + eXosip_subscribe_dialog_find(sid, &js, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No subscribe dialog here?\n")); + return -1; + } + + i = eXosip_subscribe_send_subscribe(js, jd, "0"); + return i; +} + +int eXosip_transfer_send_notify(int jid, int subscription_status, char *body) +{ + eXosip_dialog_t *jd = NULL; + eXosip_call_t *jc = NULL; + + if (jid>0) + { + eXosip_call_dialog_find(jid, &jc, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (jd==NULL || jd->d_dialog==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No established dialog!")); + return -1; + } + + return _eXosip_transfer_send_notify(jc, jd, subscription_status, body); +} + +int _eXosip_transfer_send_notify(eXosip_call_t *jc, + eXosip_dialog_t *jd, + int subscription_status, + char *body) +{ + osip_transaction_t *transaction; + osip_message_t *notify; + osip_event_t *sipevent; + int i; + char subscription_state[50]; + char *tmp; + + transaction = eXosip_find_last_inc_refer(jc, jd); + if (transaction==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No pending transfer!\n")); + return -1; + } + + transaction = eXosip_find_last_out_notify_for_refer(jc, jd); + if (transaction!=NULL) + { + if (transaction->state!=NICT_TERMINATED && + transaction->state!=NIST_TERMINATED) + return -1; + transaction=NULL; + } + + i = _eXosip_build_request_within_dialog(¬ify, "NOTIFY", jd->d_dialog, "UDP"); + if (i!=0) + return -2; + + if (subscription_status==EXOSIP_SUBCRSTATE_PENDING) + osip_strncpy(subscription_state, "pending;expires=", 16); + else if (subscription_status==EXOSIP_SUBCRSTATE_ACTIVE) + osip_strncpy(subscription_state, "active;expires=", 15); + else if (subscription_status==EXOSIP_SUBCRSTATE_TERMINATED) + { + int reason = NORESOURCE; + if (reason==DEACTIVATED) + osip_strncpy(subscription_state, "terminated;reason=deactivated", 29); + else if (reason==PROBATION) + osip_strncpy(subscription_state, "terminated;reason=probation", 27); + else if (reason==REJECTED) + osip_strncpy(subscription_state, "terminated;reason=rejected", 26); + else if (reason==TIMEOUT) + osip_strncpy(subscription_state, "terminated;reason=timeout", 25); + else if (reason==GIVEUP) + osip_strncpy(subscription_state, "terminated;reason=giveup", 24); + else if (reason==NORESOURCE) + osip_strncpy(subscription_state, "terminated;reason=noresource", 29); + } + tmp = subscription_state + strlen(subscription_state); + if (subscription_status!=EXOSIP_SUBCRSTATE_TERMINATED) + sprintf(tmp, "%i", 180); + osip_message_set_header(notify, "Subscription-State", + subscription_state); + + /* add a body */ + if (body!=NULL) + { + osip_message_set_body(notify, body, strlen(body)); + osip_message_set_content_type(notify, "message/sipfrag"); + } + + osip_message_set_header(notify, "Event", "refer"); + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + notify); + if (i!=0) + { + osip_message_free(notify); + return -1; + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(notify); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_notify_send_notify(eXosip_notify_t *jn, + eXosip_dialog_t *jd, + int subscription_status, + int online_status) +{ + osip_transaction_t *transaction; + osip_message_t *notify; + osip_event_t *sipevent; + int i; + char subscription_state[50]; + char *tmp; + int now = time(NULL); + transaction = eXosip_find_last_out_notify(jn, jd); + if (transaction!=NULL) + { + if (transaction->state!=NICT_TERMINATED && + transaction->state!=NIST_TERMINATED) + return -1; + transaction=NULL; + } + +#ifndef SUPPORT_MSN + +#else + + /* DO NOT SEND ANY NOTIFY when the status + is not active (or terminated?) */ + if (subscription_status!=EXOSIP_SUBCRSTATE_ACTIVE + && subscription_status!=EXOSIP_SUBCRSTATE_TERMINATED) + { + /* set the new state anyway! */ + jn->n_online_status = online_status; + jn->n_ss_status = subscription_status; + return -1; + } + +#endif + + i = _eXosip_build_request_within_dialog(¬ify, "NOTIFY", jd->d_dialog, "UDP"); + if (i!=0) + return -2; + + jn->n_online_status = online_status; + jn->n_ss_status = subscription_status; + + /* add the notifications info */ + if (jn->n_ss_status==EXOSIP_SUBCRSTATE_UNKNOWN) + jn->n_online_status=EXOSIP_SUBCRSTATE_PENDING; + +#ifndef SUPPORT_MSN + if (jn->n_ss_status==EXOSIP_SUBCRSTATE_PENDING) + osip_strncpy(subscription_state, "pending;expires=", 16); + else if (jn->n_ss_status==EXOSIP_SUBCRSTATE_ACTIVE) + osip_strncpy(subscription_state, "active;expires=", 15); + else if (jn->n_ss_status==EXOSIP_SUBCRSTATE_TERMINATED) + { + if (jn->n_ss_reason==DEACTIVATED) + osip_strncpy(subscription_state, "terminated;reason=deactivated", 29); + else if (jn->n_ss_reason==PROBATION) + osip_strncpy(subscription_state, "terminated;reason=probation", 27); + else if (jn->n_ss_reason==REJECTED) + osip_strncpy(subscription_state, "terminated;reason=rejected", 26); + else if (jn->n_ss_reason==TIMEOUT) + osip_strncpy(subscription_state, "terminated;reason=timeout", 25); + else if (jn->n_ss_reason==GIVEUP) + osip_strncpy(subscription_state, "terminated;reason=giveup", 24); + else if (jn->n_ss_reason==NORESOURCE) + osip_strncpy(subscription_state, "terminated;reason=noresource", 29); + } + tmp = subscription_state + strlen(subscription_state); + if (jn->n_ss_status!=EXOSIP_SUBCRSTATE_TERMINATED) + sprintf(tmp, "%i", jn->n_ss_expires-now); + osip_message_set_header(notify, "Subscription-State", + subscription_state); +#endif + + /* add a body */ + i = _eXosip_notify_add_body(jn, notify); + if (i!=0) + { + + } + +#ifdef SUPPORT_MSN +#else + osip_message_set_header(notify, "Event", "presence"); +#endif + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + notify); + if (i!=0) + { + /* TODO: release the j_call.. */ + osip_message_free(notify); + return -1; + } + + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(notify); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, NULL, jn)); + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + return 0; +} + +int eXosip_notify (int nid, int subscription_status, int online_status) +{ + int i; + eXosip_dialog_t *jd = NULL; + eXosip_notify_t *jn = NULL; + + if (nid>0) + { + eXosip_notify_dialog_find(nid, &jn, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No subscribe dialog here?\n")); + return -1; + } + + i = eXosip_notify_send_notify(jn, jd, subscription_status, online_status); + return i; +} + + +int eXosip_notify_accept_subscribe(int nid, int code, + int subscription_status, + int online_status) +{ + int i = 0; + eXosip_dialog_t *jd = NULL; + eXosip_notify_t *jn = NULL; + if (nid>0) + { + eXosip_notify_dialog_find(nid, &jn, &jd); + } + if (jd==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: No call here?\n")); + return -1; + } + if (code>100 && code<200) + { + eXosip_notify_answer_subscribe_1xx(jn, jd, code); + } + else if (code>199 && code<300) + { + eXosip_notify_answer_subscribe_2xx(jn, jd, code); + i = eXosip_notify(nid, subscription_status, online_status); + } + else if (code>300 && code<699) + { + eXosip_notify_answer_subscribe_3456xx(jn, jd, code); + } + else + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: wrong status code (101url!=NULL && a_from->url->username!=NULL ) + { + if (eXosip.j_firewall_ip[0]!='\0') + { + if (public_net) + { + if (eXosip.localport==NULL) + snprintf(contact, bufsize, "", a_from->url->username, + eXosip.j_firewall_ip); + else + snprintf(contact, bufsize, "", a_from->url->username, + eXosip.j_firewall_ip, + eXosip.localport); + } + else + { + if (eXosip.localport==NULL) + snprintf(contact, bufsize, "", a_from->url->username, + locip); + else + snprintf(contact, bufsize, "", a_from->url->username, + locip, + eXosip.localport); + } + } + else + { + if (eXosip.localport==NULL) + snprintf(contact, bufsize, "", a_from->url->username, + locip); + else + snprintf(contact, bufsize, "", a_from->url->username, + locip, + eXosip.localport); + } + + osip_from_free(a_from); + } +} + +void eXosip_set_answer_contact(const char *contacturl) +{ + osip_strncpy(eXosip.answer_contact, contacturl ? contacturl : "", sizeof(eXosip.answer_contact)-1); +} diff --git a/linphone/exosip/eXosip.h b/linphone/exosip/eXosip.h new file mode 100644 index 000000000..d6881be5b --- /dev/null +++ b/linphone/exosip/eXosip.h @@ -0,0 +1,752 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#ifndef __EXOSIP_H__ +#define __EXOSIP_H__ + +#include +#include +#include + +/** + * @file eXosip.h + * @brief eXosip API + * + * eXosip is a high layer library for rfc3261: the SIP protocol. + * It has limited API and functionnalities to make it easy to use. + * If you need complexity in your SIP applications, you may prefer + * to use directly osip. + * + * eXosip capabilities: + * REGISTER to handle mobility. + * INVITE/BYE/OPTIONS to start/stop VoIP sessions. + * re-INVITE to modify VoIP sessions (On-hold/Off-hold) + * MESSAGE to send Instant Message. + * SUBSCRIBE/NOTIFY to handle presence capabilities. + * + *

+ */ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * @defgroup eXosip eXosip Management + * @ingroup eXosip + * @{ + */ + +/** + * Use IPv6 instead of IPv4. + * + * @param ipv6_enable This paramter should be set to 1 to enable IPv6. + */ +void eXosip_enable_ipv6(int ipv6_enable); + +/** + * Initiate the eXtented oSIP library. + * + * @param input command input (RESERVED FOR FUTUR USE). + * @param output resulting output (RESERVED FOR FUTUR USE). + * @param port The SIP port to use. (5060 is the default) + */ +int eXosip_init(FILE *input, FILE *output, int port); + + +/** + * Force eXosip to use a specific local ip address in all its SIP message. + * + * @param localip the ip address. + * + * If set to NULL, then the local ip address will be guessed + * automatically (returns to default mode). + */ +int eXosip_force_localip(const char *localip); + +/** + * Release ressource used by the eXtented oSIP library. + * + */ +void eXosip_quit(void); + +/** + * Automatic refresh of subscription and register + * send subscribe refresh when subscription is close to expiration. + * send register refresh when registration is close to expiration. + * + */ +void eXosip_automatic_refresh(void); + +/** + * Wake Up the eXosip_event_wait method. + * + */ +void __eXosip_wakeup_event(void); + +/** + * This method is used to modify the sdp connection address + * When you are behind a NAT. (EXPERIMENTAL) + * + */ +void eXosip_set_firewallip(const char *firewall_address); + +/** + * This method is used to modify NAT firewall type + * When you are behind a NAT. (EXPERIMENTAL) + * @param nat type ("", "fcone", "rcone", "prcone", "sym") + */ +void eXosip_set_nattype(const char *nat_type); + +/** + * This method is used to force ALL SIP packets to go through given proxy + * @param proxyurl - when empty disable forced proxy behaviour + */ +void eXosip_force_proxy(const char *proxyurl); + +/** + * This method is used to set contact header on answers which establishes dialogs + * @param contacturl - the url to use for conatct SIP header, + * when empty - the contact header will be generated from 'to' + * header of the incoming request + */ +void eXosip_set_answer_contact(const char *contacturl); + +/** + * This method is used to build a contact header for SIP packets + * @param url url from wich username part will be extracted + * @param strbuf buffer where the result will be stored + * @param bufsize size of the 'strbuf' + * @param public_net when TRUE use firewall ip (if defined) as hostname part + * else use local host ip + * + */ +void eXosip_guess_contact_uri(const char *url, char *strbuf, int bufsize, int public_net); + +/** + * Find the current localip (interface with default route). + * ****DEPRECATED**** Use eXosip_guess_localip + * + * @param ip a string containing the local IP address. + */ +void eXosip_get_localip(char *ip); + +/** + * Find the current localip (interface with default route). + * + * @param family AF_INET or AF_INET6 + * @param address a string containing the local IP address. + * @param size The size of the string + */ +int eXosip_guess_localip(int family, char *address, int size); + +/** + * Find the interface to be used to reach the specified host. + * + * @param ip a string containing the local IP address. + * @param localip the local ip address to be used to reach host. + * + * You usually don't need this function at all. + */ +void eXosip_get_localip_for(char *host, char **localip); + +/** + * Add authentication credentials. These are used when an outgoing + * request comes back with an authorization required response. + * + * @param username username + * @param userid not sure what this is for + * @param passwd password + * @param ha1 currently ignored + * @param realm realm within which credentials apply, or NULL + * to apply credentials to unrecognized realms + */ +int eXosip_add_authentication_info(const char *username, const char *userid, + const char *passwd, const char *ha1, + const char *realm); + +/** + * Clear all authentication credentials stored in eXosip. + * + */ +int eXosip_clear_authentication_info(void); + +/** + * Remove an audio payload. + * + */ +void eXosip_sdp_negotiation_remove_audio_payloads(void); + +/** + * Remove an audio payload. + * + * @param payload The payload + * @param number_of_port The number of port + * @param proto The protocol + * @param c_nettype The connection type of network + * @param c_addrtype The connection type of address + * @param c_addr The connection address + * @param c_addr_multicast_ttl The multicast TTL value + * @param c_addr_multicast_int ? + * @param a_rtpmap The rtpmap of element. + */ +void eXosip_sdp_negotiation_add_codec(char *payload, char *number_of_port, + char *proto, char *c_nettype, + char *c_addrtype, char *c_addr, + char *c_addr_multicast_ttl, + char *c_addr_multicast_int, + char *a_rtpmap); + +/** + * Replace the internal SDP negociator facility. + * + * @param sn The new negociator context + */ +int eXosip_sdp_negotiation_replace(osip_negotiation_t *sn); + +struct eXosip_call_t; + +/** + * Set the reference element to be used in callback for the negociator. + * This must be done only if eXosip_sdp_negotiation_replace has been + * used and must not be done if this method has not been used. + * + * @param jc The related call. + * @param sn The new negociator context. + */ +void eXosip_sdp_negotiation_ctx_set_mycontext(struct eXosip_call_t *jc, void *arg); + +#define DEFAULT_MODE 2 +#define CALLBACK_MODE 1 +#define EVENT_MODE 2 +/** + * Set the functionnal mode of eXosip. + * The default mode is the EVENT_MODE. + * + * @param mode mode to use. + */ +void eXosip_set_mode(int mode); + +/** + * Set the SIP User-Agent: header string. + */ +void eXosip_set_user_agent(const char *user_agent); + +/** + * Lock the eXtented oSIP library. + * + */ +int eXosip_lock(void); + +/** + * UnLock the eXtented oSIP library. + * + */ +int eXosip_unlock(void); + +/** @} */ + +/** + * @defgroup eXosip_call eXosip Call Management + * @ingroup eXosip + * @{ + */ + +/** + * Build a default INVITE message for a new call. + * + * @param invite Pointer for the SIP element to hold. + * @param to SIP url for callee. + * @param from SIP url for caller. + * @param route Route header for INVITE. (optionnal) + * @param subject Subject for the call. + */ +int eXosip_build_initial_invite(osip_message_t **invite, char *to, + char *from, char *route, char *subject); +/** + * Initiate a call. + * + * @param invite SIP INVITE message to send. + * @param reference Application context. (optionnal) + * @param sdp_reference_context Sdp Application context. (optionnal) + * @param local_sdp_port The port to be used for this call. + */ +int eXosip_initiate_call (osip_message_t *invite, void *reference, + void *sdp_context_reference, char *local_sdp_port); + +/** + * Initiate a call with the specified body-type and body + * + * @param invite SIP INVITE message to send. + * @param body_type body type (ex: "application/sdp") + * @param body The body. + */ +int eXosip_initiate_call_with_body (osip_message_t *invite, const char *body_type, const char *body, void *reference); + + +/** + * When a call failed to initiate due to authorization reasons (407), retry the call using the authentication information + * previously stored in eXosip using eXosip_add_authentication_info() + * + * @param cid The eXosip call id as returned by eXosip_initiate_call*() + */ +int eXosip_retry_call (int cid); + +/** + * Initiate a blind transfer outside of a call. + * (probably not supported by many softphone...) + * + * @param refer_to SIP url for transfer. + * @param from SIP url for caller. + * @param to SIP url for callee. + * @param route Route header for REFER. (optionnal) + */ + int eXosip_transfer_call_out_of_dialog(char *refer_to, char *from, char *to, char *route); + +/** + * Set redirection url before a call to eXosip_answer_call. + * + * @param jid dialog id of call. + * @param contact contact address. + */ + int eXosip_set_redirection_address (int jid, char *contact); + +/** + * Answer call. + * + * @param jid dialog id of call. + * @param status Status code to use. + */ +int eXosip_answer_call (int jid, int status, char *local_sdp_port); + +/** + * Answer call. + * + * @param jid dialog id of call. + * @param status Status code to use. + * @param answer The resulting sip answer to send. + */ +int eXosip2_answer (int jid, int status, osip_message_t **answer); + +/** + * Answer call. + * + * @param jid dialog id of call. + * @param answer The sip answer to send. + */ +int eXosip2_answer_send(int jid, osip_message_t *answer); + +/** + * Answer call with the specified body. + * + * @param jid dialog id of call. + * @param status Status code to use. + * @param body_type body type (ex: "application/sdp") + * @param body The body. + */ +int eXosip_answer_call_with_body (int jid, int status,const char *body_type, const char*body); + + +/** + * Retreive payload negotiated for this dialog + * + * @param jid dialog id of call. + * @param payload will hold the negotited payload code + * @param payload_name will hold negotioated payload mime string + * @param pnsize size of the payload_name buffer + */ +int eXosip_retrieve_negotiated_payload(int jid, int *payload, char *payload_name, int pnsize); + +/** + * Set a new application context for an existing call + * + * @param jc Pointer to the call to modify + * @param reference New application context. + */ +int eXosip_set_call_reference(int jid, void *reference); + +/** + * Put a call on hold. + * + * @param jid dialog id of call. + */ +int eXosip_on_hold_call (int jid); +int eXosip_off_hold_call (int jid, char *rtp_ip, int port); + +/** + * Tranfer a call. + * + * @param jid dialog id of call. + * @param refer_to SIP Url for transfer. + */ +int eXosip_transfer_call(int jid, char *refer_to); + +/** + * Tranfer a call. + * + * @param jid dialog id of call. + * @param refer_to SIP Url for transfer. + */ +int eXosip_transfer_send_notify(int jid, int subscription_status, char *body); + +/** + * Terminate a call. + * + * @param cid call id of call. + * @param jid dialog id of call. + */ +int eXosip_terminate_call(int cid, int jid); + +/** + * Send an OPTIONS message within a call. + * + * @param cid call id of call. + * @param jid dialog id of call. + */ +int eXosip_options_call (int jid); + +/** + * Send an INFO message within a call. + * + * @param jid dialog id of call. + * @param content_type content-type of body. + * @param body body to attach. + */ +int eXosip_info_call(int jid, char *content_type, char *body); + +/** + * Answer an OPTIONS message. + * + * @param cid call id of call. + * @param jid dialog id of call. + */ +int eXosip_answer_options(int cid, int jid, int status); + +/** @} */ + +/** + * @defgroup eXosip_registration eXosip Registration Management + * @ingroup eXosip + * @{ + */ + +/** + * Send initial registration to a server. (REGISTER request) + * + * @param from SIP url for caller. + * @param proxy Proxy used for registration. + * @param contact Contact address. (optionnal) + * @param route Outbound proxy address. (optionnal) + */ +int eXosip_register_init (char *from, char *proxy, char *contact, char* route); + +/** + * Update the registration. (REGISTER request) + * + * @param rid . + * @param expires The expires value for registration. + */ +int eXosip_register (int rid, int expires); + +/** @} */ + +/** + * @defgroup eXosip_impp eXosip Instant Messaging and Presence Management + * @ingroup eXosip + * @{ + */ + +/** + * Send an Instant Message (MESSAGE request). + * + * @param rid . + */ +int eXosip_message (char *to, char *from, char *route, char *buff); + +/** + * build publication for a user. (PUBLISH request) + * + * @param message returned published request. + * @param to SIP url for callee. + * @param from SIP url for caller. + * @param route Route used for publication. + * @param event SIP Event header. + * @param expires SIP Expires header. + * @param ctype Content-Type of body. + * @param body body for publication. + */ +int eXosip_build_publish(osip_message_t **message, + char *to, + char *from, + char *route, + const char *event, + const char *expires, + const char *ctype, + const char *body); + +/** + * Send an Publication Message (PUBLISH request). + * + * @param message is a ready to be sent publish message . + * @param sip_if_match is the SIP-If-Match header. (NULL for initial publication) + */ +int eXosip_publish (osip_message_t *message, const char *sip_if_match); + +/** + * Send initial subscription to a user. (SUBSCRIBE request) + * + * @param to SIP url for callee. + * @param from SIP url for caller. + * @param route Route used for registration. + */ +int eXosip_subscribe(char *to, char *from, char *route); + +/** + * Update a subscription (SUBSCRIBE request). + * + * @param sid id of subscription. + * @param expires Time between updates. + */ +int eXosip_subscribe_refresh(int sid, char *expires); + +/** + * Close a subscription (SUBSCRIBE request). + * + * @param sid id of subscription. + */ +int eXosip_subscribe_close(int sid); + +typedef enum eXosip_ss { + EXOSIP_SUBCRSTATE_UNKNOWN, + EXOSIP_SUBCRSTATE_PENDING, + EXOSIP_SUBCRSTATE_ACTIVE, + EXOSIP_SUBCRSTATE_TERMINATED +} eXosip_ss_t; + +typedef enum eXosip_ss_reason { + DEACTIVATED, + PROBATION, + REJECTED, + TIMEOUT, + GIVEUP, + NORESOURCE +} eXosip_ss_reason_t; + + /* typo error */ +#define NORESSOURCE NORESOURCE + +typedef enum eXosip_ss_status { + EXOSIP_NOTIFY_UNKNOWN, + EXOSIP_NOTIFY_PENDING, /* subscription not yet accepted */ + EXOSIP_NOTIFY_ONLINE, + EXOSIP_NOTIFY_BUSY, + EXOSIP_NOTIFY_BERIGHTBACK, + EXOSIP_NOTIFY_AWAY, + EXOSIP_NOTIFY_ONTHEPHONE, + EXOSIP_NOTIFY_OUTTOLUNCH, + EXOSIP_NOTIFY_CLOSED +} eXosip_ss_status_t; + +/** + * Accept a subscription and notify state (NOTIFY request). + * + * @param nid call id of call. + * @param code code for answer to subscribe. + * @param subscription_status subscription status. + * @param online_status online status to send. + */ +int eXosip_notify_accept_subscribe (int nid, int code, int subscription_status, int online_status); + +/** + * Update a subscription and notify state (NOTIFY request). + * + * @param nid call id of call. + * @param subscription_status subscription status. + * @param online_status online status to send. + */ +int eXosip_notify(int nid, int subscription_status, int online_status); + +/** @} */ + + +int eXosip_send_ack(int did); + +/** + * @defgroup eXosip_event eXosip event Management + * @ingroup eXosip + * @{ + */ +typedef enum eXosip_event_type_t { + + /* Registration Info */ + EXOSIP_REGISTRATION_NEW, /* announce new registration. */ + EXOSIP_REGISTRATION_SUCCESS, /* user is successfully registred. */ + EXOSIP_REGISTRATION_FAILURE, /* user is not registred. */ + EXOSIP_REGISTRATION_REFRESHED, /* registration has been refreshed. */ + EXOSIP_REGISTRATION_TERMINATED, /* UA is not registred any more. */ + + /* for UAC events */ + EXOSIP_CALL_NOANSWER, /* announce no answer within the timeout */ + EXOSIP_CALL_PROCEEDING, /* announce processing by a remote app */ + EXOSIP_CALL_RINGING, /* announce ringback */ + EXOSIP_CALL_ANSWERED, /* announce start of call */ + EXOSIP_CALL_REDIRECTED, /* announce a redirection */ + EXOSIP_CALL_REQUESTFAILURE, /* announce a request failure */ + EXOSIP_CALL_SERVERFAILURE, /* announce a server failure */ + EXOSIP_CALL_GLOBALFAILURE, /* announce a global failure */ + + /* for UAS events */ + EXOSIP_CALL_NEW, /* announce a new call */ + EXOSIP_CALL_ACK, /* ACK received for 200ok to INVITE */ + EXOSIP_CALL_CANCELLED, /* announce that call has been cancelled */ + EXOSIP_CALL_TIMEOUT, /* announce that call has failed */ + EXOSIP_CALL_HOLD, /* audio must be stopped */ + EXOSIP_CALL_OFFHOLD, /* audio must be restarted */ + EXOSIP_CALL_CLOSED, /* a BYE was received for this call */ + + /* for both UAS & UAC events */ + EXOSIP_CALL_STARTAUDIO, /* audio must be established */ + EXOSIP_CALL_RELEASED, /* call context is cleared. */ + + /* for UAC events */ + EXOSIP_OPTIONS_NOANSWER, /* announce no answer within the timeout */ + EXOSIP_OPTIONS_PROCEEDING, /* announce processing by a remote app */ + EXOSIP_OPTIONS_ANSWERED, /* announce a 200ok */ + EXOSIP_OPTIONS_REDIRECTED, /* announce a redirection */ + EXOSIP_OPTIONS_REQUESTFAILURE, /* announce a request failure */ + EXOSIP_OPTIONS_SERVERFAILURE, /* announce a server failure */ + EXOSIP_OPTIONS_GLOBALFAILURE, /* announce a global failure */ + + EXOSIP_INFO_NOANSWER, /* announce no answer within the timeout */ + EXOSIP_INFO_PROCEEDING, /* announce processing by a remote app */ + EXOSIP_INFO_ANSWERED, /* announce a 200ok */ + EXOSIP_INFO_REDIRECTED, /* announce a redirection */ + EXOSIP_INFO_REQUESTFAILURE, /* announce a request failure */ + EXOSIP_INFO_SERVERFAILURE, /* announce a server failure */ + EXOSIP_INFO_GLOBALFAILURE, /* announce a global failure */ + + /* for UAS events */ + EXOSIP_OPTIONS_NEW, /* announce a new options method */ + EXOSIP_INFO_NEW, /* new info request received */ + + EXOSIP_MESSAGE_NEW, /* announce new incoming MESSAGE. */ + EXOSIP_MESSAGE_SUCCESS, /* announce a 200ok to a previous sent */ + EXOSIP_MESSAGE_FAILURE, /* announce a failure. */ + + /* Presence and Instant Messaging */ + EXOSIP_SUBSCRIPTION_NEW, /* announce new incoming SUBSCRIBE. */ + EXOSIP_SUBSCRIPTION_UPDATE, /* announce incoming SUBSCRIBE. */ + EXOSIP_SUBSCRIPTION_CLOSED, /* announce end of subscription. */ + + EXOSIP_SUBSCRIPTION_NOANSWER, /* announce no answer */ + EXOSIP_SUBSCRIPTION_PROCEEDING, /* announce a 1xx */ + EXOSIP_SUBSCRIPTION_ANSWERED, /* announce a 200ok */ + EXOSIP_SUBSCRIPTION_REDIRECTED, /* announce a redirection */ + EXOSIP_SUBSCRIPTION_REQUESTFAILURE, /* announce a request failure */ + EXOSIP_SUBSCRIPTION_SERVERFAILURE, /* announce a server failure */ + EXOSIP_SUBSCRIPTION_GLOBALFAILURE, /* announce a global failure */ + EXOSIP_SUBSCRIPTION_NOTIFY, /* announce new NOTIFY request */ + + EXOSIP_SUBSCRIPTION_RELEASED, /* call context is cleared. */ + + EXOSIP_IN_SUBSCRIPTION_NEW, /* announce new incoming SUBSCRIBE.*/ + EXOSIP_IN_SUBSCRIPTION_RELEASED, /* announce end of subscription. */ + + EXOSIP_CALL_REFERED, /* announce incoming REFER */ + EXOSIP_CALL_REFER_STATUS, /* announce incoming NOTIFY */ + + EXOSIP_CALLBACK_COUNT +} eXosip_event_type_t; + +typedef struct eXosip_event { + eXosip_event_type_t type; + void *external_reference; + char reason_phrase[50]; + int status_code; + + char textinfo[256]; + char req_uri[256]; + char local_uri[256]; + char remote_uri[256]; + char remote_contact[256]; + char refer_to[256]; + char subject[256]; + osip_content_type_t *i_ctt; + osip_list_t *i_bodies; + + char remote_sdp_audio_ip[50]; + int remote_sdp_audio_port; + int local_sdp_audio_port; + int payload; + char payload_name[50]; + char sdp_body[1000]; /* The whole SDP body */ + int online_status; + int ss_status; + int ss_reason; + + /* For a high level usage of the eXosip stack? (API is enough?) */ + int did; + int cid; + int rid; + int sid; + int nid; + + /* For a low level usage of the eXosip stack */ + struct eXosip_dialog_t *jd; + struct eXosip_call_t *jc; + struct eXosip_reg_t *jr; + struct eXosip_subscribe_t *js; + struct eXosip_notify_t *jn; + +} eXosip_event_t; + +/** + * Free ressource in an eXosip event. + * + * @param je event to work on. + */ +void eXosip_event_free(eXosip_event_t *je); + +/** + * Wait for an eXosip event. (FUTURE USE) + * + * @param tv_s timeout value (seconds). + * @param tv_ms timeout value (mseconds). + */ +eXosip_event_t *eXosip_event_wait(int tv_s, int tv_ms); + + +/** + * Wait for next eXosip event. + * + */ +eXosip_event_t *eXosip_event_get(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/exosip/eXosip2.h b/linphone/exosip/eXosip2.h new file mode 100644 index 000000000..5f3f32163 --- /dev/null +++ b/linphone/exosip/eXosip2.h @@ -0,0 +1,510 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#ifndef __EXOSIP2_H__ +#define __EXOSIP2_H__ + +#ifdef WIN32 +#include +#include +#include +#include +#define snprintf _snprintf +#define close(s) closesocket(s) +#else +#include +#include +#include +#include +#include +#endif + +#include + +#include +#include +#include + +#include +#include + +#include "jpipe.h" + +#ifndef JD_EMPTY + +#define JD_EMPTY 0 +#define JD_INITIALIZED 1 +#define JD_TRYING 2 +#define JD_QUEUED 3 +#define JD_RINGING 4 +#define JD_ESTABLISHED 5 +#define JD_REDIRECTED 6 +#define JD_AUTH_REQUIRED 7 +#define JD_CLIENTERROR 8 +#define JD_SERVERERROR 9 +#define JD_GLOBALFAILURE 10 +#define JD_TERMINATED 11 + +#define JD_MAX 11 + +#endif + +#define EXOSIP_VERSION "0.1" + +#ifdef __cplusplus +extern "C" +{ +#endif + +void eXosip_update(void); +void __eXosip_wakeup(void); + +typedef struct eXosip_dialog_t eXosip_dialog_t; + +struct eXosip_dialog_t { + + int d_id; + int d_STATE; + osip_dialog_t *d_dialog; /* active dialog */ + + int d_timer; + osip_message_t *d_200Ok; + osip_message_t *d_ack; + osip_list_t *media_lines; + + osip_list_t *d_inc_trs; + osip_list_t *d_out_trs; + + /* struct _BodyHandler *d_bh; */ + + eXosip_dialog_t *next; + eXosip_dialog_t *parent; +}; + +typedef struct eXosip_subscribe_t eXosip_subscribe_t; + +struct eXosip_subscribe_t { + + int s_id; + char s_uri[255]; + int s_online_status; + int s_ss_status; + int s_ss_reason; + int s_ss_expires; + eXosip_dialog_t *s_dialogs; + + osip_transaction_t *s_inc_tr; + osip_transaction_t *s_out_tr; + + eXosip_subscribe_t *next; + eXosip_subscribe_t *parent; +}; + +typedef struct eXosip_notify_t eXosip_notify_t; + +struct eXosip_notify_t { + + int n_id; + char n_uri[255]; + int n_online_status; + char *n_contact_info; + + int n_ss_status; + int n_ss_reason; + int n_ss_expires; + eXosip_dialog_t *n_dialogs; + + osip_transaction_t *n_inc_tr; + osip_transaction_t *n_out_tr; + + eXosip_notify_t *next; + eXosip_notify_t *parent; +}; + +typedef struct eXosip_call_t eXosip_call_t; + +struct eXosip_call_t { + + int c_id; + char c_subject[100]; + int c_ack_sdp; /* flag for alternative SDP offer-response model */ + eXosip_dialog_t *c_dialogs; + osip_transaction_t *c_inc_tr; + osip_transaction_t *c_out_tr; + osip_transaction_t *c_inc_options_tr; + osip_transaction_t *c_out_options_tr; + void *external_reference; + + osip_negotiation_ctx_t *c_ctx; + char c_sdp_port[10]; + + char c_redirection[1024]; /* contact for 3xx answers */ + + eXosip_call_t *next; + eXosip_call_t *parent; +}; + + +#if 0 +typedef struct eXosip_realm_t eXosip_realm_t; + +struct eXosip_realm_t { + + int r_id; + + char *r_realm; + char *r_username; + char *r_passwd; + + eXosip_realm_t *next; + eXosip_realm_t *parent; +}; +#endif + +typedef struct eXosip_reg_t eXosip_reg_t; + +struct eXosip_reg_t { + + int r_id; + + int r_reg_period; /* delay between registration */ + char *r_aor; /* sip identity */ + char *r_registrar; /* registrar */ + char *r_route; /* outbound proxy */ +#if 0 + eXosip_realm_t *r_realms; /* list of realms */ +#endif + char *r_contact; /* list of contacts string */ + + osip_transaction_t *r_last_tr; + eXosip_reg_t *next; + eXosip_reg_t *parent; +}; + + +typedef struct eXosip_pub_t eXosip_pub_t; + +struct eXosip_pub_t { + int p_id; + + time_t p_expires; /* expiration date (started+period) */ + int p_period; /* delay between registration */ + char p_aor[256]; /* sip identity */ + char p_sip_etag[64]; /* sip_etag from 200ok */ + + osip_transaction_t *p_last_tr; + eXosip_pub_t *next; + eXosip_pub_t *parent; +}; + +int _eXosip_pub_update(eXosip_pub_t **pub, osip_transaction_t *tr, osip_message_t *answer); +int _eXosip_pub_find_by_aor(eXosip_pub_t **pub, const char *aor); +int _eXosip_pub_init(eXosip_pub_t **pub, const char *aor, const char *exp); +void _eXosip_pub_free(eXosip_pub_t *pub); + +typedef struct jauthinfo_t jauthinfo_t; + +struct jauthinfo_t { + char username[50]; + char userid[50]; + char passwd[50]; + char ha1[50]; + char realm[50]; + jauthinfo_t *parent; + jauthinfo_t *next; +}; + +int +__eXosip_create_authorization_header(osip_message_t *previous_answer, + const char *rquri, const char *username, + const char *passwd, + osip_authorization_t **auth); +int +__eXosip_create_proxy_authorization_header(osip_message_t *previous_answer, + const char *rquri, + const char *username, + const char *passwd, + osip_proxy_authorization_t **auth); + + +eXosip_event_t *eXosip_event_init_for_call(int type, eXosip_call_t *jc, + eXosip_dialog_t *jd); +int eXosip_event_add_sdp_info(eXosip_event_t *je, osip_message_t *message); + +int eXosip_event_add_status(eXosip_event_t *je, osip_message_t *response); +eXosip_event_t *eXosip_event_init_for_subscribe(int type, + eXosip_subscribe_t *js, + eXosip_dialog_t *jd); +eXosip_event_t *eXosip_event_init_for_notify(int type, eXosip_notify_t *jn, + eXosip_dialog_t *jd); +eXosip_event_t *eXosip_event_init_for_reg(int type, eXosip_reg_t *jr); +eXosip_event_t *eXosip_event_init_for_message(int type, osip_transaction_t + *tr, osip_message_t *sip); +int eXosip_event_init(eXosip_event_t **je, int type); +eXosip_call_t *eXosip_event_get_callinfo(eXosip_event_t *je); +eXosip_dialog_t *eXosip_event_get_dialoginfo(eXosip_event_t *je); +eXosip_reg_t *eXosip_event_get_reginfo(eXosip_event_t *je); +eXosip_notify_t *eXosip_event_get_notifyinfo(eXosip_event_t *je); +eXosip_subscribe_t *eXosip_event_get_subscribeinfo(eXosip_event_t *je); +int eXosip_event_add(eXosip_event_t *je); +eXosip_event_t *eXosip_event_wait(int tv_s, int tv_ms); +eXosip_event_t *eXosip_event_get(void); + +typedef void (* eXosip_callback_t) (int type, eXosip_event_t *); + +char *strdup_printf(const char *fmt, ...); + +jfriend_t *jfriend_get(void); +jsubscriber_t *jsubscriber_get(void); +jidentity_t *jidentity_get(void); +int jfriend_get_and_set_next_token (char **dest, char *buf, + char **next); + +#define eXosip_trace(loglevel,args) do \ +{ \ + char *__strmsg; \ + __strmsg=strdup_printf args ; \ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,(loglevel),NULL,"%s\n",__strmsg)); \ + osip_free (__strmsg); \ +}while (0); + +typedef struct eXosip_t eXosip_t; + +struct eXosip_t { + int forced_localip; /* set to 1 when we must always use the default local ip */ + char *localip; /* default local ip */ + char *localport; + + char *user_agent; + + FILE *j_input; + FILE *j_output; + eXosip_call_t *j_calls; /* my calls */ + eXosip_subscribe_t *j_subscribes; /* my friends */ + eXosip_notify_t *j_notifies; /* my susbscribers */ + osip_list_t *j_transactions; + + eXosip_reg_t *j_reg; /* my registrations */ + eXosip_pub_t *j_pub; /* my publications */ + + void *j_cond; + void *j_mutexlock; + + osip_t *j_osip; + int j_socket; + int j_stop_ua; + void *j_thread; + jpipe_t *j_socketctl; + jpipe_t *j_socketctl_event; + + jsubscriber_t *j_subscribers; + jfriend_t *j_friends; + jidentity_t *j_identitys; + + int j_runtime_mode; + eXosip_callback_t j_call_callbacks[EXOSIP_CALLBACK_COUNT]; + osip_fifo_t *j_events; + + osip_negotiation_t *osip_negotiation; + char j_firewall_ip[50]; + jauthinfo_t *authinfos; + + int ip_family; /* AF_INET6 or AF_INET */ + char nat_type[16]; + char forced_proxy[256]; + char answer_contact[256]; /* conatact header value to use in answers */ +}; + +typedef struct jinfo_t jinfo_t; + +struct jinfo_t { + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; +}; + +int eXosip_guess_ip_for_via (int family, char *address, int size); + +int eXosip_sdp_negotiation_init(osip_negotiation_t **sn); +void eXosip_sdp_negotiation_free(osip_negotiation_t *sn); +int eXosip_retrieve_sdp_negotiation_result(osip_negotiation_ctx_t *ctx, char *payload_name, int pnsize); + + +sdp_message_t *eXosip_get_local_sdp_info(osip_transaction_t *invite_tr); +sdp_message_t *eXosip_get_remote_sdp_info(osip_transaction_t *invite_tr); +sdp_message_t *eXosip_get_local_sdp(osip_transaction_t *transaction); +sdp_message_t *eXosip_get_remote_sdp(osip_transaction_t *transaction); + + + +int eXosip_set_callbacks(osip_t *osip); +char *osip_call_id_new_random(void); +char *osip_to_tag_new_random(void); +char *osip_from_tag_new_random(void); +unsigned int via_branch_new_random(void); +void __eXosip_delete_jinfo(osip_transaction_t *transaction); +jinfo_t *__eXosip_new_jinfo(eXosip_call_t *jc, eXosip_dialog_t *jd, + eXosip_subscribe_t *js, eXosip_notify_t *jn); + +int eXosip_dialog_init_as_uac(eXosip_dialog_t **jd, osip_message_t *_200Ok); +int eXosip_dialog_init_as_uas(eXosip_dialog_t **jd, osip_message_t *_invite, osip_message_t *_200Ok); +void eXosip_dialog_free(eXosip_dialog_t *jd); +void eXosip_dialog_set_state(eXosip_dialog_t *jd, int state); +void eXosip_delete_early_dialog(eXosip_dialog_t *jd); + + +struct __eXosip_sockaddr { + u_char ss_len; + u_char ss_family; + u_char padding[128 - 2]; +}; +int eXosip_get_addrinfo (struct addrinfo **addrinfo, + char *hostname, int service); +int isrfc1918(char *ipaddr); +void eXosip_get_localip_from_via(osip_message_t *,char**localip); +int generating_initial_subscribe(osip_message_t **message, char *to, + char *from, char *route); +int generating_message(osip_message_t **message, char *to, char *from, + char *route, char *buff); +int generating_publish(osip_message_t **message, char *to, char *from, + char *route); +int generating_cancel(osip_message_t **dest, osip_message_t *request_cancelled); +int generating_options_within_dialog(osip_message_t **info, osip_dialog_t *dialog); +int generating_info_within_dialog(osip_message_t **info, osip_dialog_t *dialog); +int generating_bye(osip_message_t **bye, osip_dialog_t *dialog); +int generating_refer(osip_message_t **refer, osip_dialog_t *dialog, char *refer_to); +int generating_refer_outside_dialog(osip_message_t **refer, char *refer_to, char *from, char *to, char *proxy); +int generating_invite_on_hold(osip_message_t **invite, osip_dialog_t *dialog, + char *subject, char *sdp); +int generating_invite_off_hold(osip_message_t **invite, osip_dialog_t *dialog, + char *subject, char *sdp); +int generating_options(osip_message_t **options, char *from, char *to, char *proxy); +int generating_ack_for_2xx(osip_message_t **ack, osip_dialog_t *dialog); +int generating_info(osip_message_t **info, char *from, char *to, char *proxy); + +int _eXosip_reg_find(eXosip_reg_t **reg, osip_transaction_t *tr); +int eXosip_reg_init(eXosip_reg_t **jr, char *from, char *proxy, char *contact, char* route); +void eXosip_reg_free(eXosip_reg_t *jreg); +int generating_register(osip_message_t **reg, char *transport, char *from, char *proxy, int expires); +char *generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context); + +int eXosip_call_dialog_find(int jid, eXosip_call_t **jc, eXosip_dialog_t **jd); +int eXosip_notify_dialog_find(int nid, eXosip_notify_t **jn, eXosip_dialog_t **jd); +int eXosip_subscribe_dialog_find(int nid, eXosip_subscribe_t **js, eXosip_dialog_t **jd); +int eXosip_call_find(int cid, eXosip_call_t **jc); +int eXosip_dialog_set_200ok(eXosip_dialog_t *_jd, osip_message_t *_200Ok); + +int _eXosip2_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer); +int _eXosip2_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer); +int _eXosip2_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer); +int eXosip_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code); +int eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port); +int eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*, const char*); +int eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code); +int eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code); +int eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code); +int eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code); +void eXosip_notify_answer_subscribe_1xx(eXosip_notify_t *jc, + eXosip_dialog_t *jd, int code); +void eXosip_notify_answer_subscribe_2xx(eXosip_notify_t *jn, + eXosip_dialog_t *jd, int code); +void eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn, + eXosip_dialog_t *jd, int code); + +int eXosip_build_response_default(int jid, int status); +int _eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog, + int status, osip_message_t *request); +int complete_answer_that_establish_a_dialog(osip_message_t *response, osip_message_t *request); +int _eXosip_build_request_within_dialog(osip_message_t **dest, char *method_name, + osip_dialog_t *dialog, char *transport); +int eXosip_build_initial_options(osip_message_t **options, char *to, char *from, + char *route); + +void eXosip_kill_transaction(osip_list_t * transactions); +int eXosip_remove_transaction_from_call(osip_transaction_t *tr, eXosip_call_t *jc); +osip_transaction_t *eXosip_find_last_inc_notify(eXosip_subscribe_t *jn, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_inc_subscribe(eXosip_notify_t *jn, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd ); + +osip_transaction_t *eXosip_find_last_out_options(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_inc_options(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_options(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_out_info(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_inc_info(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_info(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_invite(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_inc_invite(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_invite(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ); +osip_transaction_t *eXosip_find_last_inc_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_inc_bye(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_bye(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_inc_refer(eXosip_call_t *jc, eXosip_dialog_t *jd); +osip_transaction_t *eXosip_find_last_out_refer(eXosip_call_t *jc, eXosip_dialog_t *jd); + + +int eXosip_call_init(eXosip_call_t **jc); +void eXosip_call_free(eXosip_call_t *jc); +void __eXosip_call_remove_dialog_reference_in_call(eXosip_call_t *jc, eXosip_dialog_t *jd); +void eXosip_call_set_subject(eXosip_call_t *jc, char *subject); +int eXosip_read_message(int max_message_nb, int sec_max, int usec_max); +void eXosip_release_terminated_calls ( void ); + + +int eXosip_subscribe_init(eXosip_subscribe_t **js, char *uri); +void eXosip_subscribe_free(eXosip_subscribe_t *js); +int _eXosip_subscribe_set_refresh_interval(eXosip_subscribe_t *js, osip_message_t *inc_subscribe); +int eXosip_subscribe_need_refresh(eXosip_subscribe_t *js, int now); +int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js, + eXosip_dialog_t *jd, const char *expires); + +int eXosip_notify_init(eXosip_notify_t **jn, osip_message_t *inc_subscribe); +void eXosip_notify_free(eXosip_notify_t *jn); +int _eXosip_notify_set_contact_info(eXosip_notify_t *jn, char *uri); +int _eXosip_notify_set_refresh_interval(eXosip_notify_t *jn, + osip_message_t *inc_subscribe); +void _eXosip_notify_add_expires_in_2XX_for_subscribe(eXosip_notify_t *jn, + osip_message_t *answer); +int _eXosip_notify_add_body(eXosip_notify_t *jn, osip_message_t *notify); +int eXosip_notify_add_allowed_subscriber(char *sip_url); +int _eXosip_notify_is_a_known_subscriber(osip_message_t *sip); +int eXosip_notify_send_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd, + int subsciption_status, + int online_status); +int _eXosip_transfer_send_notify(eXosip_call_t *jc, + eXosip_dialog_t *jd, + int subscription_status, + char *body); + + +int eXosip_is_public_address(const char *addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/exosip/eXosip_cfg.h b/linphone/exosip/eXosip_cfg.h new file mode 100644 index 000000000..b6a24f68f --- /dev/null +++ b/linphone/exosip/eXosip_cfg.h @@ -0,0 +1,150 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#ifndef __EXOSIP_CFG_H__ +#define __EXOSIP_CFG_H__ + +/** + * @defgroup eXosip_cfg eXosip Configuration Management + * @ingroup eXosip + * @{ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct jfriend_t jfriend_t; + +struct jfriend_t { + int f_id; + char *f_nick; + char *f_home; + char *f_work; + char *f_email; + char *f_e164; + + jfriend_t *next; + jfriend_t *parent; +}; + +typedef struct jidentity_t jidentity_t; + +struct jidentity_t { + int i_id; + char *i_identity; + char *i_registrar; + char *i_realm; + char *i_userid; + char *i_pwd; + + jidentity_t *next; + jidentity_t *parent; +}; + +typedef struct jsubscriber_t jsubscriber_t; + +struct jsubscriber_t { + int s_id; + char *s_nick; + char *s_uri; + char *s_allow; + + jsubscriber_t *next; + jsubscriber_t *parent; +}; + +jfriend_t *jfriend_get(void); +void jfriend_remove(jfriend_t *fr); + +jsubscriber_t *jsubscriber_get(void); +jidentity_t *jidentity_get(void); + +int jfriend_load(void); +void jfriend_unload(void); +void jfriend_add(char *nickname, char *home, + char *work, char *email, char *e164); +char *jfriend_get_home(int fid); + +int jsubscriber_load(void); +void jsubscriber_unload(void); +void subscribers_add(char *nickname, char *uri, int black_list); +char *jsubscriber_get_uri(int fid); + +int jidentity_load(void); +void jidentity_unload(void); +void identitys_add(char *identity, char *registrar, char *realm, + char *userid, char *password); +char *jidentity_get_identity(int fid); +char *jidentity_get_registrar(int fid); + +#define REMOVE_ELEMENT(first_element, element) \ + if (element->parent==NULL) \ + { first_element = element->next; \ + if (first_element!=NULL) \ + first_element->parent = NULL; } \ + else \ + { element->parent->next = element->next; \ + if (element->next!=NULL) \ + element->next->parent = element->parent; \ + element->next = NULL; \ + element->parent = NULL; } + +#define ADD_ELEMENT(first_element, element) \ + if (first_element==NULL) \ + { \ + first_element = element; \ + element->next = NULL; \ + element->parent = NULL; \ + } \ + else \ + { \ + element->next = first_element; \ + element->parent = NULL; \ + element->next->parent = element; \ + first_element = element; \ + } + +#define APPEND_ELEMENT(type_of_element_t, first_element, element) \ + if (first_element==NULL) \ + { first_element = element; \ + element->next = NULL; /* useless */ \ + element->parent = NULL; /* useless */ } \ + else \ + { type_of_element_t *f; \ + for (f=first_element; f->next!=NULL; f=f->next) \ + { } \ + f->next = element; \ + element->parent = f; \ + element->next = NULL; \ + } + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/linphone/exosip/eXutils.c b/linphone/exosip/eXutils.c new file mode 100644 index 000000000..9a7a52aab --- /dev/null +++ b/linphone/exosip/eXutils.c @@ -0,0 +1,278 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include +#include "eXosip2.h" + +extern eXosip_t eXosip; + +#ifdef WIN32 +/* You need the Platform SDK to compile this. */ +#include + +#else /* sun, *BSD, linux, and other? */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#endif + +int +eXosip_guess_ip_for_via (int family, char *address, int size){ + char *res=NULL; + if (family==AF_INET6) + eXosip_get_localip_for("2001:638:500:101:2e0:81ff:fe24:37c6",&res); + else + eXosip_get_localip_for("15.128.128.93",&res); + strncpy(address,res,size); + osip_free(res); + return 0; +} + + + +#ifdef SM + +void eXosip_get_localip_from_via(osip_message_t *mesg,char **locip){ + osip_via_t *via=NULL; + char *host; + via=(osip_via_t*)osip_list_get(mesg->vias,0); + if (via==NULL) { + host="15.128.128.93"; + eXosip_trace(OSIP_ERROR,("Could not get via:%s")); + }else host=via->host; + eXosip_get_localip_for(host,locip); + +} +#endif + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 1024 +#endif + +void eXosip_get_localip_for(char *address_to_reach,char **loc){ + int err,tmp; + struct addrinfo hints; + struct addrinfo *res=NULL,*res0=NULL; + struct sockaddr_storage addr; + int sock; +#ifdef __APPLE_CC__ + int s; +#else + socklen_t s; +#endif + + if (eXosip.forced_localip){ + *loc=osip_strdup(eXosip.localip); + return; + } + + *loc=osip_malloc(MAXHOSTNAMELEN); + if (eXosip.ip_family==AF_INET) + strcpy(*loc,"127.0.0.1"); /* always fallback to local loopback */ + else strcpy(*loc,"::1"); + + memset(&hints,0,sizeof(hints)); + hints.ai_family=(eXosip.ip_family==AF_INET) ? PF_INET:PF_INET6; + hints.ai_socktype=SOCK_DGRAM; + /*hints.ai_flags=AI_NUMERICHOST|AI_CANONNAME;*/ + err=getaddrinfo(address_to_reach,"5060",&hints,&res0); + if (err!=0){ + eXosip_trace(OSIP_ERROR,("Error in getaddrinfo for %s: %s\n",address_to_reach,gai_strerror(err))); + return ; + } + if (res0==NULL){ + eXosip_trace(OSIP_ERROR,("getaddrinfo reported nothing !")); + abort(); + return ; + } + for (res=res0;res!=NULL;res=res->ai_next){ + sock=socket(res->ai_family,SOCK_DGRAM,0); + tmp=1; + err=setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof(int)); + if (err<0){ + eXosip_trace(OSIP_ERROR,("Error in setsockopt: %s\n",strerror(errno))); + abort(); + return ; + } + err=connect(sock,res->ai_addr,res->ai_addrlen); + if (err<0) { + eXosip_trace(OSIP_ERROR,("Error in connect: %s\n",strerror(errno))); + close(sock); + sock=-1; + continue; + }else break; + } + freeaddrinfo(res0); + if (sock==-1){ + eXosip_trace(OSIP_WARNING,("Could not find interface to reach %s\n",address_to_reach)); + return; + } + res0=NULL; + res=NULL; + s=sizeof(addr); + err=getsockname(sock,(struct sockaddr*)&addr,&s); + if (err!=0) { + eXosip_trace(OSIP_ERROR,("Error in getsockname: %s\n",strerror(errno))); + close(sock); + return ; + } + + err=getnameinfo((struct sockaddr *)&addr,s,*loc,MAXHOSTNAMELEN,NULL,0,NI_NUMERICHOST); + if (err!=0){ + eXosip_trace(OSIP_ERROR,("getnameinfo error:%s ; while finding local address for %s",strerror(errno), address_to_reach)); + abort(); + return ; + } + close(sock); + eXosip_trace(OSIP_INFO1,("Outgoing interface to reach %s is %s.\n",address_to_reach,*loc)); + return ; +} + +char *strdup_printf(const char *fmt, ...) +{ + /* Guess we need no more than 100 bytes. */ + int n, size = 100; + char *p; + va_list ap; + if ((p = osip_malloc (size)) == NULL) + return NULL; + while (1) + { + /* Try to print in the allocated space. */ + va_start (ap, fmt); +#ifdef WIN32 + n = _vsnprintf (p, size, fmt, ap); +#else + n = vsnprintf (p, size, fmt, ap); +#endif + va_end (ap); + /* If that worked, return the string. */ + if (n > -1 && n < size) + return p; + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if ((p = realloc (p, size)) == NULL) + return NULL; + } +} + +int +eXosip_get_addrinfo (struct addrinfo **addrinfo, char *hostname, int service) +{ +#ifndef WIN32 + struct in_addr addr; + struct in6_addr addrv6; +#else + unsigned long int one_inet_addr; +#endif + struct addrinfo hints; + int error; + char portbuf[10]; + if (service!=0) + snprintf(portbuf, sizeof(portbuf), "%i", service); + + memset (&hints, 0, sizeof (hints)); +#ifndef WIN32 + if (inet_pton(AF_INET, hostname, &addr)>0) + { + /* ipv4 address detected */ + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = PF_INET; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "IPv4 address detected: %s\n", hostname)); + } + else if (inet_pton(AF_INET6, hostname, &addrv6)>0) + { + /* ipv6 address detected */ + /* Do the resolution anyway */ + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_INET6; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "IPv6 address detected: %s\n", hostname)); + } + else + { + /* hostname must be resolved */ + hints.ai_flags = 0; + hints.ai_family = (eXosip.ip_family==AF_INET) ? PF_INET:PF_INET6; + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "Not an IPv4 or IPv6 address: %s\n", hostname)); + } +#else + if ((int)(one_inet_addr = inet_addr(hostname)) == -1) + hints.ai_flags = AI_CANONNAME; + else + hints.ai_flags = AI_NUMERICHOST; + +#ifdef IPV6_SUPPORT + hints.ai_family = PF_UNSPEC; /* ipv6 support */ +#else + hints.ai_family = PF_INET; /* ipv4 only support */ +#endif + +#endif + + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + if (service==0) + { + error = getaddrinfo (hostname, "sip", &hints, addrinfo); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "SRV resolution with udp-sip-%s\n", hostname)); + } + else + { + error = getaddrinfo (hostname, portbuf, &hints, addrinfo); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "DNS resolution with %s:%i\n", hostname, service)); + } + if (error || *addrinfo == NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "getaddrinfo failure. %s:%s (%s)\n", hostname, portbuf, gai_strerror(error))); + return -1; + } + + return 0; +} diff --git a/linphone/exosip/exosip.dev b/linphone/exosip/exosip.dev new file mode 100755 index 000000000..c90fb628d --- /dev/null +++ b/linphone/exosip/exosip.dev @@ -0,0 +1,289 @@ +[Project] +FileName=exosip.dev +Name=exosip +UnitCount=24 +Type=2 +Ver=1 +ObjFiles= +Includes=. +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-D_WIN32_WINNT=0x501_@@_-DSM_@@_-g_@@_ +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=1 +OverrideOutputName=libexosip.a +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 + +[Unit1] +FileName=udp.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=eXosip2.h +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=eXosip.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=eXosip.h +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=eXosip_cfg.h +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=eXutils.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=jauth.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=jcall.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=jcallback.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=jdialog.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=jevents.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=jfreinds.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=jidentity.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=jnotify.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=jpipe.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=jpipe.h +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=jpublish.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=jreg.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=jrequest.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=jresponse.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=jsubscribe.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=jsubscribers.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=misc.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=sdp_offans.c +CompileCpp=0 +Folder=exosip +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + diff --git a/linphone/exosip/jauth.c b/linphone/exosip/jauth.c new file mode 100644 index 000000000..6a81d8f4c --- /dev/null +++ b/linphone/exosip/jauth.c @@ -0,0 +1,453 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include +#include + +#include +#include + +/* #include */ +#include + +/* TAKEN from rcf2617.txt */ + +#define HASHLEN 16 +typedef char HASH[HASHLEN]; +#define HASHHEXLEN 32 +typedef char HASHHEX[HASHHEXLEN+1]; +#define IN +#define OUT + +extern eXosip_t eXosip; + +/* Private functions */ +static void CvtHex(IN HASH Bin, OUT HASHHEX Hex); +static void DigestCalcHA1(IN const char * pszAlg, IN const char * pszUserName, + IN const char * pszRealm, IN const char * pszPassword, + IN const char * pszNonce, IN const char * pszCNonce, + OUT HASHHEX SessionKey); +static void DigestCalcResponse(IN HASHHEX HA1, + IN const char * pszNonce, + IN const char * pszNonceCount, + IN const char * pszCNonce, + IN const char * pszQop, + IN const char * pszMethod, + IN const char * pszDigestUri, + IN HASHHEX HEntity, OUT HASHHEX Response); + +static void CvtHex(IN HASH Bin, + OUT HASHHEX Hex) +{ + unsigned short i; + unsigned char j; + + for (i = 0; i < HASHLEN; i++) { + j = (Bin[i] >> 4) & 0xf; + if (j <= 9) + Hex[i*2] = (j + '0'); + else + Hex[i*2] = (j + 'a' - 10); + j = Bin[i] & 0xf; + if (j <= 9) + Hex[i*2+1] = (j + '0'); + else + Hex[i*2+1] = (j + 'a' - 10); + }; + Hex[HASHHEXLEN] = '\0'; +} + +/* calculate H(A1) as per spec */ +static void DigestCalcHA1(IN const char * pszAlg, + IN const char * pszUserName, + IN const char * pszRealm, + IN const char * pszPassword, + IN const char * pszNonce, + IN const char * pszCNonce, + OUT HASHHEX SessionKey) +{ + MD5_CTX Md5Ctx; + HASH HA1; + + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, (unsigned char *)pszUserName, strlen(pszUserName)); + MD5Update(&Md5Ctx, (unsigned char *)":", 1); + MD5Update(&Md5Ctx, (unsigned char *)pszRealm, strlen(pszRealm)); + MD5Update(&Md5Ctx, (unsigned char *)":", 1); + MD5Update(&Md5Ctx, (unsigned char *)pszPassword, strlen(pszPassword)); + MD5Final((unsigned char *)HA1, &Md5Ctx); + if ((pszAlg!=NULL)&&osip_strcasecmp(pszAlg, "md5-sess") == 0) + { + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, (unsigned char *)HA1, HASHLEN); + MD5Update(&Md5Ctx, (unsigned char *)":", 1); + MD5Update(&Md5Ctx, (unsigned char *)pszNonce, strlen(pszNonce)); + MD5Update(&Md5Ctx, (unsigned char *)":", 1); + MD5Update(&Md5Ctx, (unsigned char *)pszCNonce, strlen(pszCNonce)); + MD5Final((unsigned char *)HA1, &Md5Ctx); + } + CvtHex(HA1, SessionKey); +} + +/* calculate request-digest/response-digest as per HTTP Digest spec */ +static void DigestCalcResponse(IN HASHHEX HA1, /* H(A1) */ + IN const char * pszNonce, /* nonce from server */ + IN const char * pszNonceCount,/* 8 hex digits */ + IN const char * pszCNonce, /* client nonce */ + IN const char * pszQop, /* qop-value: "", "auth", "auth-int" */ + IN const char * pszMethod, /* method from the request */ + IN const char * pszDigestUri, /* requested URL */ + IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ + OUT HASHHEX Response /* request-digest or response-digest */) +{ + MD5_CTX Md5Ctx; + HASH HA2; + HASH RespHash; + HASHHEX HA2Hex; + + int auth_int_flag = 0; + + /* calculate H(A2) */ + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, (unsigned char *)pszMethod, strlen(pszMethod)); + MD5Update(&Md5Ctx, (unsigned char *)":", 1); + MD5Update(&Md5Ctx, (unsigned char *)pszDigestUri, strlen(pszDigestUri)); + + if (pszQop!=NULL) + { + char *index = strchr(pszQop,'i'); + while (index!=NULL&&index-pszQop>=5&&strlen(index)>=3) + { + if (osip_strncasecmp(index-5, "auth-int",8) == 0) + { + auth_int_flag = 1; + goto auth_withqop; + } + index = strchr(index+1,'i'); + } + + index = strchr(pszQop,'a'); + while (index!=NULL&&strlen(index)>=4) + { + if (osip_strncasecmp(index, "auth",4) == 0) + { + /* and in the case of a unknown token + like auth1. It is not auth, but this + implementation will think it is!?? + This is may not happen but it's a bug! + */ + goto auth_withqop; + } + index = strchr(index+1,'a'); + } + goto auth_withoutqop; + } + + auth_withoutqop: + MD5Final((unsigned char*)HA2, &Md5Ctx); + CvtHex(HA2, HA2Hex); + + /* calculate response */ + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHHEXLEN); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce)); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + + goto end; + + auth_withqop: + + if (auth_int_flag) + { + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)HEntity, HASHHEXLEN); + } + + MD5Final((unsigned char*)HA2, &Md5Ctx); + CvtHex(HA2, HA2Hex); + + /* calculate response */ + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHHEXLEN); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce)); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)pszNonceCount, strlen(pszNonceCount)); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)pszCNonce, strlen(pszCNonce)); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + MD5Update(&Md5Ctx, (unsigned char*)pszQop, strlen(pszQop)); + MD5Update(&Md5Ctx, (unsigned char*)":", 1); + + end: + MD5Update(&Md5Ctx, (unsigned char*)HA2Hex, HASHHEXLEN); + MD5Final((unsigned char*)RespHash, &Md5Ctx); + CvtHex(RespHash, Response); +} + + +int +__eXosip_create_authorization_header(osip_message_t *previous_answer, + const char *rquri, const char *username, + const char *passwd, + osip_authorization_t **auth) +{ + static int nc = 1; + + osip_authorization_t *aut; + osip_www_authenticate_t *wa=NULL; + + osip_message_get_www_authenticate(previous_answer,0,&wa); + + /* make some test */ + if (passwd==NULL) + return -1; + if (wa==NULL||wa->auth_type==NULL + ||(wa->realm==NULL)||(wa->nonce==NULL)) { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "www_authenticate header is not acceptable.\n")); + return -1; + } + if (0!=osip_strcasecmp("Digest",wa->auth_type)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Authentication method not supported. (Digest only).\n")); + return -1; + } + /* "MD5" is invalid, but some servers use it. */ + if (wa->algorithm!=NULL&&0!=osip_strcasecmp("MD5",wa->algorithm)&&0!=osip_strcasecmp("\"MD5\"",wa->algorithm)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Authentication method not supported. (Digest only).\n")); + return -1; + } + if (0!=osip_authorization_init(&aut)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "allocation with authorization_init failed.\n")); + return -1; + } + + /* just copy some feilds from response to new request */ + osip_authorization_set_auth_type(aut,osip_strdup("Digest")); + osip_authorization_set_realm(aut,osip_strdup(osip_www_authenticate_get_realm(wa))); + osip_authorization_set_nonce(aut,osip_strdup(osip_www_authenticate_get_nonce(wa))); + if (osip_www_authenticate_get_opaque(wa)!=NULL) + osip_authorization_set_opaque(aut,osip_strdup(osip_www_authenticate_get_opaque(wa))); + /* copy the username field in new request */ + aut->username = osip_malloc(strlen(username)+3); + sprintf(aut->username,"\"%s\"",username); + + { + char *tmp = osip_malloc(strlen(rquri)+3); + sprintf(tmp,"\"%s\"",rquri); + osip_authorization_set_uri(aut,tmp); + } + + osip_authorization_set_algorithm(aut,osip_strdup("MD5")); + + { + char * pszNonce = osip_strdup_without_quote(osip_www_authenticate_get_nonce(wa)); + char * pszCNonce = osip_strdup_without_quote("abcdefghi"); + char * pszUser = osip_strdup_without_quote(username); + char * pszRealm = osip_strdup_without_quote(osip_authorization_get_realm(aut)); + const char * pszPass=NULL; + char * pszAlg = osip_strdup("MD5"); + char *szNonceCount = NULL; + char * pszMethod = osip_strdup_without_quote(previous_answer->cseq->method); + char * pszQop = NULL; + char * pszURI = osip_strdup_without_quote(rquri); + + szNonceCount = osip_strdup("00000000"); + sprintf(szNonceCount, "%08d", nc++); + + HASHHEX HA1; + HASHHEX HA2 = ""; + HASHHEX Response; + + pszPass=passwd; + + if (osip_www_authenticate_get_qop_options(wa)!=NULL) + { + pszQop = osip_strdup_without_quote(osip_www_authenticate_get_qop_options(wa)); + + osip_authorization_set_message_qop(aut,osip_strdup(pszQop)); + osip_authorization_set_nonce_count(aut,osip_strdup(szNonceCount)); + osip_authorization_set_cnonce(aut,osip_strdup("\"abcdefghi\"")); + osip_authorization_set_algorithm(aut,osip_strdup(pszAlg)); + } + + DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce, + pszCNonce, HA1); + DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop, + pszMethod, pszURI, HA2, Response); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO4, NULL, + "Response in authorization |%s|\n", Response)); + { + char *resp = osip_malloc(35); + sprintf(resp,"\"%s\"",Response); + osip_authorization_set_response(aut,resp); + } + osip_free(pszAlg); /* xkd, 2004-5-13*/ + osip_free(pszNonce); + osip_free(pszCNonce); + osip_free(pszRealm); + osip_free(pszQop); + osip_free(szNonceCount); + osip_free(pszUser); + osip_free(pszMethod); + osip_free(pszURI); + } + + *auth = aut; + return 0; +} + +int +__eXosip_create_proxy_authorization_header(osip_message_t *previous_answer, + const char *rquri, + const char *username, + const char *passwd, + osip_proxy_authorization_t **auth) +{ + osip_proxy_authorization_t *aut; + osip_proxy_authenticate_t *wa; + + osip_message_get_proxy_authenticate(previous_answer,0,&wa); + + /* make some test */ + if (passwd==NULL) + return -1; + if (wa==NULL||wa->auth_type==NULL + ||(wa->realm==NULL)||(wa->nonce==NULL)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "www_authenticate header is not acceptable.\n")); + return -1; + } + if (0!=osip_strcasecmp("Digest",wa->auth_type)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Authentication method not supported. (Digest only).\n")); + return -1; + } + /* "MD5" is invalid, but some servers use it. */ + if (wa->algorithm!=NULL&&0!=osip_strcasecmp("MD5",wa->algorithm)&&0!=osip_strcasecmp("\"MD5\"",wa->algorithm)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Authentication method not supported. (MD5 Digest only).\n")); + return -1; + } + if (0!=osip_proxy_authorization_init(&aut)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "allocation with authorization_init failed.\n")); + return -1; + } + + /* just copy some feilds from response to new request */ + osip_proxy_authorization_set_auth_type(aut,osip_strdup("Digest")); + osip_proxy_authorization_set_realm(aut,osip_strdup(osip_proxy_authenticate_get_realm(wa))); + osip_proxy_authorization_set_nonce(aut,osip_strdup(osip_proxy_authenticate_get_nonce(wa))); + if (osip_proxy_authenticate_get_opaque(wa)!=NULL) + osip_proxy_authorization_set_opaque(aut,osip_strdup(osip_proxy_authenticate_get_opaque(wa))); + /* copy the username field in new request */ + aut->username = osip_malloc(strlen(username)+3); + sprintf(aut->username,"\"%s\"",username); + + { + char *tmp = osip_malloc(strlen(rquri)+3); + sprintf(tmp,"\"%s\"",rquri); + osip_proxy_authorization_set_uri(aut,tmp); + } + osip_proxy_authorization_set_algorithm(aut,osip_strdup("MD5")); + + { + char * pszNonce = NULL; + char * pszCNonce= NULL ; + const char * pszUser = username; + char * pszRealm = osip_strdup_without_quote(osip_proxy_authorization_get_realm(aut)); + const char * pszPass = NULL; + char * pszAlg = osip_strdup("MD5"); + char *szNonceCount = NULL; + char * pszMethod = previous_answer->cseq->method; + char * pszQop = NULL; + const char * pszURI = rquri; + + HASHHEX HA1; + HASHHEX HA2 = ""; + HASHHEX Response; + + pszPass=passwd; + + if (osip_www_authenticate_get_nonce(wa)==NULL) + return -1; + pszNonce = osip_strdup_without_quote(osip_www_authenticate_get_nonce(wa)); + + /* should upgrade szNonceCount */ + /* should add szNonceCount in aut*/ + /* should upgrade pszCNonce */ + /* should add pszCNonce in aut */ + + if (osip_proxy_authenticate_get_qop_options(wa)!=NULL) + { + szNonceCount = osip_strdup("00000001"); + /* MUST be incremented on each */ + pszQop = osip_strdup(osip_proxy_authenticate_get_qop_options(wa)); + pszCNonce = osip_strdup("234abcc436e2667097e7fe6eia53e8dd"); + } + DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce, + pszCNonce, HA1); + DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop, + pszMethod, pszURI, HA2, Response); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO4, NULL, + "Response in proxy_authorization |%s|\n", Response)); + { + char *resp = osip_malloc(35); + sprintf(resp,"\"%s\"",Response); + osip_proxy_authorization_set_response(aut,resp); + } + osip_free(pszAlg); /* xkd, 2004-5-13*/ + osip_free(pszNonce); + osip_free(pszCNonce); + osip_free(pszRealm); + osip_free(pszQop); + osip_free(szNonceCount); + } + + *auth = aut; + return 0; +} diff --git a/linphone/exosip/jcall.c b/linphone/exosip/jcall.c new file mode 100644 index 000000000..65eae08a9 --- /dev/null +++ b/linphone/exosip/jcall.c @@ -0,0 +1,122 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +int eXosip_call_find(int cid, eXosip_call_t **jc) +{ + for (*jc=eXosip.j_calls; *jc!=NULL; *jc=(*jc)->next) + { + if ((*jc)->c_id==cid) + { + return 0; + } + } + *jc = NULL; + return -1; +} + +int +eXosip_call_init(eXosip_call_t **jc) +{ + *jc = (eXosip_call_t *)osip_malloc(sizeof(eXosip_call_t)); + if (*jc == NULL) return -1; + memset(*jc, 0, sizeof(eXosip_call_t)); + + (*jc)->c_id = -1; /* make sure the eXosip_update will assign a valid id to the call */ + osip_negotiation_ctx_init(&(*jc)->c_ctx); + return 0; +} + +void +__eXosip_call_remove_dialog_reference_in_call(eXosip_call_t *jc, eXosip_dialog_t *jd) +{ + eXosip_dialog_t *_jd; + jinfo_t *ji; + if (jc==NULL) return; + if (jd==NULL) return; + + + for (_jd = jc->c_dialogs; _jd!=NULL; _jd=jc->c_dialogs) + { + if (jd==_jd) + break; + } + if (_jd==NULL) + { + /* dialog not found??? */ + } + + ji = osip_transaction_get_your_instance(jc->c_inc_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; + ji = osip_transaction_get_your_instance(jc->c_out_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; +} + +void +eXosip_call_free(eXosip_call_t *jc) +{ + /* ... */ + + eXosip_dialog_t *jd; + + for (jd = jc->c_dialogs; jd!=NULL; jd=jc->c_dialogs) + { + REMOVE_ELEMENT(jc->c_dialogs, jd); + eXosip_dialog_free(jd); + } + + __eXosip_delete_jinfo(jc->c_inc_tr); + __eXosip_delete_jinfo(jc->c_out_tr); + if (jc->c_inc_tr!=NULL) + osip_list_add(eXosip.j_transactions, jc->c_inc_tr, 0); + if (jc->c_out_tr!=NULL) + osip_list_add(eXosip.j_transactions, jc->c_out_tr, 0); + + __eXosip_delete_jinfo(jc->c_inc_options_tr); + __eXosip_delete_jinfo(jc->c_out_options_tr); + if (jc->c_inc_options_tr!=NULL) + osip_list_add(eXosip.j_transactions, jc->c_inc_options_tr, 0); + if (jc->c_out_options_tr!=NULL) + osip_list_add(eXosip.j_transactions, jc->c_out_options_tr, 0); + + + osip_negotiation_ctx_free(jc->c_ctx); + osip_free(jc); + +} + +void +eXosip_call_set_subject(eXosip_call_t *jc, char *subject) +{ + if (jc==NULL||subject==NULL||subject[0]=='\0') return; + snprintf(jc->c_subject, 99, "%s", subject); +} + diff --git a/linphone/exosip/jcallback.c b/linphone/exosip/jcallback.c new file mode 100644 index 000000000..b8bb2bc58 --- /dev/null +++ b/linphone/exosip/jcallback.c @@ -0,0 +1,1972 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include + +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#endif + +#include +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +#ifdef TEST_AUDIO +static pid_t pid = 0; +#endif + + +/* Private functions */ +static void rcvregister_failure(int type, osip_transaction_t *tr,osip_message_t *sip); +int cb_udp_snd_message(osip_transaction_t *tr, osip_message_t *sip, + char *host, int port, int out_socket); +static void cb_ict_kill_transaction(int type, osip_transaction_t *tr); +static void cb_ist_kill_transaction(int type, osip_transaction_t *tr); +static void cb_nict_kill_transaction(int type, osip_transaction_t *tr); +static void cb_nist_kill_transaction(int type, osip_transaction_t *tr); +static void cb_rcvinvite (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvack (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvack2 (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvregister(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvbye (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvcancel (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvinfo (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvoptions (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvnotify (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvsubscribe (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvunkrequest(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndinvite (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndack (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndregister(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndbye (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndcancel (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndinfo (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndoptions (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndnotify (int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndsubscribe(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_sndunkrequest(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv1xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv2xx_4invite(osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv2xx_4subscribe(osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv2xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv3xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv4xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv5xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcv6xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd1xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd2xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd3xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd4xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd5xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_snd6xx(int type, osip_transaction_t *tr,osip_message_t *sip); +static void cb_rcvresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip); +static void cb_sndreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip); +static void cb_sndresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip); +static void cb_rcvreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip); +static void cb_transport_error(int type, osip_transaction_t *tr, int error); +static void report_call_event_with_status(int evt, eXosip_call_t *jc, eXosip_dialog_t *jd, osip_message_t *sip); +static void report_event_with_status(eXosip_event_t *je, osip_message_t *sip); + +int cb_udp_snd_message(osip_transaction_t *tr, osip_message_t *sip, char *host, + int port, int out_socket) +{ + int len = 0; + size_t length = 0; + static int num = 0; + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + char *message; + int i; + + if (eXosip.j_socket==0) return -1; + + if (host==NULL) + { + host = sip->req_uri->host; + if (sip->req_uri->port!=NULL) + port = osip_atoi(sip->req_uri->port); + else + port = 5060; + } + + i = eXosip_get_addrinfo(&addrinfo, host, port); + if (i!=0) + { + return -1; + } + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + len = addrinfo->ai_addrlen; + + freeaddrinfo (addrinfo); + + i = osip_message_to_str(sip, &message, &length); + + if (i!=0 || length<=0) { + return -1; + } + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Message sent: \n%s (len=%i sizeof(addr)=%i %i)\n", + message, len, sizeof(addr), sizeof(struct sockaddr_in6))); + if (0 > sendto (eXosip.j_socket, (const void*) message, length, 0, + (struct sockaddr *) &addr, len /* sizeof(addr) */ )) + { +#ifdef WIN32 + if (WSAECONNREFUSED==WSAGetLastError()) +#else + if (ECONNREFUSED==errno) +#endif + { + /* This can be considered as an error, but for the moment, + I prefer that the application continue to try sending + message again and again... so we are not in a error case. + Nevertheless, this error should be announced! + ALSO, UAS may not have any other options than retry always + on the same port. + */ + osip_free(message); + return 1; + } + else + { + /* SIP_NETWORK_ERROR; */ + osip_free(message); + return -1; + } + } + if (strncmp(message, "INVITE", 7)==0) + { + num++; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO4,NULL,"number of message sent: %i\n", num)); + } + + osip_free(message); + return 0; + +} + +static void cb_ict_kill_transaction(int type, osip_transaction_t *tr) +{ + int i; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_ict_kill_transaction (id=%i)\r\n", tr->transactionid)); + + i = osip_remove_transaction(eXosip.j_osip, tr); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"cb_ict_kill_transaction Error: Could not remove transaction from the oSIP stack? (id=%i)\r\n", tr->transactionid)); + } +} + +static void cb_ist_kill_transaction(int type, osip_transaction_t *tr) +{ + int i; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_ist_kill_transaction (id=%i)\r\n", tr->transactionid)); + i = osip_remove_transaction(eXosip.j_osip, tr); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"cb_ist_kill_transaction Error: Could not remove transaction from the oSIP stack? (id=%i)\r\n", tr->transactionid)); + } +} + +static void cb_nict_kill_transaction(int type, osip_transaction_t *tr) +{ + int i; + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_nict_kill_transaction (id=%i)\r\n", tr->transactionid)); + i = osip_remove_transaction(eXosip.j_osip, tr); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"cb_nict_kill_transaction Error: Could not remove transaction from the oSIP stack? (id=%i)\r\n", tr->transactionid)); + } + + if (MSG_IS_REGISTER(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION + && tr->last_response==NULL) + { + eXosip_event_t *je; + eXosip_reg_t *jreg=NULL; + /* find matching j_reg */ + _eXosip_reg_find(&jreg, tr); + if (jreg!=NULL) + { + je = eXosip_event_init_for_reg(EXOSIP_REGISTRATION_FAILURE, jreg); + report_event_with_status(je, NULL); + } + return; + } + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + jn = jinfo->jn; + js = jinfo->js; + + if (jn==NULL && js==NULL) + return; + + /* no answer to a NOTIFY request! */ + if (MSG_IS_NOTIFY(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION + && tr->last_response==NULL) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + return; + } + + if (MSG_IS_NOTIFY(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION + && tr->last_response!=NULL + && tr->last_response->status_code > 299) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + return; + } + + if (MSG_IS_NOTIFY(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION + && tr->last_response!=NULL + && tr->last_response->status_code > 199 + && tr->last_response->status_code < 300) + { + if (jn->n_ss_status==EXOSIP_SUBCRSTATE_TERMINATED) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + return; + } + } + + /* no answer to a SUBSCRIBE request! */ + if (MSG_IS_SUBSCRIBE(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION + && tr->last_response==NULL) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + return; + } + + /* detect SUBSCRIBE request that close the dialogs! */ + /* expires=0 with MSN */ + if (MSG_IS_SUBSCRIBE(tr->orig_request) + && type==OSIP_NICT_KILL_TRANSACTION) + { + osip_header_t *expires; + osip_message_get_expires(tr->orig_request, 0, &expires); + if (expires==NULL || expires->hvalue==NULL) + { + } + else if (0==strcmp(expires->hvalue, "0")) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + return; + } + } +} + +static void cb_nist_kill_transaction(int type, osip_transaction_t *tr) +{ + int i; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_nist_kill_transaction (id=%i)\r\n", tr->transactionid)); + i = osip_remove_transaction(eXosip.j_osip, tr); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"cb_nist_kill_transaction Error: Could not remove transaction from the oSIP stack? (id=%i)\r\n", tr->transactionid)); + } + +} + +static void cb_rcvinvite (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvinvite (id=%i)\n", tr->transactionid)); +} + +static void cb_rcvack (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvack (id=%i)\n", tr->transactionid)); +} + +static void cb_rcvack2 (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvack2 (id=%i)\r\n", tr->transactionid)); +} + +static void cb_rcvregister(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvregister (id=%i)\r\n", tr->transactionid)); +} + +static void cb_rcvbye (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvbye (id=%i)\r\n", tr->transactionid)); +#ifdef TEST_AUDIO + if (pid!=0) + { + int i = kill(pid, SIGINT); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"audio command kill return %i %i\n", i, pid)); + pid = 0; + } +#endif +} + +static void cb_rcvcancel (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvcancel (id=%i)\r\n", tr->transactionid)); +} + +static void cb_rcvinfo (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_event_t *je; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvinfo (id=%i)\r\n", tr->transactionid)); + + if (jinfo==NULL) + return; + if (jinfo->jc==NULL) + return; + + je = eXosip_event_init_for_call(EXOSIP_INFO_NEW, jinfo->jc, jinfo->jd); + if (je!=NULL) + { + char *tmp; + osip_uri_to_str(sip->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + + if (sip!=NULL) + { + int pos; + /* get content-type info */ + osip_content_type_clone(osip_message_get_content_type(sip), &(je->i_ctt)); + /* get list of bodies */ + je->i_bodies = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(je->i_bodies); + for (pos=0;!osip_list_eol(sip->bodies, pos);pos++) + { + osip_body_t *body; + osip_body_t *_body; + body = (osip_body_t *)osip_list_get(sip->bodies, pos); + osip_body_clone(body, &_body); + osip_list_add(je->i_bodies, _body, -1); + } + } + } + + report_event_with_status(je, NULL); +} + +static void cb_rcvoptions (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_event_t *je; + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvoptions (id=%i)\r\n", tr->transactionid)); + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + jn = jinfo->jn; + js = jinfo->js; + if (jinfo->jc==NULL) + return; + + je = eXosip_event_init_for_call(EXOSIP_OPTIONS_NEW, jc, jd); + if (je!=NULL) + { + char *tmp; + osip_uri_to_str(sip->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + report_event_with_status(je, NULL); + +} + +static void cb_rcvnotify (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvnotify (id=%i)\r\n", tr->transactionid)); +} + +static void cb_rcvsubscribe (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_event_t *je; + eXosip_dialog_t *jd; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvsubscribe (id=%i)\r\n", tr->transactionid)); + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jn = jinfo->jn; + if (jinfo->jn==NULL) + return; + + je = eXosip_event_init_for_notify(EXOSIP_IN_SUBSCRIPTION_NEW, jn, jd); + if (je!=NULL) + { + char *tmp; + osip_uri_to_str(sip->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + report_event_with_status(je, NULL); +} + +static void cb_rcvunkrequest(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvunkrequest (id=%i)\r\n", tr->transactionid)); + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jinfo->jc==NULL) + return; + + + if (MSG_IS_REFER(sip)) + { + eXosip_event_t *je; + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvrefer (id=%i)\r\n", tr->transactionid)); + + je = eXosip_event_init_for_call(EXOSIP_CALL_REFERED, jc, jd); + if (je!=NULL) + { + report_event_with_status(je, NULL); + } + } + +} + +static void cb_sndinvite (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndinvite (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndack (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndack (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndregister(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndregister (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndbye (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndbye (id=%i)\r\n", tr->transactionid)); +#ifdef TEST_AUDIO + if (pid!=0) + { + int i = kill(pid, SIGINT); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"audio command kill return %i %i\n", i, pid)); + pid = 0; + } +#endif + +} + +static void cb_sndcancel (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndcancel (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndinfo (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndinfo (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndoptions (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndoptions (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndnotify (int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndnotify (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndsubscribe(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndsubscibe (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndunkrequest(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndunkrequest (id=%i)\r\n", tr->transactionid)); +} + +void __eXosip_delete_jinfo(osip_transaction_t *transaction) +{ + jinfo_t *ji; + if (transaction==NULL) + return; + ji = osip_transaction_get_your_instance(transaction); + osip_free(ji); + osip_transaction_set_your_instance(transaction, NULL); +} + +jinfo_t *__eXosip_new_jinfo(eXosip_call_t *jc, eXosip_dialog_t *jd, + eXosip_subscribe_t *js, eXosip_notify_t *jn) +{ + jinfo_t *ji = (jinfo_t *) osip_malloc(sizeof(jinfo_t)); + if (ji==NULL) return NULL; + ji->jd = jd; + ji->jc = jc; + ji->js = js; + ji->jn = jn; + return ji; +} + +static void cb_rcv1xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv1xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + jn = jinfo->jn; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv1xx (id=%i) Error: no call or transaction info for OPTIONS transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + report_call_event_with_status(EXOSIP_OPTIONS_PROCEEDING, jc, jd, sip); + return; + } + + if ((MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + && !MSG_TEST_CODE(sip, 100)) + { + int i; + /* for SUBSCRIBE, test if the dialog has been already created + with a previous NOTIFY */ + if (jd==NULL && js!=NULL && js->s_dialogs!=NULL && MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + /* find if existing dialog match the to tag */ + osip_generic_param_t *tag; + int i; + i = osip_to_get_tag (sip->to, &tag); + if (i==0 && tag!=NULL && tag->gvalue!=NULL ) + { + for (jd = js->s_dialogs; jd!= NULL ; jd=jd->next) + { + if (0==strcmp(jd->d_dialog->remote_tag, tag->gvalue)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "eXosip: found established early dialog for this subscribe\n")); + jinfo->jd = jd; + break; + } + } + } + } + + if (jd == NULL) /* This transaction initiate a dialog in the case of + INVITE (else it would be attached to a "jd" element. */ + { + /* allocate a jd */ + + i = eXosip_dialog_init_as_uac(&jd, sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot establish a dialog\n")); + return; + } + if (jc!=NULL) + { + ADD_ELEMENT(jc->c_dialogs, jd); + jinfo->jd = jd; + eXosip_update(); + } + else if (js!=NULL) + { + ADD_ELEMENT(js->s_dialogs, jd); + jinfo->jd = jd; + eXosip_update(); + } + else if (jn!=NULL) + { + ADD_ELEMENT(jn->n_dialogs, jd); + jinfo->jd = jd; + eXosip_update(); + } + else + { +#ifndef WIN32 + assert(0==0); +#else + exit(0); +#endif + } + osip_transaction_set_your_instance(tr, jinfo); + } + else + { + osip_dialog_update_route_set_as_uac(jd->d_dialog, sip); + } + + if ( jd!=NULL) + jd->d_STATE = JD_TRYING; + if ( jd!=NULL && MSG_IS_RESPONSE_FOR(sip, "INVITE") + && sip->status_code < 180) + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_PROCEEDING, jc, jd); + if (je!=NULL) + { + if (sip->status_code>100) + eXosip_event_add_sdp_info(je, sip); + report_event_with_status(je, sip); + } + } + else if ( jd!=NULL && MSG_IS_RESPONSE_FOR(sip, "INVITE") + && sip->status_code >= 180) + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_RINGING, jc, jd); + if (je!=NULL) + { + eXosip_event_add_sdp_info(je, sip); + report_event_with_status(je, sip); + } + } + else if ( jd!=NULL && MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_PROCEEDING, js, jd); + if (je!=NULL) + report_event_with_status(je, sip); + } + if (MSG_TEST_CODE(sip, 180) && jd!=NULL) + { + jd->d_STATE = JD_RINGING; + } + else if (MSG_TEST_CODE(sip, 183) && jd!=NULL) + { + jd->d_STATE = JD_QUEUED; + } + + } +} + +sdp_message_t *eXosip_get_remote_sdp(osip_transaction_t *transaction) +{ + osip_message_t *message; + osip_body_t *body; + sdp_message_t *sdp; + int pos = 0; + int i; + if (transaction->ist_context!=NULL) + /* remote sdp is in INVITE (or ACK!) */ + message = transaction->orig_request; + else + /* remote sdp is in response */ + message = transaction->last_response; + + if (message==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"No remote sdp body found\r\n")); + return NULL; + } + sdp=NULL; + body = (osip_body_t *)osip_list_get(message->bodies,0); + while (body!=NULL) + { + i = sdp_message_init(&sdp); + if (i!=0) + { sdp = NULL; break; } + i = sdp_message_parse(sdp,body->body); + if (i==0) + return sdp; + sdp_message_free(sdp); + sdp = NULL; + pos++; + body = (osip_body_t *)osip_list_get(message->bodies,pos); + } + return NULL; +} + +sdp_message_t *eXosip_get_local_sdp(osip_transaction_t *transaction) +{ + osip_message_t *message; + osip_body_t *body; + sdp_message_t *sdp; + int i; + int pos = 0; + if (transaction->ict_context!=NULL) + /* local sdp is in INVITE (or ACK!) */ + message = transaction->orig_request; + else + /* local sdp is in response */ + message = transaction->last_response; + + sdp=NULL; + body = (osip_body_t *)osip_list_get(message->bodies,0); + while (body!=NULL) + { + i = sdp_message_init(&sdp); + if (i!=0) + { sdp = NULL; break; } + i = sdp_message_parse(sdp,body->body); + if (i==0) + return sdp; + sdp_message_free(sdp); + sdp = NULL; + pos++; + body = (osip_body_t *)osip_list_get(message->bodies,pos); + } + return NULL; +} + + +static +void report_call_event_with_status(int evt, eXosip_call_t *jc, eXosip_dialog_t *jd, osip_message_t *sip) +{ + eXosip_event_t *je; + je = eXosip_event_init_for_call(evt, jc, jd); + if (je!=NULL) + { + if (sip != NULL) + eXosip_event_add_status(je, sip); + if (eXosip.j_call_callbacks[evt]!=NULL) + eXosip.j_call_callbacks[evt](evt, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } + +} + +static +void report_event_with_status(eXosip_event_t *je, osip_message_t *sip) +{ + if (je!=NULL) + { + int evt = je->type; + + if (sip != NULL) + eXosip_event_add_status(je, sip); + if (eXosip.j_call_callbacks[evt]!=NULL) + eXosip.j_call_callbacks[evt](evt, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } +} + + +#if 0 +void eXosip_update_audio_session(osip_transaction_t *transaction) +{ + char *remaddr; + sdp_message_t *remote_sdp; + sdp_message_t *local_sdp; + char *remote_port; + char *local_port; + char *payload; + char *media_type; + int pos; + /* look for the SDP informations */ + + remote_sdp = eXosip_get_remote_sdp(transaction); + if (remote_sdp==NULL) + return ; + local_sdp = eXosip_get_local_sdp(transaction); + if (local_sdp==NULL) + { + sdp_message_free(remote_sdp); + return ; + } + remaddr=sdp_message_c_addr_get(remote_sdp,-1,0); + if (remaddr==NULL){ + remaddr=sdp_message_c_addr_get(remote_sdp,0,0); + } + + pos=0; + local_port=sdp_message_m_port_get(local_sdp,pos); + media_type = sdp_message_m_media_get(local_sdp,pos); + while (local_port!=NULL && media_type!=NULL) + { /* If we have refused some media lines, the port is set to 0 */ + if (0!=strncmp(local_port,"0", 1)&&0==osip_strcasecmp(media_type,"audio")) + break; + pos++; + media_type = sdp_message_m_media_get(local_sdp,pos); + local_port=sdp_message_m_port_get(local_sdp,pos); + } + + if (media_type!=NULL && local_port!=NULL) + { + remote_port = sdp_message_m_port_get(remote_sdp,pos); + payload = sdp_message_m_payload_get(local_sdp,pos,0); + } + else + { + remote_port = NULL; + payload = NULL; + } + if (remote_port!=NULL && media_type!=NULL) /* if codec has been found */ + { + char tmp[256]; + sprintf(tmp, "mediastream --local %s --remote %s:%s --payload %s > debug_rtp 2>&1" , local_port, remaddr, remote_port, payload); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"audio command %s\n", tmp)); + +#ifdef TEST_AUDIO + if (pid!=0) + { + int i = kill(pid, SIGINT); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"audio command kill return %i %i\n", i, pid)); + pid = 0; + } + + pid = fork(); + if (pid==0) + { + int ret; +#ifndef USE_EXECL + ret = system(tmp); + if (WIFSIGNALED(ret) && + (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) + { + exit(-1); + } + if (ret==0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"Could not start audio\n", tmp)); + } + exit(0); +#else + char _remoteipport[100]; + snprintf(_remoteipport, 100, "%s:%s", remaddr, remote_port); + ret = execl("mediastream","--local", local_port, + "--remote", _remoteipport, "--payload", payload); +#endif + } +#endif + + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"Could not create audio session.\r\n")); + } + sdp_message_free(local_sdp); + sdp_message_free(remote_sdp); +} +#endif + +static void cb_rcv2xx_4invite(osip_transaction_t *tr,osip_message_t *sip) +{ + int i; + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd == NULL) /* This transaction initiate a dialog in the case of + INVITE (else it would be attached to a "jd" element. */ + { + /* allocate a jd */ + i = eXosip_dialog_init_as_uac(&jd, sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot establish a dialog\n")); + return; + } + ADD_ELEMENT(jc->c_dialogs, jd); + jinfo->jd = jd; + eXosip_update(); + osip_transaction_set_your_instance(tr, jinfo); + } + else + { + /* Here is a special case: + We have initiated a dialog and we have received informationnal + answers from 2 or more remote SIP UA. Those answer can be + differentiated with the "To" header's tag. + + We have used the first informationnal answer to create a + dialog, but we now want to be sure the 200ok received is + for the dialog this dialog. + + We have to check the To tag and if it does not match, we + just have to modify the existing dialog and replace it. */ + osip_generic_param_t *tag; + int i; + i = osip_to_get_tag (sip->to, &tag); + i=1; /* default is the same dialog */ + + if (jd->d_dialog==NULL || jd->d_dialog->remote_tag==NULL) + { + /* There are real use-case where a BYE is received/processed before + the 200ok of the previous INVITE. In this case, jd->d_dialog is + empty and the transaction should be silently discarded. */ + /* a ACK should still be sent... -but there is no dialog built- */ + return; + } + + if (jd->d_dialog->remote_tag==NULL && tag==NULL) + { } /* non compliant remote UA -> assume it is the same dialog */ + else if (jd->d_dialog->remote_tag!=NULL && tag==NULL) + { i=0; } /* different dialog! */ + else if (jd->d_dialog->remote_tag==NULL && tag!=NULL) + { i=0; } /* different dialog! */ + else if (jd->d_dialog->remote_tag!=NULL && tag!=NULL && tag->gvalue!=NULL + && 0!=strcmp(jd->d_dialog->remote_tag, tag->gvalue)) + { i=0; } /* different dialog! */ + + if (i==1) /* just update the dialog */ + { + osip_dialog_update_route_set_as_uac(jd->d_dialog, sip); + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + } + else + { + /* the best thing is to update the repace the current dialog + information... Much easier than creating a useless dialog! */ + osip_dialog_free(jd->d_dialog); + i = osip_dialog_init_as_uac(&(jd->d_dialog), sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"Cannot replace the dialog.\r\n")); + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_WARNING,NULL,"The dialog has been replaced with the new one fro 200ok.\r\n")); + } + } + } + + jd->d_STATE = JD_ESTABLISHED; + + eXosip_dialog_set_200ok(jd, sip); + + { + osip_route_t *route; + char *host; + int port; + osip_message_t *ack; + i = _eXosip_build_request_within_dialog(&ack, "ACK", jd->d_dialog, "UDP"); + if (i!=0) { + jd->d_STATE = JD_ESTABLISHED; + return ; + } + + if(jc->c_ack_sdp) /* need to build sdp answer */ + { + char *body; + char *size; + + body = generating_sdp_answer(tr->last_response, jc->c_ctx); + if (body==NULL) + { + return; + } + + i = osip_message_set_body(ack, body, strlen(body)); + if (i!=0) + { + return; + } + + size = (char *) osip_malloc(6*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(body)); +#else + sprintf(size,"%i",strlen(body)); +#endif + osip_free(body); + i = osip_message_set_content_length(ack, size); + osip_free(size); + if (i!=0) + { + return; + } + i = osip_message_set_content_type(ack, "application/sdp"); + if (i!=0) + { + return; + } + } + + /* SM: do not send the ack now, just prepare it. + The application will send it using eXosip_send_ack(int jid) + */ + /* + osip_message_get_route(ack, 0, &route); + if (route!=NULL) + { + port = 5060; + if (route->url->port!=NULL) + port = osip_atoi(route->url->port); + host = route->url->host; + } + else + { + port = 5060; + if (ack->req_uri->port!=NULL) + port = osip_atoi(ack->req_uri->port); + host = ack->req_uri->host; + } + + cb_udp_snd_message(NULL, ack, host, port, eXosip.j_socket); + */ + + jd->d_ack = ack; + + } + + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_ANSWERED, jc, jd); + if (je!=NULL) + { + eXosip_event_add_sdp_info(je, sip); + report_event_with_status(je, sip); + } + + + je = eXosip_event_init_for_call(EXOSIP_CALL_STARTAUDIO, jc, jd); + if (je!=NULL) + { + eXosip_event_add_sdp_info(je, sip); + report_event_with_status(je, sip); + } + + } + + /* look for the SDP information and decide if this answer was for + an initial INVITE, an HoldCall, or a RetreiveCall */ + + /* don't handle hold/unhold by now... */ + /* eXosip_update_audio_session(tr); */ + +} + +static void cb_rcv2xx_4subscribe(osip_transaction_t *tr,osip_message_t *sip) +{ + int i; + eXosip_dialog_t *jd; + eXosip_subscribe_t *js; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + if (jinfo==NULL) + return; + jd = jinfo->jd; + js = jinfo->js; + _eXosip_subscribe_set_refresh_interval(js, sip); + + + /* for SUBSCRIBE, test if the dialog has been already created + with a previous NOTIFY */ + if (jd==NULL && js!=NULL && js->s_dialogs!=NULL && MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + /* find if existing dialog match the to tag */ + osip_generic_param_t *tag; + int i; + i = osip_to_get_tag (sip->to, &tag); + if (i==0 && tag!=NULL && tag->gvalue!=NULL ) + { + for (jd = js->s_dialogs; jd!= NULL ; jd=jd->next) + { + if (0==strcmp(jd->d_dialog->remote_tag, tag->gvalue)) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "eXosip: found established early dialog for this subscribe\n")); + jinfo->jd = jd; + break; + } + } + } + } + + if (jd == NULL) /* This transaction initiate a dialog in the case of + SUBSCRIBE (else it would be attached to a "jd" element. */ + { + /* allocate a jd */ + i = eXosip_dialog_init_as_uac(&jd, sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot establish a dialog\n")); + return; + } + ADD_ELEMENT(js->s_dialogs, jd); + jinfo->jd = jd; + eXosip_update(); + osip_transaction_set_your_instance(tr, jinfo); + } + else + { + osip_dialog_update_route_set_as_uac(jd->d_dialog, sip); + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + } + + jd->d_STATE = JD_ESTABLISHED; + /* look for the body information */ + + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_ANSWERED, js, jd); + if (je!=NULL) + { + report_event_with_status(je, sip); + } + } + +} + +static void cb_rcv2xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv2xx (id=%i)\r\n", tr->transactionid)); + + if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) + { + eXosip_pub_t *pub; + int i; + i = _eXosip_pub_update(&pub, tr, sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"cb_rcv2xx (id=%i) No publication to update\r\n", tr->transactionid)); + } + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) + { + eXosip_event_t *je; + eXosip_reg_t *jreg=NULL; + /* find matching j_reg */ + _eXosip_reg_find(&jreg, tr); + if (jreg!=NULL) + { + je = eXosip_event_init_for_reg(EXOSIP_REGISTRATION_SUCCESS, jreg); + if (je!=NULL) + { + report_event_with_status(je, sip); + } + } + return; + } + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + jn = jinfo->jn; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv2xx (id=%i) Error: no call or transaction info for OPTIONS transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + report_call_event_with_status(EXOSIP_OPTIONS_ANSWERED, jc, jd, sip); + return; + } + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + cb_rcv2xx_4invite(tr, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + cb_rcv2xx_4subscribe(tr, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "BYE")) + { + if (jd!=NULL) + jd->d_STATE = JD_TERMINATED; + } + else if (MSG_IS_RESPONSE_FOR(sip, "MESSAGE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_SUCCESS, tr, sip); + if (je!=NULL) + report_event_with_status(je, sip); + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY")) + { +#ifdef SUPPORT_MSN + osip_header_t *expires; + osip_message_header_get_byname(tr->orig_request, "expires", + 0, &expires); + if (expires==NULL || expires->hvalue==NULL) + { + /* UNCOMPLIANT UA without a subscription-state header */ + } + else if (0==osip_strcasecmp(expires->hvalue, "0")) + { + /* delete the dialog! */ + if (jn!=NULL) + { + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + } + } +#else + osip_header_t *sub_state; + osip_message_header_get_byname(tr->orig_request, "subscription-state", + 0, &sub_state); + if (sub_state==NULL || sub_state->hvalue==NULL) + { + /* UNCOMPLIANT UA without a subscription-state header */ + } + else if (0==osip_strncasecmp(sub_state->hvalue, "terminated", 10)) + { + /* delete the dialog! */ + if (jn!=NULL) + { + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + } + } +#endif + } +} + +void eXosip_delete_early_dialog(eXosip_dialog_t *jd) +{ + if (jd == NULL) /* bug? */ + return; + + /* an early dialog was created, but the call is not established */ + if (jd->d_dialog!=NULL && jd->d_dialog->state==DIALOG_EARLY) + { + osip_dialog_free(jd->d_dialog); + jd->d_dialog = NULL; + eXosip_dialog_set_state(jd, JD_TERMINATED); + } +} + +static void +rcvregister_failure(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_event_t *je; + eXosip_reg_t *jreg=NULL; + /* find matching j_reg */ + _eXosip_reg_find(&jreg, tr); + if (jreg!=NULL) + { + je = eXosip_event_init_for_reg(EXOSIP_REGISTRATION_FAILURE, jreg); + report_event_with_status(je, sip); + } +} + +static void cb_rcv3xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv3xx (id=%i)\r\n", tr->transactionid)); + + if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) + { + eXosip_pub_t *pub; + int i; + i = _eXosip_pub_update(&pub, tr, sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"cb_rcv3xx (id=%i) No publication to update\r\n", tr->transactionid)); + } + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) + { + rcvregister_failure(type, tr, sip); + return; + } + + if (jinfo==NULL) return; + jd = jinfo->jd; + jc = jinfo->jc; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv3xx (id=%i) Error: no call or transaction info for INFO transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + + report_call_event_with_status(EXOSIP_OPTIONS_REDIRECTED, jc, jd, sip); + return; + } + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_REDIRECTED, jc, jd, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "MESSAGE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_FAILURE, tr, sip); + if (je) + report_event_with_status(je, sip); + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_REDIRECTED, js, jd); + if (je) + report_event_with_status(je, sip); + } + + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + if (jd->d_dialog==NULL) + jd->d_STATE = JD_REDIRECTED; + } + +} + +static void cb_rcv4xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv4xx (id=%i)\r\n", tr->transactionid)); + + if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) + { + eXosip_pub_t *pub; + int i; + i = _eXosip_pub_update(&pub, tr, sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"cb_rcv4xx (id=%i) No publication to update\r\n", tr->transactionid)); + } + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) + { + rcvregister_failure(type, tr, sip); + return; + } + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv4xx (id=%i) Error: no call or transaction info for INFO transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + + report_call_event_with_status(EXOSIP_OPTIONS_REQUESTFAILURE, jc, jd, sip); + return; + } + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_REQUESTFAILURE, jc, jd, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "MESSAGE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_FAILURE, tr, sip); + if (je!=NULL) + report_event_with_status(je, sip); + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_REQUESTFAILURE, js, jd); + if (je!=NULL) + report_event_with_status(je, sip); + } + + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + if (MSG_TEST_CODE(sip, 401) || MSG_TEST_CODE(sip, 407)) + jd->d_STATE = JD_AUTH_REQUIRED; + else + jd->d_STATE = JD_CLIENTERROR; + } + +} + +static void cb_rcv5xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv5xx (id=%i)\r\n", tr->transactionid)); + + if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) + { + eXosip_pub_t *pub; + int i; + i = _eXosip_pub_update(&pub, tr, sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"cb_rcv3xx (id=%i) No publication to update\r\n", tr->transactionid)); + } + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) + { + rcvregister_failure(type, tr, sip); + return; + } + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv5xx (id=%i) Error: no call or transaction info for INFO transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + + report_call_event_with_status(EXOSIP_OPTIONS_SERVERFAILURE, jc, jd, sip); + return; + } + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_SERVERFAILURE, jc, jd, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "MESSAGE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_FAILURE, tr, sip); + if (je!=NULL) + report_event_with_status(je, sip); + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_SERVERFAILURE, js, jd); + if (je!=NULL) + report_event_with_status(je, sip); + } + + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + jd->d_STATE = JD_SERVERERROR; + } + +} + +static void cb_rcv6xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv6xx (id=%i)\r\n", tr->transactionid)); + + if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) + { + eXosip_pub_t *pub; + int i; + i = _eXosip_pub_update(&pub, tr, sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"cb_rcv6xx (id=%i) No publication to update\r\n", tr->transactionid)); + } + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) + { + rcvregister_failure(type, tr, sip); + return; + } + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + js = jinfo->js; + + if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) + { + if (jc==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcv6xx (id=%i) Error: no call or transaction info for INFO transaction\r\n", tr->transactionid)); + return; + } + else if (jc->c_out_options_tr==NULL) + { + /* options is within a call */ + } + report_call_event_with_status(EXOSIP_OPTIONS_GLOBALFAILURE, jc, jd, sip); + return; + } + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_GLOBALFAILURE, jc, jd, sip); + } + else if (MSG_IS_RESPONSE_FOR(sip, "MESSAGE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_FAILURE, tr, sip); + if (je!=NULL) + report_event_with_status(je, sip); + return; + } + else if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_GLOBALFAILURE, js, jd); + if (je!=NULL) + report_event_with_status(je, sip); + } + + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + jd->d_STATE = JD_GLOBALFAILURE; + } + +} + +static void cb_snd1xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd1xx (id=%i)\r\n", tr->transactionid)); + + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + jd->d_STATE = JD_TRYING; +} + +static void cb_snd2xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd2xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + jd->d_STATE = JD_ESTABLISHED; + return; + } + jd->d_STATE = JD_ESTABLISHED; +} + +static void cb_snd3xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd3xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + } + jd->d_STATE = JD_REDIRECTED; + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_CLOSED, jc, jd, sip); + } +} + +static void cb_snd4xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd4xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + } + jd->d_STATE = JD_CLIENTERROR; + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_CLOSED, jc, jd, sip); + } + +} + +static void cb_snd5xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd5xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + } + jd->d_STATE = JD_SERVERERROR; + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_CLOSED, jc, jd, sip); + } + +} + +static void cb_snd6xx(int type, osip_transaction_t *tr,osip_message_t *sip) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_snd6xx (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + if (jd==NULL) return; + if (MSG_IS_RESPONSE_FOR(sip, "INVITE") + || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) + { + eXosip_delete_early_dialog(jd); + } + jd->d_STATE = JD_GLOBALFAILURE; + + if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) + { + report_call_event_with_status(EXOSIP_CALL_CLOSED, jc, jd, sip); + } + +} + +static void cb_rcvresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvresp_retransmission (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndreq_retransmission (id=%i)\r\n", tr->transactionid)); +} + +static void cb_sndresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_sndresp_retransmission (id=%i)\r\n", tr->transactionid)); +} + +static void cb_rcvreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) +{ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_rcvreq_retransmission (id=%i)\r\n", tr->transactionid)); +} + +static void cb_transport_error(int type, osip_transaction_t *tr, int error) +{ + eXosip_dialog_t *jd; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + jinfo_t *jinfo = (jinfo_t *)osip_transaction_get_your_instance(tr); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"cb_transport_error (id=%i)\r\n", tr->transactionid)); + if (jinfo==NULL) + return; + jd = jinfo->jd; + jc = jinfo->jc; + jn = jinfo->jn; + js = jinfo->js; + + if (jn==NULL && js==NULL) + return; + + if (MSG_IS_NOTIFY(tr->orig_request) + && type==OSIP_NICT_TRANSPORT_ERROR) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_notifies, jn); + eXosip_notify_free(jn); + } + + if (MSG_IS_SUBSCRIBE(tr->orig_request) + && type==OSIP_NICT_TRANSPORT_ERROR) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + } + + if (MSG_IS_OPTIONS(tr->orig_request) && jc->c_dialogs==NULL + && type==OSIP_NICT_TRANSPORT_ERROR) + { + /* delete the dialog! */ + REMOVE_ELEMENT(eXosip.j_calls, jc); + eXosip_call_free(jc); + } +} + + + +int +eXosip_set_callbacks(osip_t *osip) +{ + /* register all callbacks */ + + osip_set_cb_send_message(osip, &cb_udp_snd_message); + + osip_set_kill_transaction_callback(osip ,OSIP_ICT_KILL_TRANSACTION, + &cb_ict_kill_transaction); + osip_set_kill_transaction_callback(osip ,OSIP_IST_KILL_TRANSACTION, + &cb_ist_kill_transaction); + osip_set_kill_transaction_callback(osip ,OSIP_NICT_KILL_TRANSACTION, + &cb_nict_kill_transaction); + osip_set_kill_transaction_callback(osip ,OSIP_NIST_KILL_TRANSACTION, + &cb_nist_kill_transaction); + + osip_set_message_callback(osip ,OSIP_ICT_STATUS_2XX_RECEIVED_AGAIN, + &cb_rcvresp_retransmission); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_3456XX_RECEIVED_AGAIN, + &cb_rcvresp_retransmission); + osip_set_message_callback(osip ,OSIP_ICT_INVITE_SENT_AGAIN, + &cb_sndreq_retransmission); + osip_set_message_callback(osip ,OSIP_IST_STATUS_2XX_SENT_AGAIN, + &cb_sndresp_retransmission); + osip_set_message_callback(osip ,OSIP_IST_STATUS_3456XX_SENT_AGAIN, + &cb_sndresp_retransmission); + osip_set_message_callback(osip ,OSIP_IST_INVITE_RECEIVED_AGAIN, + &cb_rcvreq_retransmission); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_2XX_RECEIVED_AGAIN, + &cb_rcvresp_retransmission); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_3456XX_RECEIVED_AGAIN, + &cb_rcvresp_retransmission); + osip_set_message_callback(osip ,OSIP_NICT_REQUEST_SENT_AGAIN, + &cb_sndreq_retransmission); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_2XX_SENT_AGAIN, + &cb_sndresp_retransmission); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_3456XX_SENT_AGAIN, + &cb_sndresp_retransmission); + osip_set_message_callback(osip ,OSIP_NIST_REQUEST_RECEIVED_AGAIN, + &cb_rcvreq_retransmission); + + osip_set_transport_error_callback(osip ,OSIP_ICT_TRANSPORT_ERROR, + &cb_transport_error); + osip_set_transport_error_callback(osip ,OSIP_IST_TRANSPORT_ERROR, + &cb_transport_error); + osip_set_transport_error_callback(osip ,OSIP_NICT_TRANSPORT_ERROR, + &cb_transport_error); + osip_set_transport_error_callback(osip ,OSIP_NIST_TRANSPORT_ERROR, + &cb_transport_error); + + osip_set_message_callback(osip ,OSIP_ICT_INVITE_SENT, &cb_sndinvite); + osip_set_message_callback(osip ,OSIP_ICT_ACK_SENT, &cb_sndack); + osip_set_message_callback(osip ,OSIP_NICT_REGISTER_SENT, &cb_sndregister); + osip_set_message_callback(osip ,OSIP_NICT_BYE_SENT, &cb_sndbye); + osip_set_message_callback(osip ,OSIP_NICT_CANCEL_SENT, &cb_sndcancel); + osip_set_message_callback(osip ,OSIP_NICT_INFO_SENT, &cb_sndinfo); + osip_set_message_callback(osip ,OSIP_NICT_OPTIONS_SENT, &cb_sndoptions); + osip_set_message_callback(osip ,OSIP_NICT_SUBSCRIBE_SENT, &cb_sndsubscribe); + osip_set_message_callback(osip ,OSIP_NICT_NOTIFY_SENT, &cb_sndnotify); + /* osip_set_cb_nict_sndprack (osip,&cb_sndprack); */ + osip_set_message_callback(osip ,OSIP_NICT_UNKNOWN_REQUEST_SENT, &cb_sndunkrequest); + + osip_set_message_callback(osip ,OSIP_ICT_STATUS_1XX_RECEIVED, &cb_rcv1xx); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_2XX_RECEIVED, &cb_rcv2xx); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_3XX_RECEIVED, &cb_rcv3xx); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_4XX_RECEIVED, &cb_rcv4xx); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_5XX_RECEIVED, &cb_rcv5xx); + osip_set_message_callback(osip ,OSIP_ICT_STATUS_6XX_RECEIVED, &cb_rcv6xx); + + osip_set_message_callback(osip ,OSIP_IST_STATUS_1XX_SENT, &cb_snd1xx); + osip_set_message_callback(osip ,OSIP_IST_STATUS_2XX_SENT, &cb_snd2xx); + osip_set_message_callback(osip ,OSIP_IST_STATUS_3XX_SENT, &cb_snd3xx); + osip_set_message_callback(osip ,OSIP_IST_STATUS_4XX_SENT, &cb_snd4xx); + osip_set_message_callback(osip ,OSIP_IST_STATUS_5XX_SENT, &cb_snd5xx); + osip_set_message_callback(osip ,OSIP_IST_STATUS_6XX_SENT, &cb_snd6xx); + + osip_set_message_callback(osip ,OSIP_NICT_STATUS_1XX_RECEIVED, &cb_rcv1xx); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_2XX_RECEIVED, &cb_rcv2xx); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_3XX_RECEIVED, &cb_rcv3xx); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_4XX_RECEIVED, &cb_rcv4xx); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_5XX_RECEIVED, &cb_rcv5xx); + osip_set_message_callback(osip ,OSIP_NICT_STATUS_6XX_RECEIVED, &cb_rcv6xx); + + osip_set_message_callback(osip ,OSIP_NIST_STATUS_1XX_SENT, &cb_snd1xx); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_2XX_SENT, &cb_snd2xx); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_3XX_SENT, &cb_snd3xx); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_4XX_SENT, &cb_snd4xx); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_5XX_SENT, &cb_snd5xx); + osip_set_message_callback(osip ,OSIP_NIST_STATUS_6XX_SENT, &cb_snd6xx); + + osip_set_message_callback(osip ,OSIP_IST_INVITE_RECEIVED, &cb_rcvinvite); + osip_set_message_callback(osip ,OSIP_IST_ACK_RECEIVED, &cb_rcvack); + osip_set_message_callback(osip ,OSIP_IST_ACK_RECEIVED_AGAIN, &cb_rcvack2); + osip_set_message_callback(osip ,OSIP_NIST_REGISTER_RECEIVED, &cb_rcvregister); + osip_set_message_callback(osip ,OSIP_NIST_BYE_RECEIVED, &cb_rcvbye); + osip_set_message_callback(osip ,OSIP_NIST_CANCEL_RECEIVED, &cb_rcvcancel); + osip_set_message_callback(osip ,OSIP_NIST_INFO_RECEIVED, &cb_rcvinfo); + osip_set_message_callback(osip ,OSIP_NIST_OPTIONS_RECEIVED, &cb_rcvoptions); + osip_set_message_callback(osip ,OSIP_NIST_SUBSCRIBE_RECEIVED, &cb_rcvsubscribe); + osip_set_message_callback(osip ,OSIP_NIST_NOTIFY_RECEIVED, &cb_rcvnotify); + osip_set_message_callback(osip ,OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, &cb_rcvunkrequest); + + + return 0; +} diff --git a/linphone/exosip/jdialog.c b/linphone/exosip/jdialog.c new file mode 100644 index 000000000..9a8f859b6 --- /dev/null +++ b/linphone/exosip/jdialog.c @@ -0,0 +1,209 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" + +extern eXosip_t eXosip; + +void eXosip_dialog_set_state(eXosip_dialog_t *jd, int state) +{ + jd->d_STATE = state; +} + +int eXosip_call_dialog_find(int jid, eXosip_call_t **jc, eXosip_dialog_t **jd) +{ + for (*jc=eXosip.j_calls; *jc!=NULL; *jc=(*jc)->next) + { + for (*jd=(*jc)->c_dialogs; *jd!=NULL; *jd=(*jd)->next) + { + if ((*jd)->d_id==jid) + return 0; + } + } + *jd = NULL; + *jc = NULL; + return -1; +} + +int eXosip_notify_dialog_find(int nid, eXosip_notify_t **jn, eXosip_dialog_t **jd) +{ + for (*jn=eXosip.j_notifies; *jn!=NULL; *jn=(*jn)->next) + { + for (*jd=(*jn)->n_dialogs; *jd!=NULL; *jd=(*jd)->next) + { + if ((*jd)->d_id==nid) + return 0; + } + } + *jd = NULL; + *jn = NULL; + return -1; +} + +int eXosip_subscribe_dialog_find(int sid, eXosip_subscribe_t **js, eXosip_dialog_t **jd) +{ + for (*js=eXosip.j_subscribes; *js!=NULL; *js=(*js)->next) + { + *jd=NULL; + if ((*js)->s_id==sid) + return 0; + for (*jd=(*js)->s_dialogs; *jd!=NULL; *jd=(*jd)->next) + { + if ((*jd)->d_id==sid) + return 0; + } + } + *jd = NULL; + *js = NULL; + return -1; +} + +int eXosip_dialog_set_200ok(eXosip_dialog_t *jd, osip_message_t *_200Ok) +{ + int i; + if (jd==NULL) return -1; + i = osip_message_clone(_200Ok, &(jd->d_200Ok)); + if (i!=0) { + return -1; + } + return 0; +} + +int eXosip_dialog_init_as_uac(eXosip_dialog_t **_jd, osip_message_t *_200Ok) +{ + int i; + eXosip_dialog_t *jd; + *_jd = NULL; + jd = (eXosip_dialog_t *) osip_malloc(sizeof(eXosip_dialog_t)); + jd->d_id = -1; /* not yet available to user */ + jd->d_STATE = JD_EMPTY; + + if (MSG_IS_REQUEST(_200Ok)) + { + i = osip_dialog_init_as_uac_with_remote_request(&(jd->d_dialog), _200Ok, -1); + } + else + { /* normal usage with response */ + i = osip_dialog_init_as_uac(&(jd->d_dialog), _200Ok); + } + if (i!=0) + { + osip_free(jd); + return -1; + } + + jd->media_lines = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->media_lines); + + jd->d_timer = time(NULL); + jd->d_200Ok = NULL; + jd->d_ack = NULL; + jd->next = NULL; + jd->parent = NULL; + jd->d_out_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->d_out_trs); + jd->d_inc_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->d_inc_trs); + + /* jd->d_bh = sdp_handler_new(); */ + *_jd = jd; + return 0; +} + +int eXosip_dialog_init_as_uas(eXosip_dialog_t **_jd, osip_message_t *_invite, osip_message_t *_200Ok) +{ + int i; + eXosip_dialog_t *jd; + *_jd = NULL; + jd = (eXosip_dialog_t *) osip_malloc(sizeof(eXosip_dialog_t)); + jd->d_id = -1; /* not yet available to user */ + jd->d_STATE = JD_EMPTY; + i = osip_dialog_init_as_uas(&(jd->d_dialog), _invite, _200Ok); + if (i!=0) + { + osip_free(jd); + return -1; + } + + jd->media_lines = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->media_lines); + + jd->d_timer = time(NULL); + jd->d_200Ok = NULL; + jd->d_ack = NULL; + jd->next = NULL; + jd->parent = NULL; + jd->d_out_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->d_out_trs); + jd->d_inc_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(jd->d_inc_trs); + +#ifdef SUPPORT_MSN + /* bugguy MSN */ + jd->d_dialog->local_cseq = 1; +#endif + + /* jd->d_bh = sdp_handler_new(); */ + *_jd = jd; + return 0; +} + +void eXosip_dialog_free(eXosip_dialog_t *jd) +{ + + while (!osip_list_eol(jd->d_inc_trs, 0)) + { + osip_transaction_t *tr; + tr = (osip_transaction_t*) osip_list_get(jd->d_inc_trs, 0); + osip_list_remove(jd->d_inc_trs, 0); + __eXosip_delete_jinfo(tr); + osip_list_add(eXosip.j_transactions, tr, 0); + } + + while (!osip_list_eol(jd->d_out_trs, 0)) + { + osip_transaction_t *tr; + tr = (osip_transaction_t*) osip_list_get(jd->d_out_trs, 0); + osip_list_remove(jd->d_out_trs, 0); + __eXosip_delete_jinfo(tr); + osip_list_add(eXosip.j_transactions, tr, 0); + } + + osip_message_free(jd->d_200Ok); + osip_message_free(jd->d_ack); + + osip_dialog_free(jd->d_dialog); + + while (!osip_list_eol(jd->media_lines, 0)) + { + char *tmp = osip_list_get(jd->media_lines, 0); + osip_list_remove(jd->media_lines, 0); + osip_free(tmp); + } + + osip_free(jd->media_lines); + osip_free(jd->d_out_trs); + osip_free(jd->d_inc_trs); + osip_free(jd); +} diff --git a/linphone/exosip/jevents.c b/linphone/exosip/jevents.c new file mode 100644 index 000000000..a57efe8be --- /dev/null +++ b/linphone/exosip/jevents.c @@ -0,0 +1,949 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include +#include + +extern eXosip_t eXosip; + + +static void fill_dialog_params(eXosip_event_t *je, osip_dialog_t *dialog) +{ + char *tmp; + if (dialog->remote_uri!=NULL){ + osip_to_to_str(dialog->remote_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->remote_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (dialog->local_uri!=NULL) + { + osip_to_to_str(dialog->local_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->local_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (dialog->remote_contact_uri!=NULL){ + osip_contact_to_str(dialog->remote_contact_uri,&tmp); + if (tmp!=NULL){ + snprintf(je->remote_contact,255,"%s",tmp); + osip_free(tmp); + } + } +} + +eXosip_event_t * +eXosip_event_init_for_call(int type, + eXosip_call_t *jc, + eXosip_dialog_t *jd) +{ + eXosip_event_t *je; + eXosip_event_init(&je, type); + if (je==NULL) return NULL; + je->jc = jc; + je->jd = jd; + + je->cid = jc->c_id; + if (jd!=NULL) + je->did = jd->d_id; + + je->external_reference = jc->external_reference; + + /* fill in usefull info */ + if (type==EXOSIP_CALL_NEW + || type==EXOSIP_CALL_ACK + || type==EXOSIP_CALL_NOANSWER + || type==EXOSIP_CALL_PROCEEDING + || type==EXOSIP_CALL_RINGING + || type==EXOSIP_CALL_ANSWERED + || type==EXOSIP_CALL_REDIRECTED + || type==EXOSIP_CALL_REQUESTFAILURE + || type==EXOSIP_CALL_SERVERFAILURE + || type==EXOSIP_CALL_GLOBALFAILURE + + || type==EXOSIP_OPTIONS_NOANSWER + || type==EXOSIP_OPTIONS_PROCEEDING + || type==EXOSIP_OPTIONS_ANSWERED + || type==EXOSIP_OPTIONS_REDIRECTED + || type==EXOSIP_OPTIONS_REQUESTFAILURE + || type==EXOSIP_OPTIONS_SERVERFAILURE + || type==EXOSIP_OPTIONS_GLOBALFAILURE + || type==EXOSIP_OPTIONS_NEW + + || type==EXOSIP_INFO_NOANSWER + || type==EXOSIP_INFO_PROCEEDING + || type==EXOSIP_INFO_ANSWERED + || type==EXOSIP_INFO_REDIRECTED + || type==EXOSIP_INFO_REQUESTFAILURE + || type==EXOSIP_INFO_SERVERFAILURE + || type==EXOSIP_INFO_GLOBALFAILURE + || type==EXOSIP_INFO_NEW + + || type==EXOSIP_CALL_CANCELLED + || type==EXOSIP_CALL_TIMEOUT + || type==EXOSIP_CALL_HOLD + || type==EXOSIP_CALL_OFFHOLD + || type==EXOSIP_CALL_CLOSED + || type==EXOSIP_CALL_STARTAUDIO + + || type==EXOSIP_CALL_REFERED + || type==EXOSIP_CALL_REFER_STATUS + + || type==EXOSIP_CALL_RELEASED) + { + if (jc->c_sdp_port[0]!='\0') + je->local_sdp_audio_port = osip_atoi(jc->c_sdp_port); + + if (jd!=NULL&&jd->d_dialog!=NULL) + { + osip_transaction_t *tr; + osip_header_t *subject; + char *tmp; + + fill_dialog_params(je,jd->d_dialog); + + if (type==EXOSIP_OPTIONS_NOANSWER + || type==EXOSIP_OPTIONS_PROCEEDING + || type==EXOSIP_OPTIONS_ANSWERED + || type==EXOSIP_OPTIONS_REDIRECTED + || type==EXOSIP_OPTIONS_REQUESTFAILURE + || type==EXOSIP_OPTIONS_SERVERFAILURE + || type==EXOSIP_OPTIONS_GLOBALFAILURE + || type==EXOSIP_OPTIONS_NEW) + tr = eXosip_find_last_options(jc, jd); + else if (type==EXOSIP_INFO_NOANSWER + || type==EXOSIP_INFO_PROCEEDING + || type==EXOSIP_INFO_ANSWERED + || type==EXOSIP_INFO_REDIRECTED + || type==EXOSIP_INFO_REQUESTFAILURE + || type==EXOSIP_INFO_SERVERFAILURE + || type==EXOSIP_INFO_GLOBALFAILURE + || type==EXOSIP_INFO_NEW) + tr = eXosip_find_last_info(jc, jd); + else if (type==EXOSIP_CALL_REFERED) + tr = eXosip_find_last_refer(jc, jd); + else if (type==EXOSIP_CALL_REFER_STATUS) + tr = eXosip_find_last_inc_notify_for_refer(jc, jd); + else + tr = eXosip_find_last_invite(jc, jd); + if (tr!=NULL && tr->orig_request!=NULL) + { + osip_message_get_subject(tr->orig_request, 0, &subject); + if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0') + snprintf(je->subject, 255, "%s", subject->hvalue); + osip_message_header_get_byname(tr->orig_request, "refer-to", 0, + &subject); + if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0') + snprintf(je->refer_to, 255, "%s", subject->hvalue); + + osip_uri_to_str(tr->orig_request->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + + }else{ + osip_transaction_t *tr; + char *tmp; + tr=eXosip_find_last_invite(jc,NULL); + /* no dialog established but we need to fill remote_contact */ + if (tr!=NULL && tr->last_response!=NULL) + { + osip_contact_t *ctt=NULL; + snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase); + je->status_code = tr->last_response->status_code; + osip_message_get_contact(tr->last_response,0,&ctt); + if (ctt){ + tmp=NULL; + osip_contact_to_str(ctt,&tmp); + if (tmp){ + strncpy(je->remote_contact,tmp,255); + } + } + } + } + } + + return je; +} + +int +eXosip_event_add_status(eXosip_event_t *je, osip_message_t *response) +{ + if (response!=NULL && response->reason_phrase!=NULL) + { + snprintf(je->reason_phrase, 49, "%s", response->reason_phrase); + je->status_code = response->status_code; + } + return 0; +} + +int +eXosip_event_add_sdp_info(eXosip_event_t *je, osip_message_t *message) +{ + osip_content_type_t *ctt; + osip_mime_version_t *mv; + sdp_message_t *sdp; + osip_body_t *oldbody; + int pos; + int gotpayload = 0; + + + + /* + search for remote_sdp_audio_port & remote_sdp_audio_ip + in the last SIP message + extract the payload to be used for connection either from negotioation context + or from the last SIP message + */ + + + + if (message==NULL) return -1; + + /* get content-type info */ + ctt = osip_message_get_content_type(message); + mv = osip_message_get_mime_version(message); + if (mv==NULL && ctt==NULL) + return 0; /* previous message was not correct or empty */ + if (mv!=NULL) + { + /* look for the SDP body */ + /* ... */ + } + else if (ctt!=NULL) + { + if (ctt->type==NULL || ctt->subtype==NULL) + /* it can be application/sdp or mime... */ + return -1; + if (osip_strcasecmp(ctt->type, "application")!=0 || + osip_strcasecmp(ctt->subtype, "sdp")!=0 ) + { return -1; } + } + + + if (je->jc) + { + int pl = eXosip_retrieve_sdp_negotiation_result(je->jc->c_ctx, je->payload_name, sizeof(je->payload_name)); + if (pl >= 0) + { + je->payload = pl; + gotpayload = 1; + } + } + + + sdp = NULL; + pos = 0; + while (!osip_list_eol(message->bodies, pos)) + { + int i; + oldbody = (osip_body_t *)osip_list_get(message->bodies, pos); + pos++; + sdp_message_init(&sdp); + i = sdp_message_parse(sdp,oldbody->body); + if (i==0) + { + int len = strlen(oldbody->body); + if (len<999) + osip_strncpy(je->sdp_body, oldbody->body, len); + else + osip_strncpy(je->sdp_body, oldbody->body, 999); + + break; + } + sdp_message_free(sdp); + sdp = NULL; + } + + + + if (sdp!=NULL) + { + int j=0; + if (sdp->c_connection !=NULL + && sdp->c_connection->c_addr !=NULL ) + { + snprintf(je->remote_sdp_audio_ip, 49, "%s", + sdp->c_connection->c_addr); + } + + + for (j=0; !osip_list_eol(sdp->m_medias, j); j++) + { + sdp_media_t *med = (sdp_media_t*) osip_list_get(sdp->m_medias, j); + if (med==NULL) + { + snprintf(je->remote_sdp_audio_ip, 49, "Y a probleme!"); + } + + if (med->m_media!=NULL && + 0==osip_strcasecmp(med->m_media, "audio")) + { + sdp_connection_t *conn; + int pos_attr; + char *payload = (char *) osip_list_get (med->m_payloads, 0); + + if (!gotpayload) + je->payload = 0; + + if (!gotpayload && payload!=NULL) + { + je->payload = osip_atoi(payload); + /* copy payload name! */ + for (pos_attr=0; + !osip_list_eol(med->a_attributes, pos_attr); + pos_attr++) + { + sdp_attribute_t *attr; + attr = (sdp_attribute_t *)osip_list_get(med->a_attributes, pos_attr); + if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6)) + { + if ((je->payload<10 && + 0==osip_strncasecmp(attr->a_att_value, payload, 1)) + ||(je->payload>9 && je->payload<100 && + 0==osip_strncasecmp(attr->a_att_value, payload, 2)) + ||(je->payload>100 && je->payload<128 && + 0==osip_strncasecmp(attr->a_att_value, payload, 3))) + { + snprintf(je->payload_name, 49, "%s", attr->a_att_value); + } + } + } + } + + + je->remote_sdp_audio_port = osip_atoi(med->m_port); + conn = (sdp_connection_t*) osip_list_get(med->c_connections, 0); + if (conn!=NULL && conn->c_addr!=NULL) + { + snprintf(je->remote_sdp_audio_ip, 49, "%s", + conn->c_addr); + } + sdp_message_free(sdp); + return 0; + } + } + sdp_message_free(sdp); + } + return -1; +} + + +eXosip_event_t * +eXosip_event_init_for_subscribe(int type, + eXosip_subscribe_t *js, + eXosip_dialog_t *jd) +{ + char *tmp; + eXosip_event_t *je; + eXosip_event_init(&je, type); + if (je==NULL) return NULL; + je->js = js; + je->jd = jd; + + je->sid = js->s_id; + if (jd!=NULL) + je->did = jd->d_id; + + je->ss_status = js->s_ss_status; + je->online_status = js->s_online_status; + je->ss_reason = js->s_ss_reason; + + /* je->external_reference = js->external_reference; */ + + if (jd!=NULL&&jd->d_dialog!=NULL) + { + fill_dialog_params(je,jd->d_dialog); + } + + /* fill in usefull info */ + if (type==EXOSIP_SUBSCRIPTION_NEW + || type==EXOSIP_SUBSCRIPTION_NOANSWER + || type==EXOSIP_SUBSCRIPTION_PROCEEDING + || type==EXOSIP_SUBSCRIPTION_ANSWERED + || type==EXOSIP_SUBSCRIPTION_REDIRECTED + || type==EXOSIP_SUBSCRIPTION_REQUESTFAILURE + || type==EXOSIP_SUBSCRIPTION_SERVERFAILURE + || type==EXOSIP_SUBSCRIPTION_GLOBALFAILURE + || type==EXOSIP_SUBSCRIPTION_RELEASED) + { + if (jd!=NULL&&jd->d_dialog!=NULL) + { + osip_transaction_t *tr; + tr = eXosip_find_last_out_subscribe(js, jd); + if (tr!=NULL && tr->orig_request!=NULL) + { + osip_uri_to_str(tr->orig_request->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (tr!=NULL && tr->last_response!=NULL) + { + snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase); + je->status_code = tr->last_response->status_code; + } + } + } + else if (type==EXOSIP_SUBSCRIPTION_NOTIFY) + { + if (jd!=NULL&&jd->d_dialog!=NULL) + { + osip_transaction_t *tr; + tr = eXosip_find_last_inc_notify(js, jd); + if (tr!=NULL && tr->orig_request!=NULL) + { + osip_uri_to_str(tr->orig_request->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (tr!=NULL && tr->last_response!=NULL) + { + snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase); + je->status_code = tr->last_response->status_code; + } + } + } + + return je; +} + +eXosip_event_t * +eXosip_event_init_for_notify(int type, + eXosip_notify_t *jn, + eXosip_dialog_t *jd) +{ + eXosip_event_t *je; + eXosip_event_init(&je, type); + if (je==NULL) return NULL; + je->jn = jn; + je->jd = jd; + + je->nid = jn->n_id; + if (jd!=NULL) + je->did = jd->d_id; + + je->ss_status = jn->n_ss_status; + je->online_status = jn->n_online_status; + je->ss_reason = jn->n_ss_reason; + + /*je->external_reference = jc->external_reference; */ + + /* fill in usefull info */ + if (type==EXOSIP_IN_SUBSCRIPTION_NEW + || type==EXOSIP_IN_SUBSCRIPTION_RELEASED) + { + if (jd!=NULL&&jd->d_dialog!=NULL) + { + osip_transaction_t *tr; + char *tmp; + fill_dialog_params(je,jd->d_dialog); + tr = eXosip_find_last_inc_subscribe(jn, jd); + if (tr!=NULL && tr->orig_request!=NULL) + { + osip_uri_to_str(tr->orig_request->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (tr!=NULL && tr->last_response!=NULL) + { + snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase); + je->status_code = tr->last_response->status_code; + } + } + } + + return je; +} + +eXosip_event_t * +eXosip_event_init_for_reg(int type, + eXosip_reg_t *jr) +{ + eXosip_event_t *je; + eXosip_event_init(&je, type); + if (je==NULL) return NULL; + je->jr = jr; + je->rid = jr->r_id; + snprintf(je->remote_uri, 255, "%s", jr->r_aor); + snprintf(je->req_uri, 255, "%s", jr->r_registrar); + return je; +} + +eXosip_event_t * +eXosip_event_init_for_message(int type, osip_transaction_t *tr, + osip_message_t *sip) +{ + eXosip_event_t *je; + eXosip_event_init(&je, type); + if (je==NULL) return NULL; + + /* fill in usefull info */ + { + char *tmp; + + /* Request URI */ + + osip_uri_to_str(sip->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + + /* FROM & TO */ + + + if (sip->from != NULL) + { + osip_from_to_str(sip->from, &tmp); + if (tmp!=NULL) + { + snprintf(je->remote_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + if (sip->to != NULL) + { + osip_to_to_str(sip->to, &tmp); + if (tmp!=NULL) + { + snprintf(je->local_uri, 255, "%s", tmp); + osip_free(tmp); + } + } + } + + return je; +} + +int +eXosip_event_init(eXosip_event_t **je, int type) +{ + *je = (eXosip_event_t *) osip_malloc(sizeof(eXosip_event_t)); + if (*je==NULL) return -1; + + memset(*je, 0, sizeof(eXosip_event_t)); + (*je)->type = type; + + if (type==EXOSIP_CALL_NOANSWER) + { + sprintf((*je)->textinfo, "No answer for this Call!"); + } + else if (type==EXOSIP_CALL_PROCEEDING) + { + sprintf((*je)->textinfo, "Call is being processed!"); + } + else if (type==EXOSIP_CALL_RINGING) + { + sprintf((*je)->textinfo, "Remote phone is ringing!"); + } + else if (type==EXOSIP_CALL_ANSWERED) + { + sprintf((*je)->textinfo, "Remote phone has answered!"); + } + else if (type==EXOSIP_CALL_REDIRECTED) + { + sprintf((*je)->textinfo, "Call is redirected!"); + } + else if (type==EXOSIP_CALL_REQUESTFAILURE) + { + sprintf((*je)->textinfo, "4xx received for Call!"); + } + else if (type==EXOSIP_CALL_SERVERFAILURE) + { + sprintf((*je)->textinfo, "5xx received for Call!"); + } + else if (type==EXOSIP_CALL_GLOBALFAILURE) + { + sprintf((*je)->textinfo, "6xx received for Call!"); + } + else if (type==EXOSIP_CALL_NEW) + { + sprintf((*je)->textinfo, "New call received!"); + } + else if (type==EXOSIP_CALL_ACK) + { + sprintf((*je)->textinfo, "ACK received!"); + } + else if (type==EXOSIP_CALL_CANCELLED) + { + sprintf((*je)->textinfo, "Call has been cancelled!"); + } + else if (type==EXOSIP_CALL_TIMEOUT) + { + sprintf((*je)->textinfo, "Timeout. Gived up!"); + } + else if (type==EXOSIP_CALL_HOLD) + { + sprintf((*je)->textinfo, "Call is on Hold!"); + } + else if (type==EXOSIP_CALL_OFFHOLD) + { + sprintf((*je)->textinfo, "Call is off Hold!"); + } + else if (type==EXOSIP_CALL_CLOSED) + { + sprintf((*je)->textinfo, "Bye Received!"); + } + else if (type==EXOSIP_CALL_RELEASED) + { + sprintf((*je)->textinfo, "Call Context is released!"); + } + else if (type==EXOSIP_REGISTRATION_SUCCESS) + { + sprintf((*je)->textinfo, "User is successfully registred!"); + } + else if (type==EXOSIP_REGISTRATION_FAILURE) + { + sprintf((*je)->textinfo, "Registration failed!"); + } + else if (type==EXOSIP_OPTIONS_NEW) + { + sprintf((*je)->textinfo, "New OPTIONS received!"); + } + else if (type==EXOSIP_OPTIONS_NOANSWER) + { + sprintf((*je)->textinfo, "No answer for this OPTIONS!"); + } + else if (type==EXOSIP_OPTIONS_PROCEEDING) + { + sprintf((*je)->textinfo, "OPTIONS is being processed!"); + } + else if (type==EXOSIP_OPTIONS_ANSWERED) + { + sprintf((*je)->textinfo, "2xx received for OPTIONS!"); + } + else if (type==EXOSIP_OPTIONS_REDIRECTED) + { + sprintf((*je)->textinfo, "3xx received for OPTIONS!"); + } + else if (type==EXOSIP_OPTIONS_REQUESTFAILURE) + { + sprintf((*je)->textinfo, "4xx received for OPTIONS!"); + } + else if (type==EXOSIP_OPTIONS_SERVERFAILURE) + { + sprintf((*je)->textinfo, "5xx received for OPTIONS!"); + } + else if (type==EXOSIP_OPTIONS_GLOBALFAILURE) + { + sprintf((*je)->textinfo, "5xx received for OPTIONS!"); + } + else if (type==EXOSIP_INFO_NEW) + { + sprintf((*je)->textinfo, "New INFO received!"); + } + else if (type==EXOSIP_INFO_NOANSWER) + { + sprintf((*je)->textinfo, "No answer for this INFO!"); + } + else if (type==EXOSIP_INFO_PROCEEDING) + { + sprintf((*je)->textinfo, "INFO is being processed!"); + } + else if (type==EXOSIP_INFO_ANSWERED) + { + sprintf((*je)->textinfo, "2xx received for INFO!"); + } + else if (type==EXOSIP_INFO_REDIRECTED) + { + sprintf((*je)->textinfo, "3xx received for INFO!"); + } + else if (type==EXOSIP_INFO_REQUESTFAILURE) + { + sprintf((*je)->textinfo, "4xx received for INFO!"); + } + else if (type==EXOSIP_INFO_SERVERFAILURE) + { + sprintf((*je)->textinfo, "5xx received for INFO!"); + } + else if (type==EXOSIP_INFO_GLOBALFAILURE) + { + sprintf((*je)->textinfo, "6xx received for INFO!"); + } + else if (type==EXOSIP_MESSAGE_NEW) + { + sprintf((*je)->textinfo, "New MESSAGE received!"); + } + else if (type==EXOSIP_MESSAGE_SUCCESS) + { + sprintf((*je)->textinfo, "User has successfully received our MESSAGE!"); + } + else if (type==EXOSIP_MESSAGE_FAILURE) + { + sprintf((*je)->textinfo, "Error received for our MESSAGE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_NEW) + { + sprintf((*je)->textinfo, "New SUBSCRIBE received!"); + } + else if (type==EXOSIP_SUBSCRIPTION_NOANSWER) + { + sprintf((*je)->textinfo, "No answer for this SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_PROCEEDING) + { + sprintf((*je)->textinfo, "SUBSCRIBE is being processed!"); + } + else if (type==EXOSIP_SUBSCRIPTION_ANSWERED) + { + sprintf((*je)->textinfo, "2xx received for SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_REDIRECTED) + { + sprintf((*je)->textinfo, "3xx received for SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_REQUESTFAILURE) + { + sprintf((*je)->textinfo, "4xx received for SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_SERVERFAILURE) + { + sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_GLOBALFAILURE) + { + sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!"); + } + else if (type==EXOSIP_SUBSCRIPTION_NOTIFY) + { + sprintf((*je)->textinfo, "NOTIFY request for subscription!"); + } + else if (type==EXOSIP_SUBSCRIPTION_RELEASED) + { + sprintf((*je)->textinfo, "Subscription has terminate!"); + } + else if (type==EXOSIP_IN_SUBSCRIPTION_NEW) + { + sprintf((*je)->textinfo, "New incoming SUBSCRIBE!"); + } + else if (type==EXOSIP_IN_SUBSCRIPTION_RELEASED) + { + sprintf((*je)->textinfo, "Incoming Subscription has terminate!"); + } + else + { + (*je)->textinfo[0] = '\0'; + } + return 0; +} + +void +eXosip_event_free(eXosip_event_t *je) +{ + if (je==NULL) return; + if (je->i_ctt!=NULL) + osip_content_type_free(je->i_ctt); + if (je->i_bodies!=NULL) + { + int pos; + for (pos=0;!osip_list_eol(je->i_bodies, pos);) + { + osip_body_t *body; + body = (osip_body_t *)osip_list_get(je->i_bodies, pos); + osip_list_remove(je->i_bodies, pos); + osip_body_free(body); + } + } + osip_free(je); +} + +eXosip_call_t * +eXosip_event_get_callinfo(eXosip_event_t *je) +{ + return je->jc; +} + +eXosip_dialog_t * +eXosip_event_get_dialoginfo(eXosip_event_t *je) +{ + return je->jd; +} + +eXosip_reg_t * +eXosip_event_get_reginfo(eXosip_event_t *je) +{ + return je->jr; +} + +eXosip_notify_t * +eXosip_event_get_notifyinfo(eXosip_event_t *je) +{ + return je->jn; +} + +eXosip_subscribe_t * +eXosip_event_get_subscribeinfo(eXosip_event_t *je) +{ + return je->js; +} + +int +eXosip_event_add(eXosip_event_t *je) +{ + int i = osip_fifo_add(eXosip.j_events, (void *) je); + osip_cond_signal((struct osip_cond *)eXosip.j_cond); + __eXosip_wakeup_event(); + return i; +} + +#if 0 +#ifdef CLOCK_REALTIME +/* if CLOCK_REALTIME exist, then clock_gettime should be defined */ + +#define OSIP_CLOCK_REALTIME CLOCK_REALTIME + +void +__eXosip_clock_gettime(clockid_t cid, struct timespec *time) +{ + clock_gettime(cid, time); +} + +#elif defined (WIN32) || defined (_WIN32_WCE) + +#include +#include + +#define OSIP_CLOCK_REALTIME 4002 + +void +__eXosip_clock_gettime(unsigned int clock_id, struct timespec *time) +{ + struct _timeb time_val; + + if (clock_id != OSIP_CLOCK_REALTIME) + return; + + _ftime (&time_val); + time->tv_sec = time_val.time; + time->tv_nsec = time_val.millitm * 1000000; + return; +} +#endif +#endif + +eXosip_event_t * +eXosip_event_wait(int tv_s, int tv_ms) +{ + eXosip_event_t *je = NULL; + +#if 0 /* this does not seems to work. by now */ +#if defined (CLOCK_REALTIME) || defined (WIN32) || defined (_WIN32_WCE) + int i; + + struct timespec deadline; + struct timespec interval; + long tot_ms = (tv_s*1000) + tv_ms; + + static struct osip_mutex *mlock = NULL; + + if (mlock==NULL) mlock = osip_mutex_init(); + + je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events); + if(je) return je; + + interval.tv_sec = tot_ms / 1000; + interval.tv_nsec = (tot_ms % 1000) * 1000000L; + + __eXosip_clock_gettime(OSIP_CLOCK_REALTIME, &deadline); + + if ((deadline.tv_nsec += interval.tv_nsec) >= 1000000000L) + { + deadline.tv_nsec -= 1000000000L; + deadline.tv_sec += 1; + } + else + deadline.tv_nsec += interval.tv_nsec; + + deadline.tv_sec += interval.tv_sec; + + i = osip_cond_timedwait ((struct osip_cond *)eXosip.j_cond, + (struct osip_mutex *)mlock, + &deadline); + +#endif +#else + /* basic replacement */ + { + fd_set fdset; + struct timeval tv; + int max, i; + FD_ZERO(&fdset); +#if defined (WIN32) || defined (_WIN32_WCE) + FD_SET((unsigned int)jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset); +#else + FD_SET(jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset); +#endif + max = jpipe_get_read_descr(eXosip.j_socketctl_event); + tv.tv_sec = tv_s; + tv.tv_usec = tv_ms*1000; + + je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events); + if (je!=NULL) return je; + + if (tv_s==0 && tv_ms==0) + return NULL; + + i = select(max+1, &fdset, NULL, NULL, &tv); + if (i <= 0) + return 0; + + if (FD_ISSET (jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset)) + { + char buf[500]; + jpipe_read (eXosip.j_socketctl_event, buf, 499); + } + + je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events); + if (je!=NULL) return je; + } +#endif + + return je; +} + +eXosip_event_t * +eXosip_event_get() +{ + eXosip_event_t *je; + je = (eXosip_event_t *) osip_fifo_get(eXosip.j_events); + return je; +} diff --git a/linphone/exosip/jfreinds.c b/linphone/exosip/jfreinds.c new file mode 100644 index 000000000..0f546cef7 --- /dev/null +++ b/linphone/exosip/jfreinds.c @@ -0,0 +1,311 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +#ifndef EXOSIP_ETC_DIR +#define EXOSIP_ETC_DIR ".eXosip" +#endif + +#ifndef EXOSIP_ADDFRIENDS_SH +#define EXOSIP_ADDFRIENDS_SH "eXosip_addfriend.sh" +#endif + + +static int jfriend_init(jfriend_t **fr, char *ch) +{ + char *next; + int i; + + *fr = (jfriend_t *)osip_malloc(sizeof(jfriend_t)); + if (*fr==NULL) return -1; + + i = jfriend_get_and_set_next_token(&((*fr)->f_nick), ch, &next); + if (i != 0) + goto jf_error1; + osip_clrspace ((*fr)->f_nick); + ch = next; + + i = jfriend_get_and_set_next_token(&((*fr)->f_home), next, &next); + if (i != 0) + goto jf_error2; + osip_clrspace ((*fr)->f_home); + ch = next; + + i = jfriend_get_and_set_next_token(&((*fr)->f_work), ch, &next); + if (i != 0) + goto jf_error3; + osip_clrspace ((*fr)->f_work); + ch = next; + + i = jfriend_get_and_set_next_token(&((*fr)->f_email), ch, &next); + if (i != 0) + goto jf_error4; + osip_clrspace ((*fr)->f_email); + + (*fr)->f_e164 = osip_strdup(next); + osip_clrspace ((*fr)->f_e164); + + return 0; + + jf_error4: + osip_free((*fr)->f_work); + jf_error3: + osip_free((*fr)->f_home); + jf_error2: + osip_free((*fr)->f_nick); + jf_error1: + osip_free(*fr); + *fr = NULL; + return -1; +} + +int +jfriend_get_and_set_next_token (char **dest, char *buf, char **next) +{ + char *end; + char *start; + + *next = NULL; + + /* find first non space and tab element */ + start = buf; + while (((*start == ' ') || (*start == '\t')) && (*start != '\0') + && (*start != '\r') && (*start != '\n') ) + start++; + end = start+1; + while ((*end != '\0') && (*end != '\r') && (*end != '\n') + && (*end != '\t') && (*end != '|')) + end++; + + if ((*end == '\r') || (*end == '\n')) + /* we should continue normally only if this is the separator asked! */ + return -1; + if (end == start) + return -1; /* empty value (or several space!) */ + + *dest = osip_malloc (end - (start) + 1); + osip_strncpy (*dest, start, end - start); + + *next = end + 1; /* return the position right after the separator + */ + return 0; +} + +void __jfriend_remove(char *nickname, char *home) +{ + char *Home; + char command[256]; + char *tmp = command; + int length = 0; + if (nickname!=NULL) + length = strlen(nickname); + + Home = getenv("HOME"); + if (Home==NULL) + return; + length = length + strlen(Home); + osip_clrspace(nickname); + osip_clrspace(home); + + if (home!=NULL) + length = length + strlen(home); + else + return; /* MUST be set */ + length = length + strlen(EXOSIP_ETC_DIR); + + length = length + strlen("/jm_contact"); + if (length>235) /* leave some room for SPACEs and \r\n */ + return ; + + sprintf(tmp , "%s %s/%s/jm_contact", EXOSIP_ADDFRIENDS_SH, + Home, EXOSIP_ETC_DIR); + + tmp = tmp + strlen(tmp); + if (nickname!=NULL) + sprintf(tmp , " %s", nickname); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + if (home!=NULL) + sprintf(tmp , " %s", home); + else + sprintf(tmp , " \"\""); + + sprintf(tmp , "delete"); + + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "%s", command)); + system(command); +} + +void jfriend_add(char *nickname, char *home, + char *work, char *email, char *e164) +{ + char *Home; + char command[256]; + char *tmp = command; + int length = 0; + if (nickname!=NULL) + length = strlen(nickname); + + Home = getenv("HOME"); + if (Home==NULL) + return; + length = length + strlen(Home); + + osip_clrspace(nickname); + osip_clrspace(home); + osip_clrspace(work); + osip_clrspace(email); + osip_clrspace(e164); + + if (home!=NULL) + length = length + strlen(home); + else + return; /* MUST be set */ + if (work!=NULL) + length = length + strlen(work); + if (email!=NULL) + length = length + strlen(email); + if (e164!=NULL) + length = length + strlen(e164); + length = length + strlen(EXOSIP_ETC_DIR); + + length = length + strlen("/jm_contact"); + if (length>235) /* leave some room for SPACEs and \r\n */ + return ; + + sprintf(tmp , "%s %s/%s/jm_contact", EXOSIP_ADDFRIENDS_SH, + Home, EXOSIP_ETC_DIR); + + tmp = tmp + strlen(tmp); + if (nickname!=NULL) + sprintf(tmp , " %s", nickname); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + if (home!=NULL) + sprintf(tmp , " %s", home); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + if (work!=NULL) + sprintf(tmp , " %s", work); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + if (email!=NULL) + sprintf(tmp , " %s", email); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + if (e164!=NULL) + sprintf(tmp , " %s", e164); + else + sprintf(tmp , " \"\""); + + /* fprintf(stderr, "%s", command); */ + system(command); +} + +void +jfriend_unload() +{ + jfriend_t *fr; + if (eXosip.j_friends==NULL) return; + for (fr=eXosip.j_friends; fr!=NULL; fr=eXosip.j_friends) + { + REMOVE_ELEMENT(eXosip.j_friends,fr); + osip_free(fr->f_nick); + osip_free(fr->f_home); + osip_free(fr->f_work); + osip_free(fr->f_email); + osip_free(fr->f_e164); + osip_free(fr); + } + + osip_free(eXosip.j_friends); + eXosip.j_friends=NULL; + return; +} + +int +jfriend_load() +{ + FILE *file; + char *s; + jfriend_t *fr; + int pos; + char *home; + char filename[255]; + + jfriend_unload(); + home = getenv("HOME"); + sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_contact"); + + file = fopen(filename, "r"); + if (file==NULL) return -1; + s = (char *)osip_malloc(255*sizeof(char)); + pos = 0; + while (NULL!=fgets(s, 254, file)) + { + char *tmp = s; + while (*tmp!='\0' && *tmp!=' ') tmp++; + while (*tmp!='\0' && *tmp==' ') tmp++; + while (*tmp!='\0' && *tmp!=' ') tmp++; + tmp++; /* first usefull characters */ + pos++; + + jfriend_init(&fr, tmp); + if (fr!=NULL) + { ADD_ELEMENT(eXosip.j_friends, fr); } + } + osip_free(s); + fclose(file); + + return 0; /* ok */ +} + +char * +jfriend_get_home(int fid) +{ + jfriend_t *fr; + for (fr = eXosip.j_friends; fr!=NULL ; fr=fr->next) + { + if (fid==0) + return osip_strdup(fr->f_home); + fid--; + } + return NULL; +} diff --git a/linphone/exosip/jidentity.c b/linphone/exosip/jidentity.c new file mode 100644 index 000000000..96191e65e --- /dev/null +++ b/linphone/exosip/jidentity.c @@ -0,0 +1,277 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +#ifndef EXOSIP_ETC_DIR +#define EXOSIP_ETC_DIR ".eXosip" +#endif + + +#ifndef EXOSIP_ADDIDENTITYS_SH +#define EXOSIP_ADDIDENTITYS_SH "eXosip_addidentity.sh" +#endif + +static int +jidentity_get_and_set_next_token (char **dest, char *buf, char **next) +{ + char *end; + char *start; + + *next = NULL; + + /* find first non space and tab element */ + start = buf; + while (((*start == ' ') || (*start == '\t')) && (*start != '\0') + && (*start != '\r') && (*start != '\n') ) + start++; + end = start+1; + while ((*end != '\0') && (*end != '\r') && (*end != '\n') + && (*end != '\t') && (*end != '|')) + end++; + + if ((*end == '\r') || (*end == '\n')) + /* we should continue normally only if this is the separator asked! */ + return -1; + if (end == start) + return -1; /* empty value (or several space!) */ + + *dest = osip_malloc (end - (start) + 1); + osip_strncpy (*dest, start, end - start); + + *next = end + 1; /* return the position right after the separator + */ + return 0; +} + +static int jidentity_init(jidentity_t **fr, char *ch) +{ + char *next; + int i; + + *fr = (jidentity_t *)osip_malloc(sizeof(jidentity_t)); + if (*fr==NULL) return -1; + + i = jidentity_get_and_set_next_token(&((*fr)->i_identity), ch, &next); + if (i != 0) + goto ji_error1; + osip_clrspace ((*fr)->i_identity); + ch = next; + + i = jidentity_get_and_set_next_token(&((*fr)->i_registrar), next, &next); + if (i != 0) + goto ji_error2; + osip_clrspace ((*fr)->i_registrar); + ch = next; + + i = jidentity_get_and_set_next_token(&((*fr)->i_realm), ch, &next); + if (i != 0) + goto ji_error3; + osip_clrspace ((*fr)->i_realm); + ch = next; + + i = jidentity_get_and_set_next_token(&((*fr)->i_userid), ch, &next); + if (i != 0) + goto ji_error4; + osip_clrspace ((*fr)->i_userid); + + (*fr)->i_pwd = osip_strdup(next); + osip_clrspace ((*fr)->i_pwd); + + if ((*fr)->i_pwd!=NULL && (*fr)->i_pwd[0]!='\0') + { + eXosip_add_authentication_info((*fr)->i_userid, (*fr)->i_userid, + (*fr)->i_pwd, NULL, + (*fr)->i_realm); + } + return 0; + + ji_error4: + osip_free((*fr)->i_realm); + ji_error3: + osip_free((*fr)->i_registrar); + ji_error2: + osip_free((*fr)->i_identity); + ji_error1: + osip_free(*fr); + *fr = NULL; + return -1; +} + +void identitys_add(char *identity, char *registrar, + char *realm, char *userid, char *pwd) +{ + char command[256]; + char *tmp = command; + char *home; + + int length = 0; + if (identity==NULL) + return ; + if (registrar==NULL) + return ; + + if (realm!=NULL && *realm=='\0') + realm = NULL; + if (userid!=NULL && *userid=='\0') + userid = NULL; + if (pwd!=NULL && *pwd=='\0') + pwd = NULL; + + length = strlen(identity) +3; + length = length + strlen(registrar) +3; + + if (realm!=NULL && userid!=NULL && pwd!=NULL) + { + length = length + strlen(realm) +3; + length = length + strlen(userid) +3; + length = length + strlen(pwd) +3; + } + else if (realm==NULL && userid==NULL && pwd==NULL) + {} + else + return ; + + home = getenv("HOME"); + length = length + strlen(home); + length = length + strlen(EXOSIP_ETC_DIR) + 3; + length = length + strlen("/jm_identity") + 1; + + if (length>235) /* leave some room for SPACEs and \r\n */ + return ; + + sprintf(tmp , "%s \"%s/%s/jm_identity\"", EXOSIP_ADDIDENTITYS_SH, + home, EXOSIP_ETC_DIR); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"%s\"", identity); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"%s\"", registrar); + tmp = tmp + strlen(tmp); + + if (realm!=NULL && userid!=NULL && pwd!=NULL) + { + sprintf(tmp , " \"%s\"", realm); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"%s\"", userid); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"%s\"", pwd); + } + else if (realm==NULL && userid==NULL && pwd==NULL) + { + sprintf(tmp , " \"\""); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"\""); + tmp = tmp + strlen(tmp); + sprintf(tmp , " \"\""); + } + + system(command); +} + +void +jidentity_unload() +{ + jidentity_t *fr; + if (eXosip.j_identitys==NULL) return; + for (fr=eXosip.j_identitys; fr!=NULL; fr=eXosip.j_identitys) + { + REMOVE_ELEMENT(eXosip.j_identitys,fr); + osip_free(fr->i_identity); + osip_free(fr->i_registrar); + osip_free(fr->i_realm); + osip_free(fr->i_userid); + osip_free(fr->i_pwd); + osip_free(fr); + } + + osip_free(eXosip.j_identitys); + eXosip.j_identitys=NULL; + return; +} + +int +jidentity_load() +{ + FILE *file; + char *s; + jidentity_t *fr; + int pos; + char *home; + char filename[255]; + jidentity_unload(); + + home = getenv("HOME"); + sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_identity"); + + file = fopen(filename, "r"); + if (file==NULL) return -1; + s = (char *)osip_malloc(255*sizeof(char)); + pos = 0; + while (NULL!=fgets(s, 254, file)) + { + char *tmp = s; + while (*tmp!='\0' && *tmp!=' ') tmp++; + while (*tmp!='\0' && *tmp==' ') tmp++; + while (*tmp!='\0' && *tmp!=' ') tmp++; + tmp++; /* first usefull characters */ + pos++; + + jidentity_init(&fr, tmp); + if (fr!=NULL) + { ADD_ELEMENT(eXosip.j_identitys, fr); } + } + osip_free(s); + fclose(file); + + return 0; /* ok */ +} + +char * +jidentity_get_registrar(int fid) +{ + jidentity_t *fr; + for (fr = eXosip.j_identitys; fr!=NULL ; fr=fr->next) + { + if (fid==0) + return osip_strdup(fr->i_registrar); + fid--; + } + return NULL; +} + +char * +jidentity_get_identity(int fid) +{ + jidentity_t *fr; + for (fr = eXosip.j_identitys; fr!=NULL ; fr=fr->next) + { + if (fid==0) + return osip_strdup(fr->i_identity); + fid--; + } + return NULL; +} diff --git a/linphone/exosip/jnotify.c b/linphone/exosip/jnotify.c new file mode 100644 index 000000000..f784ed884 --- /dev/null +++ b/linphone/exosip/jnotify.c @@ -0,0 +1,528 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +#if 0 +int eXosip_notify_find(int sid, eXosip_notify_t **jn) +{ + for (*jn=eXosip.j_notifies; *jn!=NULL; *jn=(*jn)->next) + { + if ((*jn)->n_id==sid) + return 0; + } + *jn = NULL; + return -1; +} +#endif + +osip_transaction_t * +eXosip_find_last_inc_subscribe(eXosip_notify_t *jn, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "SUBSCRIBE")) + break; + else inc_tr = NULL; + pos++; + } + } + else + inc_tr = NULL; + + if (inc_tr==NULL) + return jn->n_inc_tr; /* can be NULL */ + + return inc_tr; +} + + +osip_transaction_t * +eXosip_find_last_out_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "NOTIFY")) + return out_tr; + pos++; + } + } + + return NULL; +} + +int +eXosip_notify_init(eXosip_notify_t **jn, osip_message_t *inc_subscribe) +{ + osip_contact_t *co; + char *uri; + int i; +#ifdef SM + char *locip; + eXosip_get_localip_from_via(inc_subscribe,&locip); +#else + char locip[50]; + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + if (inc_subscribe==NULL + ||inc_subscribe->to==NULL + ||inc_subscribe->to->url==NULL) + return -1; + co = (osip_contact_t *) osip_list_get(inc_subscribe->contacts, 0); + if (co==NULL || co->url==NULL) + return -1; + + *jn = (eXosip_notify_t *)osip_malloc(sizeof(eXosip_notify_t)); + if (*jn == NULL) return -1; + memset(*jn, 0, sizeof(eXosip_notify_t)); + + i = osip_uri_to_str(co->url, &uri); + if (i!=0) + { + osip_free(*jn); + *jn=NULL; + return -1; + } + osip_strncpy((*jn)->n_uri, uri, 254); + osip_free(uri); + + if (inc_subscribe->to->url->username!=NULL) + { + /* SM: allocate a string instead of risking a buffer overflow */ + if (eXosip.localport==NULL) + (*jn)->n_contact_info=strdup_printf("sip:%s@%s", + inc_subscribe->to->url->username, + locip); + else + (*jn)->n_contact_info= strdup_printf("sip:%s@%s:%s", + inc_subscribe->to->url->username, + locip, eXosip.localport); + } + else + { + if (eXosip.localport==NULL) + (*jn)->n_contact_info=strdup_printf("sip:%s", locip); + else + (*jn)->n_contact_info=strdup_printf("sip:%s:%s", locip, + eXosip.localport); + } + +#ifdef SM + osip_free(locip); +#endif + return 0; +} + +#if 0 +void +__eXosip_notify_remove_dialog_reference_in_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd) +{ + eXosip_dialog_t *_jd; + jinfo_t *ji; + if (jn==NULL) return; + if (jd==NULL) return; + + for (_jd = jn->n_dialogs; _jd!=NULL; _jd=jn->n_dialogs) + { + if (jd==_jd) + break; + } + if (_jd==NULL) + { + /* dialog not found??? */ + } + + ji = osip_transaction_get_your_instance(jn->n_inc_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; + ji = osip_transaction_get_your_instance(jn->n_out_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; +} +#endif + +void +eXosip_notify_free(eXosip_notify_t *jn) +{ + /* ... */ + + eXosip_dialog_t *jd; + + for (jd = jn->n_dialogs; jd!=NULL; jd=jn->n_dialogs) + { + REMOVE_ELEMENT(jn->n_dialogs, jd); + eXosip_dialog_free(jd); + } + + __eXosip_delete_jinfo(jn->n_inc_tr); + __eXosip_delete_jinfo(jn->n_out_tr); + if (jn->n_inc_tr!=NULL) + osip_list_add(eXosip.j_transactions, jn->n_inc_tr, 0); + if (jn->n_out_tr!=NULL) + osip_list_add(eXosip.j_transactions, jn->n_out_tr, 0); + if (jn->n_contact_info!=NULL) osip_free(jn->n_contact_info); + osip_free(jn); +} + +int +_eXosip_notify_set_refresh_interval(eXosip_notify_t *jn, + osip_message_t *inc_subscribe) +{ + osip_header_t *exp; + int now; + now = time(NULL); + if (jn==NULL || inc_subscribe==NULL) + return -1; + + osip_message_get_expires(inc_subscribe, 0, &exp); + if (exp==NULL || exp->hvalue==NULL) + jn->n_ss_expires = now + 600; + else + { + jn->n_ss_expires = osip_atoi(exp->hvalue); + if (jn->n_ss_expires!=-1) + jn->n_ss_expires = now + jn->n_ss_expires; + else /* on error, set it to default */ + jn->n_ss_expires = now + 600; + } + + return 0; +} + +int +eXosip_notify_add_allowed_subscriber(char *sip_url) +{ + /* TODO */ + return -1; +} + +int +_eXosip_notify_is_a_known_subscriber(osip_message_t *sip) +{ + /* */ + return -1; +} + + +int +_eXosip_notify_add_body(eXosip_notify_t *jn, osip_message_t *notify) +{ + char buf[1000]; +#ifdef SUPPORT_MSN + int atom_id = 1000; +#endif + if (jn->n_ss_status!=EXOSIP_SUBCRSTATE_ACTIVE + || jn->n_contact_info==NULL || jn->n_contact_info=='\0') /* mandatory! */ + return 0; /* don't need a body? */ + +#ifdef SUPPORT_MSN + + if (jn->n_online_status==EXOSIP_NOTIFY_ONLINE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +

\n\ +\n\ +\n\ +
\n\ +\n\ +", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else if (jn->n_online_status==EXOSIP_NOTIFY_BUSY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else if (jn->n_online_status==EXOSIP_NOTIFY_BERIGHTBACK) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else if (jn->n_online_status==EXOSIP_NOTIFY_AWAY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else if (jn->n_online_status==EXOSIP_NOTIFY_ONTHEPHONE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else if (jn->n_online_status==EXOSIP_NOTIFY_OUTTOLUNCH) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + + } + else + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ +\n\ +\n\ +
\n\ +
\n\ +
", jn->n_contact_info, atom_id, jn->n_contact_info); + } + + osip_message_set_body(notify, buf, strlen(buf)); + osip_message_set_content_type(notify, "application/xpidf+xml"); +#else + + if (jn->n_online_status==EXOSIP_NOTIFY_ONLINE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ +%s\n\ +online\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else if (jn->n_online_status==EXOSIP_NOTIFY_BUSY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + busy\n\ +\n\ +\n\ +%s\n\ +busy\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else if (jn->n_online_status==EXOSIP_NOTIFY_BERIGHTBACK) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + in-transit\n\ +\n\ +\n\ +%s\n\ +be right back\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else if (jn->n_online_status==EXOSIP_NOTIFY_AWAY) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + away\n\ +\n\ +\n\ +%s\n\ +away\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else if (jn->n_online_status==EXOSIP_NOTIFY_ONTHEPHONE) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + on-the-phone\n\ +\n\ +\n\ +%s\n\ +on the phone\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else if (jn->n_online_status==EXOSIP_NOTIFY_OUTTOLUNCH) + { + sprintf(buf, "\n\ +\n\ +\n\ +\n\ +open\n\ +\n\ + meal\n\ +\n\ +\n\ +%s\n\ +out to lunch\n\ +\n\ +", + jn->n_contact_info, jn->n_contact_info); + } + else + { + /* */ + sprintf(buf, "\n\ +\n%s", + jn->n_contact_info, +"\n\ +\n\ +closed\n\ +\n\ + permanent-absence\n\ +\n\ +\n\ +\n\ +\n\n"); + } + osip_message_set_body(notify, buf, strlen(buf)); + osip_message_set_content_type(notify, "application/pidf+xml"); + +#endif + + return 0; +} + +void +_eXosip_notify_add_expires_in_2XX_for_subscribe(eXosip_notify_t *jn, osip_message_t *answer) +{ + char tmp[20]; + int now; + now = time(NULL); + + if (jn->n_ss_expires-now<0) + { + tmp[0] = '0'; + tmp[1] = '\0'; + } + else + { + sprintf(tmp, "%i", jn->n_ss_expires-now); + } + osip_message_set_expires(answer, tmp); +} diff --git a/linphone/exosip/jpipe.c b/linphone/exosip/jpipe.c new file mode 100644 index 000000000..a91987dc6 --- /dev/null +++ b/linphone/exosip/jpipe.c @@ -0,0 +1,221 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "jpipe.h" + +#ifndef WIN32 + +jpipe_t * jpipe () +{ + jpipe_t *my_pipe = (jpipe_t *) osip_malloc (sizeof (jpipe_t)); + if (my_pipe==NULL) return NULL; + + if (0 != pipe (my_pipe->pipes)) + { + osip_free (my_pipe); + return NULL; + } + return my_pipe; +} + +int jpipe_close (jpipe_t * apipe) +{ + if (apipe == NULL) + return -1; + close (apipe->pipes[0]); + close (apipe->pipes[1]); + osip_free (apipe); + return 0; +} + + +/** + * Write in a pipe. + */ +int +jpipe_write (jpipe_t * apipe, const void *buf, int count) +{ + if (apipe == NULL) + return -1; + return write (apipe->pipes[1], buf, count); +} + +/** + * Read in a pipe. + */ +int jpipe_read (jpipe_t * apipe, void *buf, int count) +{ + if (apipe == NULL) + return -1; + return read (apipe->pipes[0], buf, count); +} + +/** + * Get descriptor of reading pipe. + */ +int jpipe_get_read_descr (jpipe_t * apipe) +{ + if (apipe == NULL) + return -1; + return apipe->pipes[0]; +} + +#else + +jpipe_t * jpipe () +{ + int s = 0; + int timeout = 0; + static int aport = 10500; + struct sockaddr_in raddr; + int j; + + jpipe_t *my_pipe = (jpipe_t *) osip_malloc (sizeof (jpipe_t)); + if (my_pipe==NULL) + return NULL; + + s = (int) socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > s) + { + osip_free (my_pipe); + return NULL; + } + my_pipe->pipes[1] = (int) socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > my_pipe->pipes[1]) + { + closesocket(s); + osip_free (my_pipe); + return NULL; + } + + raddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); + raddr.sin_family = AF_INET; + + j = 50; + while (aport++ && j-- > 0) + { + raddr.sin_port = htons ((short) aport); + if (bind (s, (struct sockaddr *) &raddr, sizeof (raddr)) < 0) + { + OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, + "Failed to bind one local socket %i!\n", + aport)); + } + else + break; + } + + if (j == 0) + { + OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Failed to bind a local socket, aborting!\n")); + closesocket (s); + closesocket (my_pipe->pipes[1]); + osip_free (my_pipe); + } + + j = listen(s,1); + if (j != 0) + { + OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, + "Failed to listen on a local socket, aborting!\n")); + closesocket(s); + closesocket(my_pipe->pipes[1]); + osip_free (my_pipe); + } + + j = setsockopt (my_pipe->pipes[1], + SOL_SOCKET, + SO_RCVTIMEO, (const char*) &timeout, sizeof (timeout)); + if (j != NO_ERROR) + { + /* failed for some reason... */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "udp plugin; cannot set O_NONBLOCK to the file desciptor!\n")); + closesocket(s); + closesocket(my_pipe->pipes[1]); + osip_free (my_pipe); + } + + connect (my_pipe->pipes[1], (struct sockaddr *) &raddr, sizeof (raddr)); + + my_pipe->pipes[0] = accept (s, NULL, NULL); + + if (my_pipe->pipes[0]<=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "udp plugin; Failed to call accept!\n")); + closesocket(s); + closesocket(my_pipe->pipes[1]); + osip_free (my_pipe); + } + + return my_pipe; +} + +int jpipe_close (jpipe_t * apipe) +{ + if (apipe == NULL) + return -1; + closesocket (apipe->pipes[0]); + closesocket (apipe->pipes[1]); + osip_free (apipe); + return 0; +} + + +/** + * Write in a pipe. + */ +int +jpipe_write (jpipe_t * apipe, const void *buf, int count) +{ + if (apipe == NULL) + return -1; + return send (apipe->pipes[1], buf, count, 0); +} + +/** + * Read in a pipe. + */ +int jpipe_read (jpipe_t * apipe, void *buf, int count) +{ + if (apipe == NULL) + return -1; + return recv (apipe->pipes[0], buf, count, 0 /* MSG_DONTWAIT */ ); /* BUG?? */ +} + +/** + * Get descriptor of reading pipe. + */ +int jpipe_get_read_descr (jpipe_t * apipe) +{ + if (apipe == NULL) + return -1; + return apipe->pipes[0]; +} + +#endif diff --git a/linphone/exosip/jpipe.h b/linphone/exosip/jpipe.h new file mode 100644 index 000000000..3870cefd8 --- /dev/null +++ b/linphone/exosip/jpipe.h @@ -0,0 +1,111 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _JPIPE_H_ +#define _JPIPE_H_ + +#include + +#ifndef WIN32 +#ifdef HAVE_UNISTD_H +#include +#endif +#endif + +#ifdef WIN32 +#include +#endif + +/** + * @file jpipe.h + * @brief PPL Pipe Handling Routines + */ + +/** + * @defgroup JPIPE Pipe Handling + * @ingroup PPL + * @{ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef WIN32 + +/** + * Structure for storing a pipe descriptor + * @defvar jpipe_t + */ + typedef struct jpipe_t jpipe_t; + + struct jpipe_t + { + int pipes[2]; + }; + +#else + +/** + * Structure for storing a pipe descriptor + * @defvar ppl_pipe_t + */ + typedef struct jpipe_t jpipe_t; + + struct jpipe_t + { + int pipes[2]; + }; + +#endif + +/** + * Get New pipe pair. + */ + jpipe_t * jpipe (void); + +/** + * Close pipe + */ + int jpipe_close (jpipe_t * apipe); + +/** + * Write in a pipe. + */ + int jpipe_write (jpipe_t * pipe, const void *buf, + int count); + +/** + * Read in a pipe. + */ + int jpipe_read (jpipe_t * pipe, void *buf, + int count); + +/** + * Get descriptor of reading pipe. + */ + int jpipe_get_read_descr (jpipe_t * pipe); + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif diff --git a/linphone/exosip/jpublish.c b/linphone/exosip/jpublish.c new file mode 100644 index 000000000..a309ace8c --- /dev/null +++ b/linphone/exosip/jpublish.c @@ -0,0 +1,118 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" + +extern eXosip_t eXosip; + +int _eXosip_pub_update(eXosip_pub_t **pub, osip_transaction_t *tr, osip_message_t *answer) +{ + eXosip_pub_t *jpub; + + *pub = NULL; + + for (jpub = eXosip.j_pub; jpub!=NULL; jpub = jpub->next) + { + if (jpub->p_last_tr==NULL) + { /*bug? */ } + else if (tr==jpub->p_last_tr) + { + /* update the sip_etag parameter */ + if (answer==NULL) + { /* bug? */ + } + else if (MSG_IS_STATUS_2XX(answer)) + { + osip_header_t *sip_etag=NULL; + osip_message_header_get_byname(answer, "SIP-ETag", 0, &sip_etag); + if (sip_etag!=NULL && sip_etag->hvalue!=NULL) + snprintf(jpub->p_sip_etag, 64, "%s", sip_etag->hvalue); + } + *pub=jpub; + return 0; + } + } + return -1; +} + +int _eXosip_pub_find_by_aor(eXosip_pub_t **pub, const char *aor) +{ + eXosip_pub_t *jpub; + eXosip_pub_t *ptr; + time_t now; + + *pub = NULL; + + /* delete expired publications */ + now = time(NULL); + ptr = eXosip.j_pub; + for (jpub = ptr; jpub!=NULL; jpub = ptr) + { + ptr = jpub->next; + if (now-jpub->p_expires>60) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_WARNING, NULL, + "eXosip: removing expired publication!")); + REMOVE_ELEMENT(eXosip.j_pub, jpub); + _eXosip_pub_free(jpub); + } + } + + for (jpub = eXosip.j_pub; jpub!=NULL; jpub = jpub->next) + { + if (osip_strcasecmp(aor, jpub->p_aor)==0) + { + *pub=jpub; + return 0; + } + } + return -1; +} + +int _eXosip_pub_init(eXosip_pub_t **pub, const char *aor, const char *exp) +{ + eXosip_pub_t *jpub; + + *pub = NULL; + + jpub = (eXosip_pub_t*) osip_malloc(sizeof(eXosip_pub_t)); + if (jpub==0) + return -1; + memset(jpub, 0, sizeof(eXosip_pub_t)); + snprintf(jpub->p_aor, 256, "%s", aor); + + jpub->p_expires = atoi(exp) + time(NULL); + jpub->p_period = atoi(exp); + + *pub = jpub; + return 0; +} + +void _eXosip_pub_free(eXosip_pub_t *pub) +{ + if (pub->p_last_tr!=NULL) + osip_list_add(eXosip.j_transactions, pub->p_last_tr, 0); + osip_free(pub); +} + diff --git a/linphone/exosip/jreg.c b/linphone/exosip/jreg.c new file mode 100644 index 000000000..fc16c0a1e --- /dev/null +++ b/linphone/exosip/jreg.c @@ -0,0 +1,106 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" + +extern eXosip_t eXosip; + +int eXosip_reg_init(eXosip_reg_t **jr, char *from, char *proxy, char *contact, char* route) +{ + static int r_id; + + *jr = (eXosip_reg_t*) osip_malloc(sizeof(eXosip_reg_t)); + if (*jr==NULL) return -1; + + if (r_id > 1000000) /* keep it non-negative */ + r_id = 0; + + (*jr)->r_id = ++r_id; + (*jr)->r_reg_period = 3600; /* delay between registration */ + (*jr)->r_aor = osip_strdup(from); /* sip identity */ + (*jr)->r_contact = osip_strdup(contact); /* sip identity */ + (*jr)->r_registrar = osip_strdup(proxy); /* registrar */ + (*jr)->r_route = osip_strdup(route); /* outbound proxy */ +#if 0 + (*jr)->r_realms = NULL; /* list of realms */ +#endif + (*jr)->r_last_tr = NULL; + + (*jr)->next = NULL; + (*jr)->parent = NULL; + return 0; +} + +void eXosip_reg_free(eXosip_reg_t *jreg) +{ + + osip_free(jreg->r_aor); + osip_free(jreg->r_contact); + osip_free(jreg->r_registrar); +#if 0 + osip_free(jreg->r_realms); +#endif + + if (jreg->r_last_tr != NULL) + { + if (jreg->r_last_tr->state==IST_TERMINATED || + jreg->r_last_tr->state==ICT_TERMINATED || + jreg->r_last_tr->state== NICT_TERMINATED || + jreg->r_last_tr->state==NIST_TERMINATED) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Release a terminated transaction\n")); + __eXosip_delete_jinfo(jreg->r_last_tr); + if (jreg->r_last_tr!=NULL) + osip_list_add(eXosip.j_transactions, jreg->r_last_tr, 0); + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Release a non-terminated transaction\n")); + __eXosip_delete_jinfo(jreg->r_last_tr); + if (jreg->r_last_tr!=NULL) + osip_list_add(eXosip.j_transactions, jreg->r_last_tr, 0); + } + } + + osip_free(jreg); +} + +int _eXosip_reg_find(eXosip_reg_t **reg, osip_transaction_t *tr) +{ + eXosip_reg_t *jreg; + *reg = NULL; + if (tr==NULL) return -1; + + for (jreg = eXosip.j_reg; jreg!=NULL; jreg = jreg->next) + { + if (jreg->r_last_tr==tr) + { + *reg = jreg; + return 0; + } + } + return -1; +} diff --git a/linphone/exosip/jrequest.c b/linphone/exosip/jrequest.c new file mode 100644 index 000000000..854c18782 --- /dev/null +++ b/linphone/exosip/jrequest.c @@ -0,0 +1,1158 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" + +#ifndef WIN32 +#include +#include +#include +#include +#ifdef __APPLE_CC__ +#include +#endif +#else +#include +#include +#endif + +extern eXosip_t eXosip; + +/* Private functions */ +static int generating_request_out_of_dialog(osip_message_t **dest, + char *method_name, char *to, + char *transport, char *from, + char *proxy); +static int dialog_fill_route_set(osip_dialog_t *dialog, + osip_message_t *request); + +/* should use cryptographically random identifier is RECOMMENDED.... */ +/* by now this should lead to identical call-id when application are + started at the same time... */ +char * +osip_call_id_new_random() +{ + char *tmp = (char *)osip_malloc(33); + unsigned int number = osip_build_random_number(); + sprintf(tmp,"%u",number); + return tmp; +} + +char * +osip_from_tag_new_random(void) +{ + return osip_call_id_new_random(); +} + +char * +osip_to_tag_new_random(void) +{ + return osip_call_id_new_random(); +} + +unsigned int +via_branch_new_random(void) +{ + return osip_build_random_number(); +} + +/* prepare a minimal request (outside of a dialog) with required headers */ +/* + method_name is the type of request. ("INVITE", "REGISTER"...) + to is the remote target URI + transport is either "TCP" or "UDP" (by now, only UDP is implemented!) +*/ +static int +generating_request_out_of_dialog(osip_message_t **dest, char *method_name, + char *to, char *transport, char *from, + char *proxy) +{ + /* Section 8.1: + A valid request contains at a minimum "To, From, Call-iD, Cseq, + Max-Forwards and Via + */ + int i; + osip_message_t *request; +#ifdef SM + char *locip=NULL; +#else + char locip[50]; +#endif + int doing_register; + char *register_callid_number = NULL; + + i = osip_message_init(&request); + if (i!=0) return -1; + + /* prepare the request-line */ + osip_message_set_method(request, osip_strdup(method_name)); + osip_message_set_version(request, osip_strdup("SIP/2.0")); + osip_message_set_status_code(request, 0); + osip_message_set_reason_phrase(request, NULL); + + doing_register = 0==strcmp("REGISTER", method_name); + + if (doing_register) + { + osip_uri_init(&(request->req_uri)); + i = osip_uri_parse(request->req_uri, proxy); + if (i!=0) + { + goto brood_error_1; + } + osip_message_set_to(request, from); + } + else + { + /* in any cases except REGISTER: */ + i = osip_message_set_to(request, to); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "ERROR: callee address does not seems to be a sipurl: %s\n", to)); + goto brood_error_1; + } + if (proxy!=NULL && proxy[0] != 0) + { /* equal to a pre-existing route set */ + /* if the pre-existing route set contains a "lr" (compliance + with bis-08) then the req_uri should contains the remote target + URI */ + osip_uri_param_t *lr_param; + osip_route_t *o_proxy; +#ifndef __VXWORKS_OS__ + osip_route_init(&o_proxy); +#else + osip_route_init2(&o_proxy); +#endif + i = osip_route_parse(o_proxy, proxy); + if (i!=0) { + osip_route_free(o_proxy); + goto brood_error_1; + } + + osip_uri_uparam_get_byname(o_proxy->url, "lr", &lr_param); + if (lr_param!=NULL) /* to is the remote target URI in this case! */ + { + osip_uri_clone(request->to->url, &(request->req_uri)); + /* "[request] MUST includes a Route header field containing + the route set values in order." */ + osip_list_add(request->routes, o_proxy, 0); + } + else + /* if the first URI of route set does not contain "lr", the req_uri + is set to the first uri of route set */ + { + request->req_uri = o_proxy->url; + o_proxy->url = NULL; + osip_route_free(o_proxy); + /* add the route set */ + /* "The UAC MUST add a route header field containing + the remainder of the route set values in order. + The UAC MUST then place the remote target URI into + the route header field as the last value + */ + osip_message_set_route(request, to); + } + } + else /* No route set (outbound proxy) is used */ + { + /* The UAC must put the remote target URI (to field) in the req_uri */ + i = osip_uri_clone(request->to->url, &(request->req_uri)); + if (i!=0) goto brood_error_1; + } + } + /*guess the local ip since req uri is known */ +#ifdef SM + { + eXosip_get_localip_for(request->req_uri->host,&locip); + } +#else + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + /* set To and From */ + osip_message_set_from(request, from); + /* add a tag */ + osip_from_set_tag(request->from, osip_from_tag_new_random()); + + /* set the cseq and call_id header */ + { + osip_call_id_t *callid; + osip_cseq_t *cseq; + char *num; + char *cidrand; + + /* call-id is always the same for REGISTRATIONS */ + i = osip_call_id_init(&callid); + if (i!=0) goto brood_error_1; + cidrand = osip_call_id_new_random(); + osip_call_id_set_number(callid, cidrand); + if (doing_register) + register_callid_number = cidrand; + + osip_call_id_set_host(callid, osip_strdup(locip)); + request->call_id = callid; + + i = osip_cseq_init(&cseq); + if (i!=0) goto brood_error_1; + num = osip_strdup(doing_register ? "1" : "20" ); + osip_cseq_set_number(cseq, num); + osip_cseq_set_method(cseq, osip_strdup(method_name)); + request->cseq = cseq; + } + + /* always add the Max-Forward header */ + osip_message_set_max_forwards(request, "70"); /* a UA should start a request with 70 */ + +#define MASQUERADE_VIA +#ifdef MASQUERADE_VIA + /* should be useless with compliant UA */ + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = request->req_uri->host; + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, request->req_uri->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + if (eXosip_is_public_address(c_address)) + { + char tmp[200]; + snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + eXosip.j_firewall_ip, + eXosip.localport, + via_branch_new_random() ); + osip_message_set_via(request, tmp); + } + else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + snprintf(tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + else + snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + osip_message_set_via(request, tmp); + } + } + else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + snprintf(tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + else + snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + osip_message_set_via(request, tmp); + } + +#else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + spnrintf(tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + else + spnrintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + + osip_message_set_via(request, tmp); + } +#endif + + /* add specific headers for each kind of request... */ + + if (0==strcmp("INVITE", method_name) || 0==strcmp("SUBSCRIBE", method_name)) + { + char *contact; + osip_from_t *a_from; + int i; + i = osip_from_init(&a_from); + if (i==0) + i = osip_from_parse(a_from, from); + + if (i==0 && a_from!=NULL + && a_from->url!=NULL && a_from->url->username!=NULL ) + { + contact = (char *) osip_malloc(50+strlen(a_from->url->username)); + + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = request->req_uri->host; + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, request->req_uri->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + if (eXosip_is_public_address(c_address)) + { + if (eXosip.localport==NULL) + sprintf(contact, "", a_from->url->username, + eXosip.j_firewall_ip); + else + sprintf(contact, "", a_from->url->username, + eXosip.j_firewall_ip, + eXosip.localport); + } + else + { + if (eXosip.localport==NULL) + sprintf(contact, "", a_from->url->username, + locip); + else + sprintf(contact, "", a_from->url->username, + locip, + eXosip.localport); + } + } + else + { + if (eXosip.localport==NULL) + sprintf(contact, "", a_from->url->username, + locip); + else + sprintf(contact, "", a_from->url->username, + locip, + eXosip.localport); + } + osip_message_set_contact(request, contact); + osip_free(contact); + } + osip_from_free(a_from); + + /* This is probably useless for other messages */ + osip_message_set_allow(request, "INVITE"); + osip_message_set_allow(request, "ACK"); + osip_message_set_allow(request, "CANCEL"); + osip_message_set_allow(request, "BYE"); + osip_message_set_allow(request, "OPTIONS"); + osip_message_set_allow(request, "REFER"); + osip_message_set_allow(request, "SUBSCRIBE"); + osip_message_set_allow(request, "NOTIFY"); + osip_message_set_allow(request, "MESSAGE"); + } + + if (0==strcmp("SUBSCRIBE", method_name)) + { + osip_message_set_header(request, "Event", "presence"); +#ifdef SUPPORT_MSN + osip_message_set_accept(request, "application/xpidf+xml"); +#else + osip_message_set_accept(request, "application/pidf+xml"); +#endif + } + else if (0==strcmp("REGISTER", method_name)) + { + } + else if (0==strcmp("INFO", method_name)) + { + } + else if (0==strcmp("OPTIONS", method_name)) + { + osip_message_set_accept(request, "application/sdp"); + } + + osip_message_set_user_agent(request, eXosip.user_agent); + /* else if ... */ + *dest = request; +#ifdef SM + osip_free(locip); +#endif + return 0; + + brood_error_1: + osip_message_free(request); + *dest = NULL; +#ifdef SM + if (locip!=NULL) osip_free(locip); +#endif + return -1; +} + +int +generating_register(osip_message_t **reg, char *from, + char *proxy, char *contact, int expires) +{ + osip_from_t *a_from; + osip_via_t *via; + int i; + char * locip; + + i = generating_request_out_of_dialog(reg, "REGISTER", NULL, "UDP", + from, proxy); + if (i!=0) return -1; + + /*get the local ip from the via already established by generating_request_out_of_dialog */ + if (osip_message_get_via((*reg),0,&via)==0){ + locip=via->host; + }else return -1; + + if (contact==NULL) + { + i = osip_from_init(&a_from); + if (i==0) + i = osip_from_parse(a_from, from); + + if (i==0 && a_from!=NULL + && a_from->url!=NULL && a_from->url->username!=NULL ) + { + contact = (char *) osip_malloc(50+strlen(a_from->url->username)); + + if (eXosip.ip_family==AF_INET6) + sprintf(contact, "", a_from->url->username, + locip, + eXosip.localport!=NULL ? eXosip.localport : "5060"); + else + sprintf(contact, "", a_from->url->username, + locip, + eXosip.localport!=NULL ? eXosip.localport : "5060"); + osip_message_set_contact(*reg, contact); + osip_free(contact); + } + osip_from_free(a_from); + } + else + { + osip_message_set_contact(*reg, contact); + } + + { + char exp[10]; /* MUST never be ouside 1 and 3600 */ + snprintf(exp, 9, "%i", expires); + osip_message_set_expires(*reg, exp); + } + + osip_message_set_content_length(*reg, "0"); + + return 0; +} + +/* this method can't be called unless the previous + INVITE transaction is over. */ +int eXosip_build_initial_invite(osip_message_t **invite, char *to, char *from, + char *route, char *subject) +{ + int i; + + if (to!=NULL && *to=='\0') + return -1; + + osip_clrspace(to); + osip_clrspace(subject); + osip_clrspace(from); + osip_clrspace(route); + if (route!=NULL && *route=='\0') + route=NULL; + if (subject!=NULL && *subject=='\0') + subject=NULL; + + i = generating_request_out_of_dialog(invite, "INVITE", to, "UDP", from, + route); + if (i!=0) return -1; + +#if 0 + if (subject==NULL) + osip_message_set_subject(*invite, "New Call"); + else + osip_message_set_subject(*invite, subject); +#else + if (subject!=NULL) + osip_message_set_subject(*invite, subject); +#endif + + /* after this delay, we should send a CANCEL */ + osip_message_set_expires(*invite, "120"); + + /* osip_message_set_organization(*invite, "Jack's Org"); */ + return 0; +} + +/* this method can't be called unless the previous + INVITE transaction is over. */ +int eXosip_build_initial_options(osip_message_t **options, char *to, char *from, + char *route) +{ + int i; + + if (to!=NULL && *to=='\0') + return -1; + + osip_clrspace(to); + osip_clrspace(from); + osip_clrspace(route); + if (route!=NULL && *route=='\0') + route=NULL; + + i = generating_request_out_of_dialog(options, "OPTIONS", to, "UDP", from, + route); + if (i!=0) return -1; + + /* after this delay, we should send a CANCEL */ + osip_message_set_expires(*options, "120"); + + /* osip_message_set_organization(*invite, "Jack's Org"); */ + return 0; +} + +/* this method can't be called unless the previous + INVITE transaction is over. */ +int generating_initial_subscribe(osip_message_t **subscribe, char *to, + char *from, char *route) +{ + int i; + + if (to!=NULL && *to=='\0') + return -1; + + osip_clrspace(to); + osip_clrspace(from); + osip_clrspace(route); + if (route!=NULL && *route=='\0') + route=NULL; + + i = generating_request_out_of_dialog(subscribe, "SUBSCRIBE", to, "UDP", from, + route); + if (i!=0) return -1; + +#ifdef LOW_EXPIRE + osip_message_set_expires(*subscribe, "120"); +#else + osip_message_set_expires(*subscribe, "3600"); +#endif + + /* osip_message_set_organization(*subscribe, "Jack's Org"); */ + return 0; +} + +/* this method can't be called unless the previous + INVITE transaction is over. */ +int generating_message(osip_message_t **message, char *to, char *from, + char *route, char *buff) +{ + int i; + + if (to!=NULL && *to=='\0') + return -1; + + osip_clrspace(to); + /* osip_clrspace(buff); */ + osip_clrspace(from); + osip_clrspace(route); + if (route!=NULL && *route=='\0') + route=NULL; + if (buff!=NULL && *buff=='\0') + return -1; /* at least, the message must be of length >= 1 */ + + i = generating_request_out_of_dialog(message, "MESSAGE", to, "UDP", from, + route); + if (i!=0) return -1; + + osip_message_set_expires(*message, "120"); + osip_message_set_body(*message, buff, strlen(buff)); + osip_message_set_content_type(*message, "text/plain"); + + /* osip_message_set_organization(*message, "Jack's Org"); */ + + + return 0; +} + +/* this method can't be called unless the previous + INVITE transaction is over. */ +int +generating_publish(osip_message_t **message, char *to, char *from, + char *route) +{ + int i; + + if (to!=NULL && *to=='\0') + return -1; + + osip_clrspace(to); + osip_clrspace(from); + osip_clrspace(route); + if (route!=NULL && *route=='\0') + route=NULL; + + i = generating_request_out_of_dialog(message, "PUBLISH", to, "UDP", from, + route); + if (i!=0) return -1; + + /* osip_message_set_organization(*message, "Jack's Org"); */ + + return 0; +} + + +int +generating_options(osip_message_t **options, char *from, char *to, char *proxy) +{ + int i; + i = generating_request_out_of_dialog(options, "OPTIONS", to, "UDP", + from, proxy); + if (i!=0) return -1; + +#if 0 + if (sdp!=NULL) + { + osip_message_set_content_type(*options, "application/sdp"); + osip_message_set_body(*options, sdp); + } +#endif + + return 0; +} + +int +generating_info(osip_message_t **info, char *from, char *to, char *proxy) +{ + int i; + i = generating_request_out_of_dialog(info, "INFO", to, "UDP", + from, proxy); + if (i!=0) return -1; + return 0; +} + + +static int +dialog_fill_route_set(osip_dialog_t *dialog, osip_message_t *request) +{ + /* if the pre-existing route set contains a "lr" (compliance + with bis-08) then the req_uri should contains the remote target + URI */ + int i; + int pos=0; + osip_uri_param_t *lr_param; + osip_route_t *route; + char *last_route; + /* AMD bug: fixed 17/06/2002 */ + + if (dialog->type==CALLER) + { + pos = osip_list_size(dialog->route_set)-1; + route = (osip_route_t*)osip_list_get(dialog->route_set, pos); + } + else + route = (osip_route_t*)osip_list_get(dialog->route_set, 0); + + osip_uri_uparam_get_byname(route->url, "lr", &lr_param); + if (lr_param!=NULL) /* the remote target URI is the req_uri! */ + { + i = osip_uri_clone(dialog->remote_contact_uri->url, + &(request->req_uri)); + if (i!=0) return -1; + /* "[request] MUST includes a Route header field containing + the route set values in order." */ + /* AMD bug: fixed 17/06/2002 */ + pos=0; /* first element is at index 0 */ + while (!osip_list_eol(dialog->route_set, pos)) + { + osip_route_t *route2; + route = osip_list_get(dialog->route_set, pos); + i = osip_route_clone(route, &route2); + if (i!=0) return -1; + if (dialog->type==CALLER) + osip_list_add(request->routes, route2, 0); + else + osip_list_add(request->routes, route2, -1); + pos++; + } + return 0; + } + + /* if the first URI of route set does not contain "lr", the req_uri + is set to the first uri of route set */ + + + i = osip_uri_clone(route->url, &(request->req_uri)); + if (i!=0) return -1; + /* add the route set */ + /* "The UAC MUST add a route header field containing + the remainder of the route set values in order. */ + pos=0; /* yes it is */ + + while (!osip_list_eol(dialog->route_set, pos)) /* not the first one in the list */ + { + osip_route_t *route2; + route = osip_list_get(dialog->route_set, pos); + i = osip_route_clone(route, &route2); + if (i!=0) return -1; + if (dialog->type==CALLER) + { + if (pos!=osip_list_size(dialog->route_set)-1) + osip_list_add(request->routes, route2, 0); + else + osip_route_free(route2); + } + else + { + if (!osip_list_eol(dialog->route_set, pos+1)) + osip_list_add(request->routes, route2, -1); + else + osip_route_free(route2); + } + pos++; + } + + /* The UAC MUST then place the remote target URI into + the route header field as the last value */ + i = osip_uri_to_str(dialog->remote_contact_uri->url, &last_route); + if (i!=0) return -1; + i = osip_message_set_route(request, last_route); + osip_free(last_route); + if (i!=0) { return -1; } + + /* route header and req_uri set */ + return 0; +} + +int +_eXosip_build_request_within_dialog(osip_message_t **dest, char *method_name, + osip_dialog_t *dialog, char *transport) +{ + int i; + osip_message_t *request; +#ifdef SM + char *locip=NULL; +#else + char locip[50]; +#endif + + i = osip_message_init(&request); + if (i!=0) return -1; + + if (dialog->remote_contact_uri==NULL) + { + /* this dialog is probably not established! or the remote UA + is not compliant with the latest RFC + */ + osip_message_free(request); + return -1; + } +#ifdef SM + eXosip_get_localip_for(dialog->remote_contact_uri->url->host,&locip); +#else + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + /* prepare the request-line */ + request->sip_method = osip_strdup(method_name); + request->sip_version = osip_strdup("SIP/2.0"); + request->status_code = 0; + request->reason_phrase = NULL; + + /* and the request uri???? */ + if (osip_list_eol(dialog->route_set, 0)) + { + /* The UAC must put the remote target URI (to field) in the req_uri */ + i = osip_uri_clone(dialog->remote_contact_uri->url, &(request->req_uri)); + if (i!=0) goto grwd_error_1; + } + else + { + /* fill the request-uri, and the route headers. */ + dialog_fill_route_set(dialog, request); + } + + /* To and From already contains the proper tag! */ + i = osip_to_clone(dialog->remote_uri, &(request->to)); + if (i!=0) goto grwd_error_1; + i = osip_from_clone(dialog->local_uri, &(request->from)); + if (i!=0) goto grwd_error_1; + + /* set the cseq and call_id header */ + osip_message_set_call_id(request, dialog->call_id); + + if (0==strcmp("ACK", method_name)) + { + osip_cseq_t *cseq; + char *tmp; + i = osip_cseq_init(&cseq); + if (i!=0) goto grwd_error_1; + tmp = osip_malloc(20); + sprintf(tmp,"%i", dialog->local_cseq); + osip_cseq_set_number(cseq, tmp); + osip_cseq_set_method(cseq, osip_strdup(method_name)); + request->cseq = cseq; + } + else + { + osip_cseq_t *cseq; + char *tmp; + i = osip_cseq_init(&cseq); + if (i!=0) goto grwd_error_1; + dialog->local_cseq++; /* we should we do that?? */ + tmp = osip_malloc(20); + sprintf(tmp,"%i", dialog->local_cseq); + osip_cseq_set_number(cseq, tmp); + osip_cseq_set_method(cseq, osip_strdup(method_name)); + request->cseq = cseq; + } + + /* always add the Max-Forward header */ + osip_message_set_max_forwards(request, "70"); /* a UA should start a request with 70 */ + + + /* even for ACK for 2xx (ACK within a dialog), the branch ID MUST + be a new ONE! */ +#ifdef MASQUERADE_VIA + /* should be useless with compliant UA */ + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = request->req_uri->host; + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, request->req_uri->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + if (eXosip_is_public_address(c_address)) + { + char tmp[200]; + sprintf(tmp, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + eXosip.j_firewall_ip, + eXosip.localport, + via_branch_new_random() ); + osip_message_set_via(request, tmp); + } + else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + snprintf(tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + else + snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + + osip_message_set_via(request, tmp); + } + } + else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + snprintf(tmp, 200, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + else + snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, + eXosip.localport, + via_branch_new_random() ); + + osip_message_set_via(request, tmp); + } + +#else + { + char tmp[200]; + if (eXosip.ip_family==AF_INET6) + sprintf(tmp, "SIP/2.0/%s [%s]:%s;branch=z9hG4bK%u", transport, + locip, eXosip.localport, + via_branch_new_random()); + else + sprintf(tmp, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", transport, + locip, eXosip.localport, + via_branch_new_random()); + + osip_message_set_via(request, tmp); + } +#endif + + /* add specific headers for each kind of request... */ + +#if 0 + if (0==strcmp("INVITE", method_name) || 0==strcmp("SUBSCRIBE", method_name)) +#endif + { + char contact[200]; + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = request->req_uri->host; + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, request->req_uri->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + if (eXosip_is_public_address(c_address)) + { + sprintf(contact, "", dialog->local_uri->url->username, + eXosip.j_firewall_ip, + eXosip.localport); + } + else + { + sprintf(contact, "", dialog->local_uri->url->username, + locip, + eXosip.localport); + } + } + else + { + sprintf(contact, "", dialog->local_uri->url->username, + locip, + eXosip.localport); + } + osip_message_set_contact(request, contact); + /* Here we'll add the supported header if it's needed! */ + /* the require header must be added by the upper layer if needed */ + } + + if (0==strcmp("SUBSCRIBE", method_name)) + { + osip_message_set_header(request, "Event", "presence"); +#ifdef SUPPORT_MSN + osip_message_set_accept(request, "application/xpidf+xml"); +#else + osip_message_set_accept(request, "application/pidf+xml"); +#endif + } + else if (0==strcmp("NOTIFY", method_name)) + { + } + else if (0==strcmp("INFO", method_name)) + { + + } + else if (0==strcmp("OPTIONS", method_name)) + { + osip_message_set_accept(request, "application/sdp"); + } + else if (0==strcmp("ACK", method_name)) + { + /* The ACK MUST contains the same credential than the INVITE!! */ + /* TODO... */ + } + + osip_message_set_user_agent(request, eXosip.user_agent); + /* else if ... */ + *dest = request; + return 0; + + /* grwd_error_2: */ + dialog->local_cseq--; + grwd_error_1: + osip_message_free(request); + *dest = NULL; + return -1; +} + +/* this request is only build within a dialog!! */ +int +generating_bye(osip_message_t **bye, osip_dialog_t *dialog) +{ + int i; + i = _eXosip_build_request_within_dialog(bye, "BYE", dialog, "UDP"); + if (i!=0) return -1; + + return 0; +} + +/* this request is only build within a dialog! (but should not!) */ +int +generating_refer_outside_dialog(osip_message_t **refer, char *refer_to, char *from, char *to, char *proxy) +{ + int i; + i = generating_request_out_of_dialog(refer, "REFER", to, "UDP", + from, proxy); + if (i!=0) return -1; + + osip_message_set_header(*refer, "Refer-to", refer_to); + return 0; +} + +/* this request is only build within a dialog! (but should not!) */ +int +generating_refer(osip_message_t **refer, osip_dialog_t *dialog, char *refer_to) +{ + int i; + i = _eXosip_build_request_within_dialog(refer, "REFER", dialog, "UDP"); + if (i!=0) return -1; + + osip_message_set_header(*refer, "Refer-to", refer_to); + + return 0; +} + +/* this request can be inside or outside a dialog */ +int +generating_options_within_dialog(osip_message_t **options, osip_dialog_t *dialog) +{ + int i; + i = _eXosip_build_request_within_dialog(options, "OPTIONS", dialog, "UDP"); + if (i!=0) return -1; + +#if 0 + if (sdp!=NULL) + { + osip_message_set_content_type(*options, "application/sdp"); + osip_message_set_body(*options, sdp); + } +#endif + + return 0; +} + +int +generating_info_within_dialog(osip_message_t **info, osip_dialog_t *dialog) +{ + int i; + i = _eXosip_build_request_within_dialog(info, "INFO", dialog, "UDP"); + if (i!=0) return -1; + return 0; +} + +/* It is RECOMMENDED to only cancel INVITE request */ +int +generating_cancel(osip_message_t **dest, osip_message_t *request_cancelled) +{ + int i; + osip_message_t *request; + + i = osip_message_init(&request); + if (i!=0) return -1; + + /* prepare the request-line */ + osip_message_set_method(request, osip_strdup("CANCEL")); + osip_message_set_version(request, osip_strdup("SIP/2.0")); + osip_message_set_status_code(request, 0); + osip_message_set_reason_phrase(request, NULL); + + i = osip_uri_clone(request_cancelled->req_uri, &(request->req_uri)); + if (i!=0) goto gc_error_1; + + i = osip_to_clone(request_cancelled->to, &(request->to)); + if (i!=0) goto gc_error_1; + i = osip_from_clone(request_cancelled->from, &(request->from)); + if (i!=0) goto gc_error_1; + + /* set the cseq and call_id header */ + i = osip_call_id_clone(request_cancelled->call_id, &(request->call_id)); + if (i!=0) goto gc_error_1; + i = osip_cseq_clone(request_cancelled->cseq, &(request->cseq)); + if (i!=0) goto gc_error_1; + osip_free(request->cseq->method); + request->cseq->method = osip_strdup("CANCEL"); + + /* copy ONLY the top most Via Field (this method is also used by proxy) */ + { + osip_via_t *via; + osip_via_t *via2; + i = osip_message_get_via(request_cancelled, 0, &via); + if (i!=0) goto gc_error_1; + i = osip_via_clone(via, &via2); + if (i!=0) goto gc_error_1; + osip_list_add(request->vias, via2, -1); + } + + /* add the same route-set than in the previous request */ + { + int pos=0; + osip_route_t *route; + osip_route_t *route2; + while (!osip_list_eol(request_cancelled->routes, pos)) + { + route = (osip_route_t*) osip_list_get(request_cancelled->routes, pos); + i = osip_route_clone(route, &route2); + if (i!=0) goto gc_error_1; + osip_list_add(request->routes, route2, -1); + pos++; + } + } + + osip_message_set_max_forwards(request, "70"); /* a UA should start a request with 70 */ + osip_message_set_user_agent(request, eXosip.user_agent); + + *dest = request; + return 0; + + gc_error_1: + osip_message_free(request); + *dest = NULL; + return -1; +} + + +int +generating_ack_for_2xx(osip_message_t **ack, osip_dialog_t *dialog) +{ + int i; + i = _eXosip_build_request_within_dialog(ack, "ACK", dialog, "UDP"); + if (i!=0) return -1; + + return 0; +} diff --git a/linphone/exosip/jresponse.c b/linphone/exosip/jresponse.c new file mode 100644 index 000000000..39d83c127 --- /dev/null +++ b/linphone/exosip/jresponse.c @@ -0,0 +1,1264 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +/* Private functions */ +static char *generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_message_t *orig_request, char *local_sdp_port); + +int +eXosip_build_response_default(int jid, int status) +{ + return -1; +} + +int +_eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog, + int status, osip_message_t *request) +{ + osip_generic_param_t *tag; + osip_message_t *response; + int pos; + int i; + + if (request==NULL) return -1; + + i = osip_message_init(&response); + if (i!=0) + return -1; + /* initialise osip_message_t structure */ + /* yet done... */ + + response->sip_version = (char *)osip_malloc(8*sizeof(char)); + sprintf(response->sip_version,"SIP/2.0"); + osip_message_set_status_code(response, status); + + /* handle some internal reason definitions. */ + if (MSG_IS_NOTIFY(request) && status==481) + { + response->reason_phrase = osip_strdup("Subcription Does Not Exist"); + } + else if (MSG_IS_SUBSCRIBE(request) && status==202) + { + response->reason_phrase = osip_strdup("Accepted subscription"); + } + else + { + response->reason_phrase = osip_strdup(osip_message_get_reason(status)); + if (response->reason_phrase==NULL) + { + if (response->status_code == 101) + response->reason_phrase = osip_strdup("Dialog Establishement"); + else + response->reason_phrase = osip_strdup("Unknown code"); + } + response->req_uri = NULL; + response->sip_method = NULL; + } + + i = osip_to_clone(request->to, &(response->to)); + if (i!=0) goto grd_error_1; + + i = osip_to_get_tag(response->to,&tag); + if (i!=0) + { /* we only add a tag if it does not already contains one! */ + if ((dialog!=NULL) && (dialog->local_tag!=NULL)) + /* it should contain the local TAG we created */ + { osip_to_set_tag(response->to, osip_strdup(dialog->local_tag)); } + else + { + if (status!=100) + osip_to_set_tag(response->to, osip_to_tag_new_random()); + } + } + + i = osip_from_clone(request->from, &(response->from)); + if (i!=0) goto grd_error_1; + + pos = 0; + while (!osip_list_eol(request->vias,pos)) + { + osip_via_t *via; + osip_via_t *via2; + via = (osip_via_t *)osip_list_get(request->vias,pos); + i = osip_via_clone(via, &via2); + if (i!=-0) goto grd_error_1; + osip_list_add(response->vias, via2, -1); + pos++; + } + + i = osip_call_id_clone(request->call_id, &(response->call_id)); + if (i!=0) goto grd_error_1; + i = osip_cseq_clone(request->cseq, &(response->cseq)); + if (i!=0) goto grd_error_1; + + if (MSG_IS_SUBSCRIBE(request)) + { + osip_header_t *exp; + osip_message_set_header(response, "Event", "presence"); + i = osip_message_get_expires(request, 0, &exp); + if (exp==NULL) + { + osip_header_t *cp; + i = osip_header_clone(exp, &cp); + if (cp!=NULL) + osip_list_add(response->headers, cp, 0); + } + } + + osip_message_set_allow(response, "INVITE"); + osip_message_set_allow(response, "ACK"); + osip_message_set_allow(response, "OPTIONS"); + osip_message_set_allow(response, "CANCEL"); + osip_message_set_allow(response, "BYE"); + osip_message_set_allow(response, "SUBSCRIBE"); + osip_message_set_allow(response, "NOTIFY"); + osip_message_set_allow(response, "MESSAGE"); + osip_message_set_allow(response, "INFO"); + + *dest = response; + return 0; + + grd_error_1: + osip_message_free(response); + return -1; +} + +int +complete_answer_that_establish_a_dialog(osip_message_t *response, osip_message_t *request) +{ + int i; + int pos=0; + char contact[1000]; +#ifdef SM + char *locip=NULL; +#else + char locip[50]; +#endif + /* 12.1.1: + copy all record-route in response + add a contact with global scope + */ + while (!osip_list_eol(request->record_routes, pos)) + { + osip_record_route_t *rr; + osip_record_route_t *rr2; + rr = osip_list_get(request->record_routes, pos); + i = osip_record_route_clone(rr, &rr2); + if (i!=0) return -1; + osip_list_add(response->record_routes, rr2, -1); + pos++; + } + +#ifdef SM + eXosip_get_localip_from_via(response,&locip); +#else + eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); +#endif + + if (eXosip.answer_contact[0]) + snprintf(contact,1000, "%s", eXosip.answer_contact); + else if (request->to->url->username==NULL) + snprintf(contact,1000, "", locip, eXosip.localport); + else + snprintf(contact,1000, "", request->to->url->username, + locip, eXosip.localport); + + if (eXosip.j_firewall_ip[0]!='\0') + { + osip_contact_t *con = (osip_contact_t *) osip_list_get (request->contacts, 0); + if (con!=NULL && con->url!=NULL && con->url->host!=NULL) + { + char *c_address = con->url->host; + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, con->url->host, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + /* If c_address is a PUBLIC address, the request was + coming from the PUBLIC network. */ + if (eXosip_is_public_address(c_address)) + { + if (request->to->url->username==NULL) + snprintf(contact,1000, "", eXosip.j_firewall_ip, + eXosip.localport); + else + snprintf(contact,1000, "", request->to->url->username, + eXosip.j_firewall_ip, eXosip.localport); + } + } + } + +#ifdef SM + osip_free(locip); +#endif + + osip_message_set_contact(response, contact); + + return 0; +} + +static char * +generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_message_t *orig_request, char *local_sdp_port) +{ + sdp_message_t *local_sdp = NULL; + char *local_body = NULL; + char *size; + int i; + + jc->c_ack_sdp = 1; + if(osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &local_sdp, local_sdp_port, NULL) != 0) + return NULL; + + if (local_sdp!=NULL) + { + int pos=0; + while (!sdp_message_endof_media (local_sdp, pos)) + { + int k = 0; + char *tmp = sdp_message_m_media_get (local_sdp, pos); + if (0 == strncmp (tmp, "audio", 5)) + { + char *payload = NULL; + do { + payload = sdp_message_m_payload_get (local_sdp, pos, k); + if (payload == NULL) + { + } + else if (0==strcmp("110",payload)) + { + sdp_message_a_attribute_add (local_sdp, + pos, + osip_strdup ("AS"), + osip_strdup ("110 20")); + } + else if (0==strcmp("111",payload)) + { + sdp_message_a_attribute_add (local_sdp, + pos, + osip_strdup ("AS"), + osip_strdup ("111 20")); + } + k++; + } while (payload != NULL); + } + pos++; + } + } + + i = sdp_message_to_str(local_sdp, &local_body); + + if (local_body!=NULL) + { + size= (char *)osip_malloc(7*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(local_body)); +#else + sprintf(size,"%i",strlen(local_body)); +#endif + osip_message_set_content_length(orig_request, size); + osip_free(size); + + osip_message_set_body(orig_request, local_body, strlen(local_body)); + osip_message_set_content_type(orig_request, "application/sdp"); + } + else + osip_message_set_content_length(orig_request, "0"); + + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, local_sdp); + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL,"200 OK w/ SDP (RESPONSE TO INVITE w/ NO SDP)=\n%s\n", local_body)); + + return local_body; +} + +char * +generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context) +{ + sdp_message_t *remote_sdp; + sdp_message_t *local_sdp = NULL; + int i; + char *local_body; + if (context==NULL) + return NULL; + + local_body = NULL; + if (MSG_IS_INVITE(request)||MSG_IS_OPTIONS(request)||MSG_IS_RESPONSE_FOR(request, "INVITE")) + { + osip_body_t *body; + body = (osip_body_t *)osip_list_get(request->bodies,0); + if(body == NULL) + return NULL; + + /* remote_sdp = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t)); */ + i = sdp_message_init(&remote_sdp); + if (i!=0) return NULL; + + /* WE ASSUME IT IS A SDP BODY AND THAT */ + /* IT IS THE ONLY ONE, OF COURSE, THIS IS */ + /* NOT TRUE */ + i = sdp_message_parse(remote_sdp,body->body); + if (i!=0) return NULL; + + i = osip_negotiation_ctx_set_remote_sdp(context, remote_sdp); + + i = osip_negotiation_ctx_execute_negotiation(eXosip.osip_negotiation, context); + if (i==200) + { + local_sdp = osip_negotiation_ctx_get_local_sdp(context); + + if (eXosip.j_firewall_ip[0]!='\0') + { + char *c_address = NULL; + int pos=0; + /* If remote message contains a Public IP, we have to replace the SDP + connection address */ + c_address = sdp_message_c_addr_get(remote_sdp, -1, 0); + while (c_address==NULL) + { + c_address = sdp_message_c_addr_get(remote_sdp, pos, 0); + pos++; + if (pos>10) + break; + } + if (c_address!=NULL) /* found a connection address: check if it is public */ + { + + struct addrinfo *addrinfo; + struct __eXosip_sockaddr addr; + i = eXosip_get_addrinfo(&addrinfo, c_address, 5060); + if (i==0) + { + memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); + freeaddrinfo (addrinfo); + c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO1, NULL, + "eXosip: here is the resolved destination host=%s\n", c_address)); + } + + if (eXosip_is_public_address(c_address)) + { + /* replace the IP with our firewall ip */ + sdp_connection_t *conn; + pos=-1; + conn = sdp_message_connection_get(local_sdp, pos, 0); + while (conn!=NULL) + { + if (conn->c_addr!=NULL ) + { + osip_free(conn->c_addr); + conn->c_addr = osip_strdup(eXosip.j_firewall_ip); + } + pos++; + conn = sdp_message_connection_get(local_sdp, pos, 0); + } + } + } + } + + i = sdp_message_to_str(local_sdp, &local_body); + + remote_sdp = osip_negotiation_ctx_get_remote_sdp(context); + sdp_message_free(remote_sdp); + osip_negotiation_ctx_set_remote_sdp(context, NULL); + + if (i!=0) { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not parse local SDP answer %i\n",i)); + return NULL; + } + return local_body; + } + else if (i==415) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"WARNING: Unsupported media %i\n",i)); + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: while building answer to SDP (%i)\n",i)); + } + remote_sdp = osip_negotiation_ctx_get_remote_sdp(context); + sdp_message_free(remote_sdp); + osip_negotiation_ctx_set_remote_sdp(context, NULL); + } + return NULL; +} + +int +eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_transaction_t *tr; + osip_message_t *response; + int i; + + tr = eXosip_find_last_inc_options(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + + if (jd!=NULL) + { + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + } + else + { + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + } + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for OPTIONS\n")); + return -1; + } + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; +} + +int +eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_transaction_t *tr; + osip_message_t *response; + sdp_message_t *sdp; + char *body; + char size[10]; + int i; + + tr = eXosip_find_last_inc_options(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL); + if (sdp==NULL) + { + return -1; + } + if (jd!=NULL) + { + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + } + else + { + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + } + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); + sdp_message_free(sdp); /* not used */ + return -1; + } + i = sdp_message_to_str(sdp, &body); + sdp_message_free(sdp); + if (i!=0) { + osip_message_free(response); + return -1; + } + i = osip_message_set_body(response, body, strlen(body)); + if (i!=0) { + osip_message_free(response); + return -1; + } +#ifdef __APPLE_CC__ + snprintf(size, 9,"%li",strlen(body)); +#else + snprintf(size, 9,"%i",strlen(body)); +#endif + i = osip_message_set_content_length(response, size); + if (i!=0) { + osip_free(body); + osip_message_free(response); + return -1; + } + osip_free(body); + i = osip_message_set_content_type(response, "application/sdp"); + if (i!=0) { + osip_message_free(response); + return -1; + } + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; +} + +int +eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_transaction_t *tr; + osip_message_t *response; + int i; + tr = eXosip_find_last_inc_options(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + + if (jd!=NULL) + { + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + } + else + { + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + } + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); + return -1; + } + + if (300<=code<=399) + { + /* Should add contact fields */ + /* ... */ + osip_message_set_contact(response, jc->c_redirection); + } + + osip_message_set_content_length(response, "0"); + /* send message to transaction layer */ + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + + return 0; +} + +int +_eXosip2_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer) +{ + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + if (jd==NULL) + i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n")); + return -2; + } + + osip_message_set_content_length(*answer, "0"); + /* send message to transaction layer */ + + if (code>100) + { + i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request); + } + + return 0; +} + +int +_eXosip2_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer) +{ + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + + if (tr==NULL || tr->orig_request==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer\n")); + return -1; + } + + if (jd!=NULL && jd->d_dialog==NULL) + { /* element previously removed */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot answer this closed transaction\n")); + return -1; + } + + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + if (jd==NULL) + i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); + return -1; + } + + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + { + i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request); + if (i!=0) goto g2atii_error_1;; /* ?? */ + } + + return 0; + + g2atii_error_1: + osip_message_free(*answer); + return -1; +} + +int +_eXosip2_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer) +{ + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); + return -1; + } + + if (300<=code<=399) + { + /* Should add contact fields */ + /* ... */ + } + + osip_message_set_content_length(*answer, "0"); + /* send message to transaction layer */ + + return 0; +} + +int +eXosip_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + if (jd==NULL) + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n")); + return -2; + } + + osip_message_set_content_length(response, "0"); + /* send message to transaction layer */ + + if (code>100) + { + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + i = complete_answer_that_establish_a_dialog(response, tr->orig_request); + + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + } + ADD_ELEMENT(jc->c_dialogs, jd); + } + } + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + + return 0; +} + +int +eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + char *size; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + + if (tr==NULL || tr->orig_request==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer\n")); + return -1; + } + + if (jd!=NULL && jd->d_dialog==NULL) + { /* element previously removed */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot answer this closed transaction\n")); + return -1; + } + + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + if (jd==NULL) + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); + code = 500; /* ? which code to use? */ + return -1; + } + + if (code==488) + { + osip_message_set_content_length(response, "0"); + /* TODO: send message to transaction layer */ + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; + } + + i = osip_message_set_body(response, body, strlen(body)); + if (i!=0) { + goto g2atii_error_1; + } + size = (char *) osip_malloc(6*sizeof(char)); + sprintf(size,"%i",strlen(body)); + i = osip_message_set_content_length(response, size); + osip_free(size); + if (i!=0) goto g2atii_error_1; + i = osip_message_set_content_type(response, bodytype); + if (i!=0) goto g2atii_error_1; + + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + { + i = complete_answer_that_establish_a_dialog(response, tr->orig_request); + if (i!=0) goto g2atii_error_1;; /* ?? */ + } + /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ + /* this response must be stored at the upper layer!!! (it will be destroyed*/ + /* right after being sent! */ + + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + return -1; + } + ADD_ELEMENT(jc->c_dialogs, jd); + } + + eXosip_dialog_set_200ok(jd, response); + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + __eXosip_wakeup(); + return 0; + + g2atii_error_1: + osip_message_free(response); + return -1; +} + +int +eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + char *size; + char *body = NULL; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + + if (tr==NULL || tr->orig_request==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer\n")); + return -1; + } + + if (jd!=NULL && jd->d_dialog==NULL) + { /* element previously removed */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot answer this closed transaction\n")); + return -1; + } + + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + /* WE SHOULD LOOK FOR A SDP PACKET!! */ + if(NULL != osip_list_get(tr->orig_request->bodies,0)) + { + body = generating_sdp_answer(tr->orig_request, jc->c_ctx); + if (body==NULL) + code = 488; /* bad sdp */ + } + else + { + if(local_sdp_port==NULL) + code = 488; /* session description in the request is not acceptable. */ + else + /* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */ + body = generating_no_sdp_answer(jc, jd, tr->orig_request, local_sdp_port); + } + + if (jd==NULL) + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); + code = 500; /* ? which code to use? */ + osip_free(body); /* not used */ + return -1; + } + + if (code==488) + { + osip_message_set_content_length(response, "0"); + /* TODO: send message to transaction layer */ + osip_free(body); + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; + } + + i = osip_message_set_body(response, body, strlen(body)); + if (i!=0) { + goto g2atii_error_1; + } + size = (char *) osip_malloc(6*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(body)); +#else + sprintf(size,"%i",strlen(body)); +#endif + i = osip_message_set_content_length(response, size); + osip_free(size); + if (i!=0) goto g2atii_error_1; + i = osip_message_set_content_type(response, "application/sdp"); + if (i!=0) goto g2atii_error_1; + + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + { + i = complete_answer_that_establish_a_dialog(response, tr->orig_request); + if (i!=0) goto g2atii_error_1;; /* ?? */ + } + + osip_free(body); + /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ + /* this response must be stored at the upper layer!!! (it will be destroyed*/ + /* right after being sent! */ + + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + return -1; + } + ADD_ELEMENT(jc->c_dialogs, jd); + } + + eXosip_dialog_set_200ok(jd, response); + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + __eXosip_wakeup(); + return 0; + + g2atii_error_1: + osip_free(body); + osip_message_free(response); + return -1; +} + +int +eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return -1; + } + /* is the transaction already answered? */ + if (tr->state==IST_COMPLETED + || tr->state==IST_CONFIRMED + || tr->state==IST_TERMINATED) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: transaction already answered\n")); + return -1; + } + + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); + return -1; + } + + if (300<=code<=399) + { + /* Should add contact fields */ + /* ... */ + osip_message_set_contact(response, jc->c_redirection); + } + + osip_message_set_content_length(response, "0"); + /* send message to transaction layer */ + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return 0; +} + + +void +eXosip_notify_answer_subscribe_1xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_subscribe(jn, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return; + } + + if (jd==NULL) + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for subscribe\n")); + return; + } + + if (code>100) + { + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + i = complete_answer_that_establish_a_dialog(response, tr->orig_request); + + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + } + ADD_ELEMENT(jn->n_dialogs, jd); + } + } + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return ; +} + +void +eXosip_notify_answer_subscribe_2xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_subscribe(jn, jd); + + if (tr==NULL || tr->orig_request==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer\n")); + return; + } + + if (jd!=NULL && jd->d_dialog==NULL) + { /* element previously removed, this is a no hop! */ + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot answer this closed transaction\n")); + return ; + } + + if (jd==NULL) + i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); + else + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n")); + code = 500; /* ? which code to use? */ + return; + } + + /* request that estabish a dialog: */ + /* 12.1.1 UAS Behavior */ + { + i = complete_answer_that_establish_a_dialog(response, tr->orig_request); + if (i!=0) goto g2atii_error_1;; /* ?? */ + } + + /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ + /* this response must be stored at the upper layer!!! (it will be destroyed*/ + /* right after being sent! */ + + if (jd==NULL) + { + i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + return; + } + ADD_ELEMENT(jn->n_dialogs, jd); + } + + eXosip_dialog_set_200ok(jd, response); + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + return ; + + g2atii_error_1: + osip_message_free(response); + return ; +} + +void +eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code) +{ + osip_event_t *evt_answer; + osip_message_t *response; + int i; + osip_transaction_t *tr; + tr = eXosip_find_last_inc_subscribe(jn, jd); + if (tr==NULL) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot find transaction to answer")); + return; + } + i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n")); + return; + } + + if (300<=code<=399) + { + /* Should add contact fields */ + /* ... */ + } + + evt_answer = osip_new_outgoing_sipmessage(response); + evt_answer->transactionid = tr->transactionid; + + osip_transaction_add_event(tr, evt_answer); + __eXosip_wakeup(); + return ; +} diff --git a/linphone/exosip/jsubscribe.c b/linphone/exosip/jsubscribe.c new file mode 100644 index 000000000..d6b9ad11b --- /dev/null +++ b/linphone/exosip/jsubscribe.c @@ -0,0 +1,231 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + + +#include "eXosip2.h" +#include + +extern eXosip_t eXosip; + +#if 0 +int eXosip_subscribe_find(int sid, eXosip_subscribe_t **js) +{ + for (*js=eXosip.j_subscribes; *js!=NULL; *js=(*js)->next) + { + if ((*js)->s_id==sid) + return 0; + } + *js = NULL; + return -1; +} +#endif + +osip_transaction_t * +eXosip_find_last_out_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "SUBSCRIBE")) + break; + else out_tr = NULL; + pos++; + } + } + else + out_tr = NULL; + + if (out_tr==NULL) + return js->s_out_tr; /* can be NULL */ + + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_inc_notify(eXosip_subscribe_t *js, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "NOTIFY")) + return out_tr; + pos++; + } + } + + return NULL; +} + + +#if 0 +void +__eXosip_subscribe_remove_dialog_reference_in_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd) +{ + eXosip_dialog_t *_jd; + jinfo_t *ji; + if (js==NULL) return; + if (jd==NULL) return; + + + for (_jd = js->s_dialogs; _jd!=NULL; _jd=js->s_dialogs) + { + if (jd==_jd) + break; + } + if (_jd==NULL) + { + /* dialog not found??? */ + } + + ji = osip_transaction_get_your_instance(js->s_inc_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; + ji = osip_transaction_get_your_instance(js->s_out_tr); + if (ji!=NULL && ji->jd==jd) + ji->jd=NULL; +} +#endif + +int +eXosip_subscribe_init(eXosip_subscribe_t **js, char *uri) +{ + if (uri==NULL) return -1; + *js = (eXosip_subscribe_t *)osip_malloc(sizeof(eXosip_subscribe_t)); + if (*js == NULL) return -1; + memset(*js, 0, sizeof(eXosip_subscribe_t)); + osip_strncpy((*js)->s_uri, uri, strlen(uri)); + return 0; +} + +void +eXosip_subscribe_free(eXosip_subscribe_t *js) +{ + /* ... */ + + eXosip_dialog_t *jd; + + for (jd = js->s_dialogs; jd!=NULL; jd=js->s_dialogs) + { + REMOVE_ELEMENT(js->s_dialogs, jd); + eXosip_dialog_free(jd); + } + + __eXosip_delete_jinfo(js->s_inc_tr); + __eXosip_delete_jinfo(js->s_out_tr); + if (js->s_inc_tr!=NULL) + osip_list_add(eXosip.j_transactions, js->s_inc_tr, 0); + if (js->s_out_tr!=NULL) + osip_list_add(eXosip.j_transactions, js->s_out_tr, 0); + + osip_free(js); +} + +int +_eXosip_subscribe_set_refresh_interval(eXosip_subscribe_t *js, + osip_message_t *out_subscribe) +{ + osip_header_t *exp; + int now = time(NULL); + if (js==NULL || out_subscribe==NULL) + return -1; + + osip_message_get_expires(out_subscribe, 0, &exp); + if (exp==NULL || exp->hvalue==NULL) + js->s_ss_expires = now + 600; + else + { + js->s_ss_expires = osip_atoi(exp->hvalue); + if (js->s_ss_expires!=-1) + js->s_ss_expires = now + js->s_ss_expires; + else /* on error, set it to default */ + js->s_ss_expires = now + 600; + } + + return 0; +} + +int eXosip_subscribe_need_refresh(eXosip_subscribe_t *js, int now) +{ + if (now-js->s_ss_expires>-120) + return 0; + return -1; +} + +int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js, + eXosip_dialog_t *jd, const char *expires) +{ + osip_transaction_t *transaction; + osip_message_t *subscribe; + osip_event_t *sipevent; + int i; + transaction = eXosip_find_last_out_subscribe(js, jd); + if (transaction!=NULL) + { + if (transaction->state!=NICT_TERMINATED && + transaction->state!=NIST_TERMINATED) + return -1; + } + + i = _eXosip_build_request_within_dialog(&subscribe, "SUBSCRIBE", + jd->d_dialog, "UDP"); + if (i!=0) + return -2; + + osip_message_set_expires(subscribe, expires); + + i = osip_transaction_init(&transaction, + NICT, + eXosip.j_osip, + subscribe); + if (i!=0) + { + /* TODO: release the j_call.. */ + osip_message_free(subscribe); + return -1; + } + + _eXosip_subscribe_set_refresh_interval(js, subscribe); + osip_list_add(jd->d_out_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(subscribe); + sipevent->transactionid = transaction->transactionid; + + osip_transaction_add_event(transaction, sipevent); + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, js, NULL)); + __eXosip_wakeup(); + return 0; +} diff --git a/linphone/exosip/jsubscribers.c b/linphone/exosip/jsubscribers.c new file mode 100644 index 000000000..a4242b43b --- /dev/null +++ b/linphone/exosip/jsubscribers.c @@ -0,0 +1,185 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include +#include + +extern eXosip_t eXosip; + +#ifndef EXOSIP_ETC_DIR +#define EXOSIP_ETC_DIR ".eXosip" +#endif + +#ifndef EXOSIP_ADDSUBSCRIBERS_SH +#define EXOSIP_ADDSUBSCRIBERS_SH "eXosip_addsubscriber.sh" +#endif + + +static int jsubscriber_init(jsubscriber_t **js, char *ch) +{ + char *next; + int i; + + *js = (jsubscriber_t *)osip_malloc(sizeof(jsubscriber_t)); + if (*js==NULL) return -1; + + i = jfriend_get_and_set_next_token(&((*js)->s_nick), ch, &next); + if (i != 0) + goto js_error1; + osip_clrspace ((*js)->s_nick); + ch = next; + + i = jfriend_get_and_set_next_token(&((*js)->s_uri), ch, &next); + if (i != 0) + goto js_error2; + osip_clrspace ((*js)->s_uri); + ch = next; + + (*js)->s_allow = osip_strdup(next); + osip_clrspace ((*js)->s_allow); + + return 0; + + js_error2: + osip_free((*js)->s_nick); + js_error1: + osip_free(*js); + *js = NULL; + return -1; +} + +void +jsubscriber_unload() +{ + jsubscriber_t *js; + if (eXosip.j_subscribers==NULL) return; + for (js=eXosip.j_subscribers; js!=NULL; js=eXosip.j_subscribers) + { + REMOVE_ELEMENT(eXosip.j_subscribers,js); + osip_free(js->s_nick); + osip_free(js->s_uri); + osip_free(js->s_allow); + osip_free(js); + } + + osip_free(eXosip.j_subscribers); + eXosip.j_subscribers=NULL; + return; +} + +int +jsubscriber_load() +{ + FILE *file; + char *s; + jsubscriber_t *js; + int pos; + char *home; + char filename[255]; + + jsubscriber_unload(); + home = getenv("HOME"); + sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_subscriber"); + + + file = fopen(filename, "r"); + if (file==NULL) return -1; + s = (char *)osip_malloc(255*sizeof(char)); + pos = 0; + while (NULL!=fgets(s, 254, file)) + { + char *tmp = s; + while (*tmp!='\0' && *tmp!=' ') tmp++; + while (*tmp!='\0' && *tmp==' ') tmp++; + while (*tmp!='\0' && *tmp!=' ') tmp++; + tmp++; /* first usefull characters */ + pos++; + + jsubscriber_init(&js, tmp); + if (js!=NULL) + { ADD_ELEMENT(eXosip.j_subscribers, js); } + } + osip_free(s); + fclose(file); + + return 0; /* ok */ +} + +void subscribers_add(char *nickname, char *uri, int black_list) +{ + char *home; + char command[256]; + char *tmp = command; + int length = 0; + if (nickname!=NULL) + length = strlen(nickname); + + if (uri==NULL) + return ; + home = getenv("HOME"); + length = length + strlen(home); + length = length + strlen(uri); + + length = length + 10; /* for black_list info */ + length = length + strlen(EXOSIP_ETC_DIR); + + length = length + strlen("/jm_subscriber"); + if (length>235) /* leave some room for SPACEs and \r\n */ + return ; + + sprintf(tmp , "%s %s/%s/jm_subscriber", EXOSIP_ADDSUBSCRIBERS_SH, home, EXOSIP_ETC_DIR); + + tmp = tmp + strlen(tmp); + if (nickname!=NULL) + sprintf(tmp , " %s", nickname); + else + sprintf(tmp , " \"\""); + + tmp = tmp + strlen(tmp); + sprintf(tmp , " %s", uri); + + tmp = tmp + strlen(tmp); + if (black_list==0) /* allowed */ + sprintf(tmp , " allow"); + else + sprintf(tmp , " reject"); + + system(command); + + jsubscriber_load(); +} + +char * +jsubscriber_get_uri(int fid) +{ + jsubscriber_t *js; + for (js = eXosip.j_subscribers; js!=NULL ; js=js->next) + { + if (fid==0) + return osip_strdup(js->s_uri); + fid--; + } + return NULL; +} diff --git a/linphone/exosip/misc.c b/linphone/exosip/misc.c new file mode 100644 index 000000000..2be6b1a45 --- /dev/null +++ b/linphone/exosip/misc.c @@ -0,0 +1,436 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + + +#include "eXosip2.h" + +extern eXosip_t eXosip; + + +/* some methods to extract transaction information from a eXosip_call_t */ + +int +eXosip_remove_transaction_from_call(osip_transaction_t *tr, eXosip_call_t *jc) +{ + osip_transaction_t *inc_tr; + osip_transaction_t *out_tr; + eXosip_dialog_t *jd; + int pos=0; + + if (jc->c_inc_tr==tr) + { + jc->c_inc_tr = NULL; /* can be NULL */ + return 0; + } + + for (jd=jc->c_dialogs;jd!=NULL;jd=jd->next) + { + pos=0; + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (inc_tr==tr) + { + osip_list_remove(jd->d_inc_trs, pos); + return 0; + } + pos++; + } + } + + if (jc->c_out_tr==tr) + { + jc->c_out_tr = NULL; /* can be NULL */ + return 0; + } + + for (jd=jc->c_dialogs;jd!=NULL;jd=jd->next) + { + pos=0; + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (out_tr==tr) + { + osip_list_remove(jd->d_out_trs, pos); + return 0; + } + pos++; + } + } + + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "eXosip: No information.\n")); + return -1; +} + +osip_transaction_t * +eXosip_find_last_options(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + osip_transaction_t *out_tr; + inc_tr = eXosip_find_last_inc_options(jc, jd); + out_tr = eXosip_find_last_out_options(jc, jd); + if (inc_tr==NULL) + return out_tr; + if (out_tr==NULL) + return inc_tr; + + if (inc_tr->birth_time>out_tr->birth_time) + return inc_tr; + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_inc_options(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "OPTIONS")) + break; + else inc_tr = NULL; + pos++; + } + } + else + inc_tr = NULL; + + if (inc_tr==NULL) + return jc->c_inc_options_tr; /* can be NULL */ + + return inc_tr; +} + +osip_transaction_t * +eXosip_find_last_out_options(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd==NULL && jc==NULL) return NULL; + + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "OPTIONS")) + break; + else out_tr = NULL; + pos++; + } + } + + if (out_tr==NULL) + return jc->c_out_options_tr; /* can be NULL */ + + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_info(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + osip_transaction_t *out_tr; + inc_tr = eXosip_find_last_inc_info(jc, jd); + out_tr = eXosip_find_last_out_info(jc, jd); + if (inc_tr==NULL) + return out_tr; + if (out_tr==NULL) + return inc_tr; + + if (inc_tr->birth_time>out_tr->birth_time) + return inc_tr; + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_inc_info(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "INFO")) + break; + else inc_tr = NULL; + pos++; + } + } + else + inc_tr = NULL; + + return inc_tr; +} + +osip_transaction_t * +eXosip_find_last_out_info(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd==NULL && jc==NULL) return NULL; + + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "INFO")) + break; + else out_tr = NULL; + pos++; + } + } + + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + osip_transaction_t *out_tr; + inc_tr = eXosip_find_last_inc_refer(jc, jd); + out_tr = eXosip_find_last_out_refer(jc, jd); + if (inc_tr==NULL) + return out_tr; + if (out_tr==NULL) + return inc_tr; + + if (inc_tr->birth_time>out_tr->birth_time) + return inc_tr; + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_invite(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + osip_transaction_t *out_tr; + inc_tr = eXosip_find_last_inc_invite(jc, jd); + out_tr = eXosip_find_last_out_invite(jc, jd); + if (inc_tr==NULL) + return out_tr; + if (out_tr==NULL) + return inc_tr; + + if (inc_tr->birth_time>out_tr->birth_time) + return inc_tr; + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_inc_invite(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "INVITE")) + break; + else inc_tr = NULL; + pos++; + } + } + else + inc_tr = NULL; + + if (inc_tr==NULL) + return jc->c_inc_tr; /* can be NULL */ + + return inc_tr; +} + +osip_transaction_t * +eXosip_find_last_out_invite(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd==NULL && jc==NULL) return NULL; + + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "INVITE")) + break; + else out_tr = NULL; + pos++; + } + } + + if (out_tr==NULL) + return jc->c_out_tr; /* can be NULL */ + + return out_tr; +} + +osip_transaction_t * +eXosip_find_last_inc_bye(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "BYE")) + return inc_tr; + pos++; + } + } + + return NULL; +} + +osip_transaction_t * +eXosip_find_last_out_bye(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "BYE")) + return out_tr; + pos++; + } + } + + return NULL; +} + +osip_transaction_t * +eXosip_find_last_inc_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "REFER")) + return inc_tr; + pos++; + } + } + + return NULL; +} + +osip_transaction_t * +eXosip_find_last_out_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "REFER")) + return out_tr; + pos++; + } + } + + return NULL; +} + +osip_transaction_t * +eXosip_find_last_inc_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *inc_tr; + int pos; + inc_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + inc_tr = osip_list_get(jd->d_inc_trs, pos); + if (0==strcmp(inc_tr->cseq->method, "NOTIFY")) + return inc_tr; + pos++; + } + } + + return NULL; +} + +osip_transaction_t * +eXosip_find_last_out_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *out_tr; + int pos; + out_tr = NULL; + pos=0; + if (jd!=NULL) + { + while (!osip_list_eol(jd->d_out_trs, pos)) + { + out_tr = osip_list_get(jd->d_out_trs, pos); + if (0==strcmp(out_tr->cseq->method, "NOTIFY")) + return out_tr; + pos++; + } + } + + return NULL; +} diff --git a/linphone/exosip/sdp_offans.c b/linphone/exosip/sdp_offans.c new file mode 100644 index 000000000..0abef586c --- /dev/null +++ b/linphone/exosip/sdp_offans.c @@ -0,0 +1,333 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" + +extern eXosip_t eXosip; + +osip_list_t *supported_codec = NULL; + +int eXosip_sdp_accept_audio_codec(osip_negotiation_ctx_t *context, + char *port, char *number_of_port, + int audio_qty, char *payload); +int eXosip_sdp_accept_video_codec(osip_negotiation_ctx_t *context, + char *port, char *number_of_port, + int video_qty, char *payload); +int eXosip_sdp_accept_other_codec(osip_negotiation_ctx_t *context, + char *type, char *port, + char *number_of_port, char *payload); + +char *eXosip_sdp_get_audio_port(osip_negotiation_ctx_t *context, int pos_media); + +int eXosip_sdp_accept_audio_codec(osip_negotiation_ctx_t *context, + char *port, char *number_of_port, + int audio_qty, char *payload) +{ + int pos; + for (pos=0;!osip_list_eol(supported_codec, pos);pos++) + { + char *_payload; + _payload = osip_list_get(supported_codec, pos); + if (0==strcmp(payload,_payload)) + { + /* + We have to look at the rtpmap attributes in context->remote + to check if we support this stuff. + */ + + return 0; + } + } + return -1; +} + +int eXosip_sdp_accept_video_codec(osip_negotiation_ctx_t *context, + char *port, char *number_of_port, + int video_qty, char *payload) +{ + return -1; +} + +int eXosip_sdp_accept_other_codec(osip_negotiation_ctx_t *context, + char *type, char *port, + char *number_of_port, char *payload) +{ + /* ... */ + return -1; +} + +char *eXosip_sdp_get_audio_port(osip_negotiation_ctx_t *context, int pos_media) +{ + eXosip_call_t *jc = (eXosip_call_t*)osip_negotiation_ctx_get_mycontext(context); + if (jc==NULL) + return osip_strdup("10500"); + else if (jc->c_sdp_port[0]=='\0') + return osip_strdup("10500"); + else return osip_strdup(jc->c_sdp_port); +} + +int eXosip_sdp_negotiation_replace(osip_negotiation_t *sn) +{ + if (eXosip.osip_negotiation!=NULL) + osip_negotiation_free(eXosip.osip_negotiation); + eXosip.osip_negotiation = sn; + return 0; +} + +void +eXosip_sdp_negotiation_ctx_set_mycontext(struct eXosip_call_t *jc, void *arg) +{ + osip_negotiation_ctx_set_mycontext(jc->c_ctx, arg); +} + +void eXosip_sdp_negotiation_remove_audio_payloads() +{ + if (supported_codec==NULL) + return; + for (;!osip_list_eol(supported_codec, 0);) + { + char *p; + p = (char *) osip_list_get(supported_codec, 0); + osip_free(p); + osip_list_remove(supported_codec, 0); + } + osip_negotiation_remove_audio_payloads(eXosip.osip_negotiation); +} + +void eXosip_sdp_negotiation_add_codec(char *payload, char *number_of_port, + char *proto, char *c_nettype, + char *c_addrtype, char *c_addr, + char *c_addr_multicast_ttl, + char *c_addr_multicast_int, + char *a_rtpmap) +{ + osip_negotiation_add_support_for_audio_codec(eXosip.osip_negotiation, + payload, + number_of_port, + proto, + c_nettype, + c_addrtype, + c_addr, + c_addr_multicast_ttl, + c_addr_multicast_int, + a_rtpmap); + osip_list_add(supported_codec, osip_strdup(payload), -1); +} + +int eXosip_sdp_negotiation_init(osip_negotiation_t **sn) +{ + int i = osip_negotiation_init(sn); + if (i!=0) { + return -1; + } + if (supported_codec==NULL) + { + supported_codec = (osip_list_t*) osip_malloc(sizeof(osip_list_t)); + osip_list_init(supported_codec); + } + osip_negotiation_set_o_username(*sn, osip_strdup("userX")); + osip_negotiation_set_o_session_id(*sn, osip_strdup("20000001")); + osip_negotiation_set_o_session_version(*sn, osip_strdup("20000001")); + osip_negotiation_set_o_nettype(*sn, osip_strdup("IN")); + osip_negotiation_set_o_addrtype(*sn, osip_strdup("IP4")); + osip_negotiation_set_o_addr(*sn, osip_strdup(eXosip.localip)); + + osip_negotiation_set_c_nettype(*sn, osip_strdup("IN")); + osip_negotiation_set_c_addrtype(*sn, osip_strdup("IP4")); + osip_negotiation_set_c_addr(*sn, osip_strdup(eXosip.localip)); + + /* ALL CODEC MUST SHARE THE SAME "C=" line and proto as the media + will appear on the same "m" line... */ + + osip_negotiation_set_fcn_accept_audio_codec(*sn, &eXosip_sdp_accept_audio_codec); + osip_negotiation_set_fcn_accept_video_codec(*sn, &eXosip_sdp_accept_video_codec); + + osip_negotiation_set_fcn_accept_other_codec(*sn, &eXosip_sdp_accept_other_codec); + osip_negotiation_set_fcn_get_audio_port(*sn, &eXosip_sdp_get_audio_port); + + return 0; +} + +void eXosip_sdp_negotiation_free(osip_negotiation_t *sn) +{ + if (sn==NULL) + return; + osip_list_ofchar_free(supported_codec); + supported_codec = NULL; + osip_negotiation_free(sn); +} + +sdp_message_t * +eXosip_get_local_sdp_info(osip_transaction_t *invite_tr) +{ + osip_content_type_t *ctt; + osip_mime_version_t *mv; + osip_message_t *message; + sdp_message_t *sdp; + osip_body_t *oldbody; + int pos; + + if (invite_tr->ctx_type == IST) + message = invite_tr->last_response; + else if (invite_tr->ctx_type == ICT) + message = invite_tr->orig_request; + else return NULL; /* BUG -> NOT AN INVITE TRANSACTION!! */ + + if (message==NULL) return NULL; + + /* get content-type info */ + ctt = osip_message_get_content_type(message); + mv = osip_message_get_mime_version(message); + if (mv==NULL && ctt==NULL) + return NULL; /* previous message was not correct or empty */ + if (mv!=NULL) + { + /* look for the SDP body */ + /* ... */ + } + else if (ctt!=NULL) + { + if (ctt->type==NULL || ctt->subtype==NULL) + /* it can be application/sdp or mime... */ + return NULL; + if (osip_strcasecmp(ctt->type, "application")!=0 || + osip_strcasecmp(ctt->subtype, "sdp")!=0 ) + { return NULL; } + } + + pos=0; + while (!osip_list_eol(message->bodies, pos)) + { + int i; + oldbody = (osip_body_t *) osip_list_get(message->bodies, pos); + pos++; + sdp_message_init(&sdp); + i = sdp_message_parse(sdp,oldbody->body); + if (i==0) return sdp; + sdp_message_free(sdp); + sdp = NULL; + } + return NULL; +} + +sdp_message_t * +eXosip_get_remote_sdp_info(osip_transaction_t *invite_tr) +{ + osip_content_type_t *ctt; + osip_mime_version_t *mv; + osip_message_t *message; + sdp_message_t *sdp; + osip_body_t *oldbody; + int pos; + + if (invite_tr->ctx_type == IST) + message = invite_tr->orig_request; + else if (invite_tr->ctx_type == ICT) + message = invite_tr->last_response; + else return NULL; /* BUG -> NOT AN INVITE TRANSACTION!! */ + + if (message==NULL) return NULL; + + /* get content-type info */ + ctt = osip_message_get_content_type(message); + mv = osip_message_get_mime_version(message); + if (mv==NULL && ctt==NULL) + return NULL; /* previous message was not correct or empty */ + if (mv!=NULL) + { + /* look for the SDP body */ + /* ... */ + } + else if (ctt!=NULL) + { + if (ctt->type==NULL || ctt->subtype==NULL) + /* it can be application/sdp or mime... */ + return NULL; + if (osip_strcasecmp(ctt->type, "application")!=0 || + osip_strcasecmp(ctt->subtype, "sdp")!=0 ) + { return NULL; } + } + + pos=0; + while (!osip_list_eol(message->bodies, pos)) + { + int i; + oldbody = (osip_body_t *) osip_list_get(message->bodies, pos); + pos++; + sdp_message_init(&sdp); + i = sdp_message_parse(sdp,oldbody->body); + if (i==0) return sdp; + sdp_message_free(sdp); + sdp = NULL; + } + return NULL; +} + +int eXosip_retrieve_sdp_negotiation_result(osip_negotiation_ctx_t *ctx, char *payload_name, int pnsize) +{ + sdp_message_t *local_sdp = 0; + int payload_result = -1; + + if (!ctx) + return payload_result; + + local_sdp = osip_negotiation_ctx_get_local_sdp(ctx); + + if (local_sdp != NULL) + { + sdp_media_t *med = (sdp_media_t*) osip_list_get(local_sdp->m_medias, 0); + char *payload = (char *) osip_list_get (med->m_payloads, 0); + int pos_attr; + + if (payload!=NULL) + { + payload_result = osip_atoi(payload); + + /* copy payload name! */ + for (pos_attr=0; + !osip_list_eol(med->a_attributes, pos_attr); + pos_attr++) + { + sdp_attribute_t *attr; + attr = (sdp_attribute_t *)osip_list_get(med->a_attributes, pos_attr); + if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6)) + { + if ((payload_result <10 && + 0==osip_strncasecmp(attr->a_att_value, payload, 1)) + ||(payload_result>9 && payload_result<100 && + 0==osip_strncasecmp(attr->a_att_value, payload, 2)) + ||(payload_result >100 && payload_result<128 && + 0==osip_strncasecmp(attr->a_att_value, payload, 3))) + { + snprintf(payload_name, pnsize, "%s", attr->a_att_value); + return payload_result; + } + } + } + } + } + + return payload_result; + +} diff --git a/linphone/exosip/udp.c b/linphone/exosip/udp.c new file mode 100644 index 000000000..e192c2646 --- /dev/null +++ b/linphone/exosip/udp.c @@ -0,0 +1,2635 @@ +/* + eXosip - This is the eXtended osip library. + Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org + + eXosip is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + eXosip is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifdef ENABLE_MPATROL +#include +#endif + +#include "eXosip2.h" +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#ifdef __APPLE_CC__ +#include +#endif +#else +#include +#include +#endif + +extern eXosip_t eXosip; + +/* Private functions */ +static void eXosip_send_default_answer(eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, + int status, + char *reason_phrase, + char *warning, + int line); +static void eXosip_process_info(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_options(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_bye(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_refer(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_ack(eXosip_call_t *jc, eXosip_dialog_t *jd, osip_event_t *evt); +static int cancel_match_invite(osip_transaction_t *invite, osip_message_t *cancel); +static void eXosip_process_cancel(osip_transaction_t *transaction, osip_event_t *evt); +static osip_event_t *eXosip_process_reinvite(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *remote_sdp); +static void eXosip_process_invite_on_hold(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *sdp); +static void eXosip_process_invite_off_hold(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *sdp); +static void eXosip_process_new_options(osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_new_invite(osip_transaction_t *transaction, osip_event_t *evt); +static void eXosip_process_invite_within_call(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt); +static int eXosip_event_package_is_supported(osip_transaction_t *transaction, + osip_event_t *evt); +static void eXosip_process_new_subscribe(osip_transaction_t *transaction, + osip_event_t *evt); +static void eXosip_process_subscribe_within_call(eXosip_notify_t *jn, + eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt); +static void eXosip_process_notify_within_dialog(eXosip_subscribe_t *js, + eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt); +static int eXosip_match_notify_for_subscribe(eXosip_subscribe_t *js, osip_message_t *notify); +static void eXosip_process_newrequest(osip_event_t *evt); +static void eXosip_process_response_out_of_transaction(osip_event_t *evt); +static int eXosip_pendingosip_transaction_exist(eXosip_call_t *jc, eXosip_dialog_t *jd); +static int eXosip_release_finished_calls(eXosip_call_t *jc, eXosip_dialog_t *jd); +static int eXosip_release_aborted_calls(eXosip_call_t *jc, eXosip_dialog_t *jd); + + +static void eXosip_send_default_answer(eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, + int status, + char *reason_phrase, + char *warning, + int line) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + /* osip_list_add(eXosip.j_transactions, transaction, 0); */ + osip_transaction_set_your_instance(transaction, NULL); + + /* THIS METHOD DOES NOT ACCEPT STATUS CODE BETWEEN 101 and 299 */ + if (status>100 && status<299 && MSG_IS_INVITE(evt->sip)) + return ; + + if (jd!=NULL) + i = _eXosip_build_response_default(&answer, jd->d_dialog, status, evt->sip); + else + i = _eXosip_build_response_default(&answer, NULL, status, evt->sip); + + if (i!=0 || answer==NULL) + { + return ; + } + + if (reason_phrase!=NULL) + { + char *_reason; + _reason = osip_message_get_reason_phrase(answer); + if (_reason!=NULL) + osip_free(_reason); + _reason = osip_strdup(reason_phrase); + osip_message_set_reason_phrase(answer, _reason); + } + + osip_message_set_content_length(answer, "0"); + + if (status==500) + osip_message_set_retry_after(answer, "10"); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); + +} + +static void +__eXosip_report_event(int evt, eXosip_call_t *jc, eXosip_dialog_t *jd, eXosip_event_t *je ) +{ + if (!je) + je = eXosip_event_init_for_call(evt, jc, jd); + + if (eXosip.j_call_callbacks[evt]!=NULL) + eXosip.j_call_callbacks[evt](evt, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); +} + + +static void eXosip_process_options(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + osip_transaction_set_your_instance(transaction, + __eXosip_new_jinfo(jc, + NULL /*jd */, + NULL, + NULL)); + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction , 0); + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); +} + +static void eXosip_process_info(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + osip_transaction_set_your_instance(transaction, + __eXosip_new_jinfo(jc, + jd, + NULL, + NULL)); + /* for now, send default response of 200ok. eventually, application should + be deciding how to answer INFO messages */ + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction , 0); + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); +} + + +static void eXosip_process_bye(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + osip_transaction_set_your_instance(transaction, + __eXosip_new_jinfo(jc, + NULL /*jd */, + NULL, + NULL)); + + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + osip_message_set_content_length(answer, "0"); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction , 0); + + /* Release the eXosip_dialog */ + osip_dialog_free(jd->d_dialog); + jd->d_dialog = NULL; + __eXosip_report_event(EXOSIP_CALL_CLOSED, jc, jd, NULL); + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); +} + +static void eXosip_process_refer(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + osip_header_t *referto_head = NULL; + osip_contact_t *referto; + int i; + + /* check if the refer is valid */ + osip_message_header_get_byname(evt->sip, "refer-to", 0, &referto_head); + if (referto_head==NULL || referto_head->hvalue==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, "Missing Refer-To header", "Missing Refer-To header", __LINE__); + return; + } + /* check if refer-to is well-formed */ + osip_contact_init(&referto); + i = osip_contact_parse(referto, referto_head->hvalue); + if (i!=0) + { + osip_contact_free(referto); + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, "Non valid Refer-To header", "Non valid Refer-To header", __LINE__); + return; + } + if (0!=osip_strcasecmp(referto->url->scheme, "sip")) + { + osip_contact_free(referto); + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 501, "Scheme Not Implemented", "Scheme Not Implemented", __LINE__); + return; + } + + osip_contact_free(referto); + + /* check policy so we can decline immediatly the refer */ + + osip_transaction_set_your_instance(transaction, + __eXosip_new_jinfo(jc, + jd, + NULL, + NULL)); + + i = _eXosip_build_response_default(&answer, jd->d_dialog, 202, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction , 0); + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); + + _eXosip_transfer_send_notify(jc, jd, EXOSIP_SUBCRSTATE_ACTIVE, "SIP/2.0 100 Trying"); +} + +static void eXosip_process_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + osip_transaction_t *ref; + osip_header_t *event_hdr; + osip_header_t *sub_state; + osip_content_type_t *ctype; + osip_body_t *body = NULL; + + /* get the event type and return "489 Bad Event". */ + osip_message_header_get_byname(evt->sip, "event", 0, &event_hdr); + if (event_hdr==NULL || event_hdr->hvalue==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 481, "Missing Event header in Notify", "Missing Event header in Notify", __LINE__); + return ; + } + if (0!=osip_strcasecmp(event_hdr->hvalue, "refer")) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 501, "Unsupported Event header", "Unsupported Event header in Notify", __LINE__); + return ; + } + osip_message_header_get_byname(evt->sip, "subscription-state", + 0, + &sub_state); + if (sub_state==NULL||sub_state->hvalue==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, NULL, NULL, __LINE__); + return; + } + + ctype = osip_message_get_content_type(evt->sip); + if (ctype==NULL || ctype->type==NULL || ctype->subtype==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, "Missing Header", "Missing Content-Type Header", __LINE__); + return ; + } + if (0!=osip_strcasecmp(ctype->type, "message") + || 0!=osip_strcasecmp(ctype->subtype, "sipfrag")) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 501, "Unsupported body type", "Unsupported body type", __LINE__); + return ; + } + + osip_message_get_body(evt->sip, 0, &body); + if (body==NULL || body->body==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, "Missing Body", "Missing Body", __LINE__); + return ; + } + + + { + eXosip_event_t *je; + int len; + je = eXosip_event_init_for_call(EXOSIP_CALL_REFER_STATUS, jc, jd); + if (je==NULL) return; + + len = strlen(body->body); + if (len<999) + osip_strncpy(je->sdp_body, body->body, len); + else + osip_strncpy(je->sdp_body, body->body, 999); + + __eXosip_report_event(EXOSIP_CALL_REFER_STATUS, NULL, NULL, je); + } + + /* check if a refer was sent previously! */ + ref = eXosip_find_last_out_refer(jc, jd); + if (ref==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 481, NULL, "Not associated refer", __LINE__); + return ; + } + + osip_transaction_set_your_instance(transaction, + __eXosip_new_jinfo(jc, + jd, + NULL, + NULL)); + /* for now, send default response of 200ok. eventually, application should + be deciding how to answer INFO messages */ + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction , 0); + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); +} + +static void eXosip_process_ack(eXosip_call_t *jc, eXosip_dialog_t *jd, osip_event_t *evt) +{ + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_ACK, jc, jd); + if (je==NULL) return; + + /* MBW - for SDP in ACK used in alternate SDP offer-response model */ + eXosip_event_add_sdp_info(je, evt->sip); + __eXosip_report_event(EXOSIP_CALL_ACK, NULL, NULL, je); + + osip_event_free(evt); +} + +static int cancel_match_invite(osip_transaction_t *invite, osip_message_t *cancel) +{ + osip_generic_param_t *br; + osip_generic_param_t *br2; + osip_via_t *via; + osip_via_param_get_byname (invite->topvia, "branch", &br); + via = osip_list_get(cancel->vias, 0); + if (via==NULL) return -1; /* request without via??? */ + osip_via_param_get_byname (via, "branch", &br2); + if (br!=NULL && br2==NULL) + return -1; + if (br2!=NULL && br==NULL) + return -1; + if (br2!=NULL && br!=NULL) /* compliant UA :) */ + { + if (br->gvalue!=NULL && br2->gvalue!=NULL && + 0==strcmp(br->gvalue, br2->gvalue)) + return 0; + return -1; + } + /* old backward compatibility mechanism */ + if (0 != osip_call_id_match (invite->callid, cancel->call_id)) + return -1; + if (0 != osip_to_tag_match (invite->to, cancel->to)) + return -1; + if (0 != osip_from_tag_match (invite->from, cancel->from)) + return -1; + if (0 != osip_cseq_match (invite->cseq, cancel->cseq)) + return -1; + if (0 != osip_via_match (invite->topvia, via)) + return -1; + return 0; +} + +static void eXosip_process_cancel(osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_transaction_t *tr; + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + eXosip_call_t *jc; + eXosip_dialog_t *jd; + + tr = NULL; + jd = NULL; + /* first, look for a Dialog in the map of element */ + for (jc = eXosip.j_calls; jc!= NULL ; jc=jc->next) + { + if (jc->c_inc_tr!=NULL) + { + i = cancel_match_invite(jc->c_inc_tr, evt->sip); + if (i==0) { + tr = jc->c_inc_tr; + break; + } + } + tr=NULL; + for (jd = jc->c_dialogs; jd!= NULL ; jd=jd->next) + { + int pos=0; + while (!osip_list_eol(jd->d_inc_trs, pos)) + { + tr = osip_list_get(jd->d_inc_trs, pos); + i = cancel_match_invite(tr, evt->sip); + if (i==0) + break; + tr = NULL; + pos++; + } + } + if (jd!=NULL) break; /* tr has just been found! */ + } + + if (tr==NULL) /* we didn't found the transaction to cancel */ + { + i = _eXosip_build_response_default(&answer, NULL, 481, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot cancel transaction.\n")); + osip_list_add(eXosip.j_transactions, tr, 0); + osip_transaction_set_your_instance(tr, NULL); + return ; + } + osip_message_set_content_length(answer, "0"); + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction,evt_answer); + + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + __eXosip_wakeup(); + return; + } + + if (tr->state==IST_TERMINATED || tr->state==IST_CONFIRMED + || tr->state==IST_COMPLETED) + { + /* I can't find the status code in the rfc? + (I read I must answer 200? wich I found strange) + I probably misunderstood it... and prefer to send 481 + as the transaction has been answered. */ + if (jd==NULL) + i = _eXosip_build_response_default(&answer, NULL, 481, evt->sip); + else + i = _eXosip_build_response_default(&answer, jd->d_dialog, 481, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot cancel transaction.\n")); + osip_list_add(eXosip.j_transactions, tr, 0); + osip_transaction_set_your_instance(tr, NULL); + return ; + } + osip_message_set_content_length(answer, "0"); + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction,evt_answer); + + if (jd!=NULL) + osip_list_add(jd->d_inc_trs, transaction , 0); + else + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + __eXosip_wakeup(); + + return ; + } + + { + if (jd==NULL) + i = _eXosip_build_response_default(&answer, NULL, 200, evt->sip); + else + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot cancel transaction.\n")); + osip_list_add(eXosip.j_transactions, tr, 0); + osip_transaction_set_your_instance(tr, NULL); + return ; + } + osip_message_set_content_length(answer, "0"); + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); + + if (jd!=NULL) + osip_list_add(jd->d_inc_trs, transaction , 0); + else + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + + /* answer transaction to cancel */ + if (jd==NULL) + i = _eXosip_build_response_default(&answer, NULL, 487, + tr->orig_request); + else + i = _eXosip_build_response_default(&answer, jd->d_dialog, 487, + tr->orig_request); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot cancel transaction.\n")); + osip_list_add(eXosip.j_transactions, tr, 0); + osip_transaction_set_your_instance(tr, NULL); + return ; + } + osip_message_set_content_length(answer, "0"); + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = tr->transactionid; + osip_transaction_add_event(tr,evt_answer); + __eXosip_wakeup(); + } +} + +static osip_event_t * +eXosip_process_reinvite(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *remote_sdp) +{ + sdp_message_t *local_sdp; + osip_message_t *answer; + osip_event_t *sipevent; + int i; + + /* We must negociate... */ + local_sdp = NULL; + if (remote_sdp!=NULL) { + sdp_message_t *old_remote_sdp = osip_negotiation_ctx_get_remote_sdp(jc->c_ctx); + if (old_remote_sdp!=NULL) + { + sdp_message_free(old_remote_sdp); + } + osip_negotiation_ctx_set_remote_sdp(jc->c_ctx, remote_sdp); + local_sdp = osip_negotiation_ctx_get_local_sdp(jc->c_ctx); + if (local_sdp!=NULL) + { + sdp_message_free(local_sdp); + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, NULL); + } + local_sdp = NULL; + i = osip_negotiation_ctx_execute_negotiation(eXosip.osip_negotiation, jc->c_ctx); + + if (i!=200) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, i, NULL, NULL, 0); + return NULL; + } + local_sdp = osip_negotiation_ctx_get_local_sdp(jc->c_ctx); + } + +#if 0 + if (remote_sdp==NULL) + { + sdp_message_t *local_sdp; + osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &local_sdp, "25563", NULL); + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, local_sdp); + + if (local_sdp==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, NULL, NULL, __LINE__); + return NULL; + } + } +#endif + + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SIP Error", "Failed to build Answer for INVITE within call", __LINE__); + return NULL; + } + + complete_answer_that_establish_a_dialog(answer, evt->sip); + + if (local_sdp!=NULL) + { + char *local_body; + char *size; + + osip_negotiation_ctx_set_local_sdp(jc->c_ctx, NULL); + i = sdp_message_to_str(local_sdp, &local_body); + sdp_message_free(local_sdp); + if (i!=0) { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SDP Error", "SDP packet is corrupted", __LINE__); + osip_message_free(answer); + return NULL; + } + i = osip_message_set_body(answer, local_body, strlen(local_body)); + if (i!=0) { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SDP Error", "SDP cannot be added in message", __LINE__); + osip_free(local_body); + osip_message_free(answer); + return NULL; + } + size = (char *) osip_malloc(6*sizeof(char)); +#ifdef __APPLE_CC__ + sprintf(size,"%li",strlen(local_body)); +#else + sprintf(size,"%i",strlen(local_body)); +#endif + osip_free(local_body); + osip_message_set_content_length(answer, size); + osip_free(size); + i = osip_message_set_content_type(answer, "application/sdp"); + if (i!=0) { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SIP Error", "Content-Type cannot be added in message", __LINE__); + osip_message_free(answer); + return NULL; + } + + } + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + sipevent = osip_new_outgoing_sipmessage(answer); + sipevent->transactionid = transaction->transactionid; + + osip_list_add(jd->d_inc_trs, transaction, 0); + return sipevent; +} + + +static void eXosip_process_invite_on_hold(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *sdp) +{ + osip_event_t *sipevent; + sipevent = eXosip_process_reinvite(jc, jd, transaction, evt, sdp); + if (sipevent==NULL) + return; /* ERROR */ + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_HOLD, jc, jd); + eXosip_event_add_status(je, sipevent->sip); + eXosip_event_add_sdp_info(je, evt->sip); + __eXosip_report_event(EXOSIP_CALL_HOLD, NULL, NULL, je); + } + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); +} + +static void eXosip_process_invite_off_hold(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt, sdp_message_t *sdp) +{ + osip_event_t *sipevent; + sipevent = eXosip_process_reinvite(jc, jd, transaction, evt, sdp); + if (sipevent==NULL) + return; /* ERROR */ + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_OFFHOLD, jc, jd); + eXosip_event_add_status(je, sipevent->sip); + eXosip_event_add_sdp_info(je, evt->sip); + __eXosip_report_event(EXOSIP_CALL_OFFHOLD, NULL, NULL, je); + } + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); +} + +static void eXosip_process_new_options(osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + + i = _eXosip_build_response_default(&answer, NULL, 200, evt->sip); + if (i!=0) + { + return ; + } + + osip_list_add(eXosip.j_transactions, transaction, 0); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_transaction_add_event(transaction,evt_answer); + __eXosip_wakeup(); +} + +static void eXosip_process_new_invite(osip_transaction_t *transaction, osip_event_t *evt) +{ + osip_event_t *evt_answer; + int i; + eXosip_call_t *jc; + eXosip_dialog_t *jd; + osip_message_t *answer; + + eXosip_call_init(&jc); + /* eXosip_call_set_subect... */ + + ADD_ELEMENT(eXosip.j_calls, jc); + + i = _eXosip_build_response_default(&answer, NULL, 101, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog.")); + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n")); + return; + } + osip_message_set_content_length(answer, "0"); + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot complete answer!\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + osip_message_free(answer); + return ; + } + + i = eXosip_dialog_init_as_uas(&jd, evt->sip, answer); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + osip_message_free(answer); + return ; + } + ADD_ELEMENT(jc->c_dialogs, jd); + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jc, jd, NULL, NULL)); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; +#ifdef AUTO_RING /* default is now to not send a 180 Ringing */ + osip_transaction_add_event(transaction, evt_answer); + __eXosip_wakeup(); +#endif + +#ifdef AUTO_RING /* default is now to not send a 180 Ringing */ + i = _eXosip_build_response_default(&answer, jd->d_dialog, 180, evt->sip); + + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot send ringback.")); + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n")); + return; + } + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot complete answer!\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_transaction_set_your_instance(transaction, NULL); + osip_message_free(answer); + return ; + } + + osip_message_set_content_length(answer, "0"); + /* send message to transaction layer */ + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; +#endif + + eXosip_update(); + jc->c_inc_tr = transaction; + osip_transaction_add_event(transaction, evt_answer); + + /* be sure the invite will be processed + before any API call on this dialog*/ + osip_ist_execute(eXosip.j_osip); + + if (transaction->orig_request!=NULL) + { + eXosip_event_t *je; + je = eXosip_event_init_for_call(EXOSIP_CALL_NEW, jc, jd); + if (je!=NULL) + { + osip_header_t *subject; + char *tmp; + osip_message_get_subject(transaction->orig_request, 0, &subject); + if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0') + snprintf(je->subject, 255, "%s", subject->hvalue); + osip_uri_to_str(transaction->orig_request->req_uri, &tmp); + if (tmp!=NULL) + { + snprintf(je->req_uri, 255, "%s", tmp); + osip_free(tmp); + } + eXosip_event_add_sdp_info(je, transaction->orig_request); + eXosip_event_add_status(je, answer); + } + __eXosip_report_event(EXOSIP_CALL_NEW, NULL, NULL, je); + } + + __eXosip_wakeup(); + +} + +static void eXosip_process_invite_within_call(eXosip_call_t *jc, eXosip_dialog_t *jd, + osip_transaction_t *transaction, osip_event_t *evt) +{ + sdp_message_t *sdp; + int i; + int pos; + int pos_media; + char *sndrcv; + char *ipaddr; + + /* Is this a "on hold" message? */ + sdp = NULL; + pos = 0; + i = 500; + while (!osip_list_eol(evt->sip->bodies,pos)) + { + osip_body_t *body; + body = (osip_body_t *)osip_list_get(evt->sip->bodies,pos); + pos++; + + i = sdp_message_init(&sdp); + if (i!=0) break; + + /* WE ASSUME IT IS A SDP BODY AND THAT */ + /* IT IS THE ONLY ONE, OF COURSE, THIS IS */ + /* NOT TRUE */ + if (body->body!=NULL) + { + i = sdp_message_parse(sdp,body->body); + if (i==0) { + i = 200; + break; + } + } + sdp_message_free(sdp); + sdp = NULL; + } + + if (pos!=0 && i!=200) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, NULL, NULL, __LINE__); + return; + } + + /* TODO: we should verify the content-type */ + if (pos!=0) + { + pos_media=-1; + pos = 0; + ipaddr = NULL; + while (!sdp_message_endof_media(sdp, pos_media)) + { + ipaddr = sdp_message_c_addr_get(sdp, pos_media, pos); + while (ipaddr!=NULL) /* only one is allowed here? */ + { + if (pos==1 && pos_media==-1) + break; + if (0==osip_strcasecmp("0.0.0.0", ipaddr)) + break; + pos++; + ipaddr = sdp_message_c_addr_get(sdp, pos_media, pos); + } + if (pos==1 && pos_media==-1) + ipaddr=NULL; + if (ipaddr!=NULL) + break; + pos = 0; + pos_media++; + } + + if (ipaddr==NULL) + { + sndrcv = NULL; + pos_media=-1; + pos = 0; + while (!sdp_message_endof_media(sdp, pos_media)) + { + sndrcv = sdp_message_a_att_field_get(sdp, pos_media, pos); + while (sndrcv!=NULL) + { + if (0==osip_strcasecmp("inactive", sndrcv) || 0==osip_strcasecmp("sendonly", sndrcv)) + break; + pos++; + sndrcv = sdp_message_a_att_field_get(sdp, pos_media, pos); + } + if (sndrcv!=NULL) + break; + pos = 0; + pos_media++; + } + } + + if (ipaddr!=NULL || (sndrcv!=NULL && (0==osip_strcasecmp("inactive", sndrcv) + || 0==osip_strcasecmp("sendonly", sndrcv)))) + { + /* We received an INVITE to put on hold the other party. */ + eXosip_process_invite_on_hold(jc, jd, transaction, evt, sdp); + return; + } + else + { + /* This is a call modification, probably for taking it of hold */ + eXosip_process_invite_off_hold(jc, jd, transaction, evt, sdp); + return; + } + } + eXosip_process_invite_off_hold(jc, jd, transaction, evt, NULL); + return; +} + +static int eXosip_event_package_is_supported(osip_transaction_t *transaction, + osip_event_t *evt) +{ + osip_header_t *event_hdr; + int code; + + /* get the event type and return "489 Bad Event". */ + osip_message_header_get_byname(evt->sip, "event", 0, &event_hdr); + if (event_hdr==NULL || event_hdr->hvalue==NULL) + { +#ifdef SUPPORT_MSN + /* msn don't show any event header */ + code = 200; /* Bad Request... anyway... */ +#else + code = 400; /* Bad Request */ +#endif + } + else if (0!=osip_strcasecmp(event_hdr->hvalue, "presence")) + code = 489; + else code = 200; + if (code!=200) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(NULL, transaction, evt, code, NULL, NULL, __LINE__); + return 0; + } + return -1; +} + +static void eXosip_process_new_subscribe(osip_transaction_t *transaction, + osip_event_t *evt) +{ + osip_event_t *evt_answer; + eXosip_notify_t *jn; + eXosip_dialog_t *jd; + osip_message_t *answer; + int code; + int i; + + eXosip_notify_init(&jn, evt->sip); + _eXosip_notify_set_refresh_interval(jn, evt->sip); + + i = _eXosip_build_response_default(&answer, NULL, 101, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog.")); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_notify_free(jn); + return; + } + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + if (i!=0) + { + osip_message_free(answer); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot complete answer!\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_notify_free(jn); + return ; + } + + i = eXosip_dialog_init_as_uas(&jd, evt->sip, answer); + if (i!=0) + { + osip_message_free(answer); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot create dialog!\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_notify_free(jn); + return ; + } + ADD_ELEMENT(jn->n_dialogs, jd); + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, NULL, jn)); + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction, evt_answer); + + ADD_ELEMENT(eXosip.j_notifies, jn); + __eXosip_wakeup(); + + /* There should be a list of already accepted freinds for which we + have already accepted the subscription. */ + if (0==_eXosip_notify_is_a_known_subscriber(evt->sip)) + code = 200; + else + code = 202; + + i = _eXosip_build_response_default(&answer, jd->d_dialog, code, evt->sip); + if (i!=0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n")); + osip_list_add(eXosip.j_transactions, transaction, 0); + return; + } + + _eXosip_notify_add_expires_in_2XX_for_subscribe(jn, answer); + + { + + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + osip_message_free(answer); + return; + } + } + + jn->n_inc_tr = transaction; + + /* eXosip_dialog_set_200ok(jd, answer); */ + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_transaction_add_event(transaction, evt_answer); + + osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); + + eXosip_update(); + __eXosip_wakeup(); +} + +static void eXosip_process_subscribe_within_call(eXosip_notify_t *jn, + eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt) +{ + osip_message_t *answer; + osip_event_t *sipevent; + int i; + + _eXosip_notify_set_refresh_interval(jn, evt->sip); + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SIP Error", "Failed to build Answer for SUBSCRIBE", __LINE__); + return ; + } + + _eXosip_notify_add_expires_in_2XX_for_subscribe(jn, answer); + + { + + i = complete_answer_that_establish_a_dialog(answer, evt->sip); + if (i!=0) + { + /* this info is yet known by the remote UA, + so we don't have to exit here */ + } + } + + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, NULL, jn)); + sipevent = osip_new_outgoing_sipmessage(answer); + sipevent->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction, sipevent); + __eXosip_wakeup(); + + /* if subscribe request contains expires="0", close the subscription */ + { + int now = time(NULL); + if (jn->n_ss_expires-now<=0) + { + jn->n_ss_status=EXOSIP_SUBCRSTATE_TERMINATED; + jn->n_ss_reason=TIMEOUT; + } + } + + osip_list_add(jd->d_inc_trs, transaction, 0); + + eXosip_notify_send_notify(jn, jd, jn->n_ss_status, + jn->n_online_status); + return; +} + +static void +eXosip_process_notify_within_dialog(eXosip_subscribe_t *js, + eXosip_dialog_t *jd, + osip_transaction_t *transaction, + osip_event_t *evt) +{ + osip_message_t *answer; + osip_event_t *sipevent; + osip_header_t *sub_state; +#ifdef SUPPORT_MSN + osip_header_t *expires; +#endif + int i; + + if (jd==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SIP Error", "No dialog for this NOTIFY", __LINE__); + return ; + } + + /* if subscription-state has a reason state set to terminated, + we close the dialog */ +#ifndef SUPPORT_MSN + osip_message_header_get_byname(evt->sip, "subscription-state", + 0, + &sub_state); + if (sub_state==NULL||sub_state->hvalue==NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 400, NULL, NULL, __LINE__); + return; + } +#endif + + i = _eXosip_build_response_default(&answer, jd->d_dialog, 200, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Internal SIP Error", "Failed to build Answer for NOTIFY", __LINE__); + return ; + } + +#ifdef SUPPORT_MSN + osip_message_header_get_byname(evt->sip, "expires", + 0, + &expires); + if (expires!=NULL&&expires->hvalue!=NULL + && 0==osip_strcasecmp(expires->hvalue, "0")) + { + /* delete the dialog! */ + js->s_ss_status = EXOSIP_SUBCRSTATE_TERMINATED; + js->s_online_status = EXOSIP_NOTIFY_UNKNOWN; + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_NOTIFY, js, jd); + if (je!=NULL) + { + eXosip_event_add_status(je, answer); + } + + if (eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY]!=NULL) + eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY](EXOSIP_SUBSCRIPTION_NOTIFY, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } + + sipevent = osip_new_outgoing_sipmessage(answer); + sipevent->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction, sipevent); + + osip_list_add(eXosip.j_transactions, transaction, 0); + + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + __eXosip_wakeup(); + + return ; + } + else + { + osip_content_type_t *ctype; + osip_body_t *body = NULL; + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, js, NULL)); + js->s_ss_status = EXOSIP_SUBCRSTATE_ACTIVE; + js->s_online_status = EXOSIP_NOTIFY_UNKNOWN; /* default value */ + + ctype = osip_message_get_content_type(evt->sip); + if (ctype!=NULL && ctype->type!=NULL && ctype->subtype!=NULL) + { + if (0==osip_strcasecmp(ctype->type, "application") + && 0==osip_strcasecmp(ctype->subtype, "xpidf+xml")) + osip_message_get_body(evt->sip, 0, &body); + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Unknown body: %s/%s\n", + ctype->type, ctype->subtype)); + } + } + + if (body!=NULL) + { + /* search for the open string */ + char *tmp = body->body; + while (tmp[0]!='\0') + { + if (tmp[0]=='o' && 0==strncmp(tmp, "online", 6)) + { + js->s_online_status = EXOSIP_NOTIFY_ONLINE; + /* search for the contact entry */ + while (tmp[0]!='\0') + { + if (tmp[0]=='c' && 0==strncmp(tmp, "contact", 7)) + { + /* ... */ + } + tmp++; + } + break; + } + else if (tmp[0]=='b' && 0==strncmp(tmp, "busy", 4)) + { + js->s_online_status = EXOSIP_NOTIFY_BUSY; + break; + } + else if (tmp[0]=='b' && 0==strncmp(tmp, "berightback",11)) + { + js->s_online_status = EXOSIP_NOTIFY_BERIGHTBACK; + break; + } + else if (tmp[0]=='a' && 0==strncmp(tmp, "away", 4)) + { + js->s_online_status = EXOSIP_NOTIFY_AWAY; + break; + } + else if (tmp[0]=='o' && 0==strncmp(tmp, "onthephone", 10)) + { + js->s_online_status = EXOSIP_NOTIFY_ONTHEPHONE; + break; + } + else if (tmp[0]=='o' && 0==strncmp(tmp, "outtolunch", 10)) + { + js->s_online_status = EXOSIP_NOTIFY_OUTTOLUNCH; + break; + } + tmp++; + } + } + } +#else + /* modify the status of user */ + if (0==osip_strncasecmp(sub_state->hvalue, "active", 6)) + { + osip_content_type_t *ctype; + osip_body_t *body = NULL; + js->s_ss_status = EXOSIP_SUBCRSTATE_ACTIVE; + js->s_online_status = EXOSIP_NOTIFY_UNKNOWN; /* default value */ + + /* if there is a body which we understand, analyse it */ + ctype = osip_message_get_content_type(evt->sip); + if (ctype!=NULL && ctype->type!=NULL && ctype->subtype!=NULL) + { + if (0==osip_strcasecmp(ctype->type, "application") + && 0==osip_strcasecmp(ctype->subtype, "pidf+xml")) + osip_message_get_body(evt->sip, 0, &body); + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Unknown body: %s/%s\n", + ctype->type, ctype->subtype)); + } + } + + if (body!=NULL) + { + /* search for the open string */ + char *tmp = body->body; + while (tmp[0]!='\0') + { + if (tmp[0]=='o' && 0==osip_strncasecmp(tmp, "open", 4)) + { + js->s_online_status = EXOSIP_NOTIFY_ONLINE; + /* search for the contact entry */ + while (tmp[0]!='\0') + { + if (tmp[0]=='a' && 0==osip_strncasecmp(tmp, "away", 4)) + js->s_online_status = EXOSIP_NOTIFY_AWAY; + else if (tmp[0]=='m' && 0==osip_strncasecmp(tmp, "meal", 4)) + js->s_online_status = EXOSIP_NOTIFY_OUTTOLUNCH; + else if (tmp[0]=='i' && 0==osip_strncasecmp(tmp, "in-transit", 10)) + js->s_online_status = EXOSIP_NOTIFY_BERIGHTBACK; + else if (tmp[0]=='b' && 0==osip_strncasecmp(tmp, "busy", 4)) + js->s_online_status = EXOSIP_NOTIFY_BUSY; + else if (tmp[0]=='o' && 0==osip_strncasecmp(tmp, "on-the-phone", 12)) + js->s_online_status = EXOSIP_NOTIFY_ONTHEPHONE; + + if (tmp[0]=='/' && 0==osip_strncasecmp(tmp, "/status", 7)) + break; + if (js->s_online_status!=EXOSIP_NOTIFY_ONLINE) + break; + tmp++; + } + + while (tmp[0]!='\0') + { + if (tmp[0]=='c' && 0==osip_strncasecmp(tmp, "contact", 7)) + { + /* ... */ + } + tmp++; + } + break; + } + else if (tmp[0]=='c' && 0==osip_strncasecmp(tmp, "closed", 6)) + { + js->s_online_status = EXOSIP_NOTIFY_CLOSED; + break; + } + tmp++; + } + } + } + else if (0==osip_strncasecmp(sub_state->hvalue, "pending", 7)) + { + js->s_ss_status = EXOSIP_SUBCRSTATE_PENDING; + js->s_online_status = EXOSIP_NOTIFY_PENDING; + } + + if (0==osip_strncasecmp(sub_state->hvalue, "terminated", 10)) + { + /* delete the dialog! */ + js->s_ss_status = EXOSIP_SUBCRSTATE_TERMINATED; + js->s_online_status = EXOSIP_NOTIFY_UNKNOWN; + + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_NOTIFY, js, jd); + if (je!=NULL) + { + eXosip_event_add_status(je, answer); + } + + if (eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY]!=NULL) + eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY](EXOSIP_SUBSCRIPTION_NOTIFY, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } + + sipevent = osip_new_outgoing_sipmessage(answer); + sipevent->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction, sipevent); + + osip_list_add(eXosip.j_transactions, transaction, 0); + + REMOVE_ELEMENT(eXosip.j_subscribes, js); + eXosip_subscribe_free(js); + __eXosip_wakeup(); + return; + } + else + { + osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, js, NULL)); + } +#endif + + osip_list_add(jd->d_inc_trs, transaction, 0); + + sipevent = osip_new_outgoing_sipmessage(answer); + sipevent->transactionid = transaction->transactionid; + osip_transaction_add_event(transaction, sipevent); + + { + eXosip_event_t *je; + je = eXosip_event_init_for_subscribe(EXOSIP_SUBSCRIPTION_NOTIFY, js, jd); + if (je!=NULL) + { + eXosip_event_add_status(je, answer); + } + + if (eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY]!=NULL) + eXosip.j_call_callbacks[EXOSIP_SUBSCRIPTION_NOTIFY](EXOSIP_SUBSCRIPTION_NOTIFY, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } + + __eXosip_wakeup(); + return; +} + +static int +eXosip_match_notify_for_subscribe(eXosip_subscribe_t *js, osip_message_t *notify) +{ + osip_transaction_t *out_sub; + + if (js==NULL) + return -1; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Trying to match notify with subscribe\n")); + + out_sub = eXosip_find_last_out_subscribe(js, NULL); + if (out_sub==NULL || out_sub->orig_request==NULL) + return -1; + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "subscribe transaction found\n")); + + /* some checks to avoid crashing on bad requests */ + if (notify == NULL || notify->cseq == NULL + || notify->cseq->method == NULL || notify->to == NULL) + return -1; + + if (0 != osip_call_id_match (out_sub->callid, notify->call_id)) + return -1; + + { + /* The From tag of outgoing request must match + the To tag of incoming notify: + */ + osip_generic_param_t *tag_from; + osip_generic_param_t *tag_to; + + osip_from_param_get_byname (out_sub->from, "tag", &tag_from); + osip_from_param_get_byname (notify->to, "tag", &tag_to); + if (tag_to == NULL || tag_to->gvalue==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Uncompliant user agent: no tag in from of outgoing request\n")); + return -1; + } + if (tag_from == NULL || tag_to->gvalue==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Uncompliant user agent: no tag in to of incoming request\n")); + return -1; + } + + if (0 != strcmp (tag_from->gvalue, tag_to->gvalue)) + return -1; + } + + return 0; +} + +static void +eXosip_process_message_outside_of_dialog(osip_transaction_t *transaction, + osip_event_t *evt) +{ + osip_message_t *answer; + osip_event_t *evt_answer; + osip_header_t *expires, *date; + int i; + + /* Check whether the Expire time has been reached */ + + /* the Expires header is present ? */ + if (osip_message_get_expires(evt->sip, 0, &expires) != -1 && expires->hvalue!=NULL) + { + + unsigned long expires_ul; + time_t now_ts, date_ts; + + expires_ul = strtoul(expires->hvalue, (char**)NULL, 10); + now_ts = time(NULL); + + /* + ** A MESSAGE request is said to be expired if its expiration time has + ** passed. The expiration time is determined by examining the Expires + ** header field, if present. MESSAGE requests without an Expires header + ** field do not expire. If the MESSAGE request containing an Expires + ** header field also contains a Date header field, the UAS SHOULD + ** interpret the Expires header field value as delta time from the Date + ** header field value. If the request does not contain a Date header + ** field, the UAS SHOULD interpret the Expires header value as delta + ** time from the time the UAS received the request. + */ + + /* Does the message also contain a Date header ? */ + if (osip_message_get_date(evt->sip, 0, &date) != -1 && date->hvalue != NULL) + { + + /* + 20.17 Date + The Date header field contains the date and time. Unlike HTTP/1.1, + SIP only supports the most recent RFC 1123 [20] format for dates. + As in [H3.3], SIP restricts the time zone in SIP-date to "GMT", while + RFC 1123 allows any time zone. An RFC 1123 date is case-sensitive. + The Date header field reflects the time when the request or + response is first sent. + + The Date header field can be used by simple end systems without a + battery-backed clock to acquire a notion of current time. + However, in its GMT form, it requires clients to know their offset + from GMT. + + Example: + + Date: Sat, 13 Nov 2010 23:29:00 GMT + + 20.19 Expires + + The Expires header field gives the relative time after which the + message (or content) expires. + + The precise meaning of this is method dependent. + + The expiration time in an INVITE does not affect the duration of + the actual session that may result from the invitation. Session + description protocols may offer the ability to express time limits + on the session duration, however. + + The value of this field is an integral number of seconds (in decimal) + between 0 and (2**32)-1, measured from the receipt of the request. + + Example: + + Expires: 5 + + */ + + /* TODO: + date_ts = RECUPERE_TIMESTAMP(date->hvalue); + */ + + date_ts = time(NULL); + + /* Has the message expired ? */ + if (date_ts + expires_ul < now_ts) + { + /* discard old data. */ + return; + } + } + else if (expires_ul != 0) + { + /* No date header, but a not null Expires one: + ** TODO: Compare to the UAS reception time + */ + date_ts = transaction->birth_time; + } + /* The message has not expired */ + } + + /* We must create the event */ + { + eXosip_event_t *je; + je = eXosip_event_init_for_message(EXOSIP_MESSAGE_NEW, transaction, evt->sip); + i = _eXosip_build_response_default(&answer, NULL, SIP_OK, evt->sip); + if (i!=0) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + return ; + } + + if (je!=NULL) + { + int pos = 0; + osip_body_t *oldbody; + + eXosip_event_add_status(je, answer); + + while (!osip_list_eol(evt->sip->bodies, pos)) + { + int len; + oldbody = (osip_body_t *)osip_list_get(evt->sip->bodies, pos); + len = strlen(oldbody->body); + pos++; + + if (len<999) + osip_strncpy(je->sdp_body, oldbody->body, len); + else + osip_strncpy(je->sdp_body, oldbody->body, 999); + } + } + + if (eXosip.j_call_callbacks[EXOSIP_MESSAGE_NEW]!=NULL) + eXosip.j_call_callbacks[EXOSIP_MESSAGE_NEW](EXOSIP_MESSAGE_NEW, je); + else if (eXosip.j_runtime_mode==EVENT_MODE) + eXosip_event_add(je); + } + + /* finally, send the 200 OK response */ + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + osip_transaction_add_event(transaction, evt_answer); + +#ifdef NEW_TIMER + __eXosip_wakeup(); +#endif + return; +} + + +static void eXosip_process_newrequest (osip_event_t *evt) +{ + osip_transaction_t *transaction; + osip_event_t *evt_answer; + osip_message_t *answer; + int i; + int ctx_type; + eXosip_call_t *jc; + eXosip_subscribe_t *js; + eXosip_notify_t *jn; + eXosip_dialog_t *jd; + + if (MSG_IS_INVITE(evt->sip)) + { + ctx_type = IST; + } + else if (MSG_IS_ACK(evt->sip)) + { /* this should be a ACK for 2xx (but could be a late ACK!) */ + ctx_type = -1; +#if 0 /* ACK must be announced */ + osip_event_free(evt); + return ; +#endif + } + else if (MSG_IS_REQUEST(evt->sip)) + { + ctx_type = NIST; + } + else + { /* We should handle late response and 200 OK before coming here. */ + ctx_type = -1; + osip_event_free(evt); + return ; + } + + transaction=NULL; + if (ctx_type != -1) + { + i = osip_transaction_init(&transaction, + (osip_fsm_type_t)ctx_type, + eXosip.j_osip, + evt->sip); + if (i!=0) + { + osip_event_free(evt); + return ; + } + + evt->transactionid = transaction->transactionid; + osip_transaction_set_your_instance(transaction, NULL); + + i = _eXosip_build_response_default(&answer, NULL, 100, evt->sip); + if (i!=0) + { + __eXosip_delete_jinfo(transaction); + osip_transaction_free(transaction); + osip_event_free(evt); + return ; + } + + osip_message_set_content_length(answer, "0"); + /* send message to transaction layer */ + + evt_answer = osip_new_outgoing_sipmessage(answer); + evt_answer->transactionid = transaction->transactionid; + + /* add the REQUEST & the 100 Trying */ + osip_transaction_add_event(transaction, evt); + osip_transaction_add_event(transaction, evt_answer); + __eXosip_wakeup(); + } + + if (MSG_IS_CANCEL(evt->sip)) + { + /* special handling for CANCEL */ + /* in the new spec, if the CANCEL has a Via branch, then it + is the same as the one in the original INVITE */ + eXosip_process_cancel(transaction, evt); + return ; + } + + jd = NULL; + /* first, look for a Dialog in the map of element */ + for (jc = eXosip.j_calls; jc!= NULL ; jc=jc->next) + { + for (jd = jc->c_dialogs; jd!= NULL ; jd=jd->next) + { + if (jd->d_dialog!=NULL) + { + if (osip_dialog_match_as_uas(jd->d_dialog, evt->sip)==0) + break; + } + } + if (jd!=NULL) break; + } + + + if (jd!=NULL) + { + osip_transaction_t *old_trn; + /* it can be: + 1: a new INVITE offer. + 2: a REFER request from one of the party. + 2: a BYE request from one of the party. + 3: a REQUEST with a wrong CSeq. + 4: a NOT-SUPPORTED method with a wrong CSeq. + */ + + if (!MSG_IS_BYE(evt->sip)) + { + /* reject all requests for a closed dialog */ + old_trn = eXosip_find_last_inc_bye(jc, jd); + if (old_trn == NULL) + old_trn = eXosip_find_last_out_bye(jc, jd); + + if (old_trn!=NULL) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 481, NULL, NULL, __LINE__); + return ; + } + } + + if (MSG_IS_INVITE(evt->sip)) + { + /* the previous transaction MUST be freed */ + old_trn = eXosip_find_last_inc_invite(jc, jd); + + if (old_trn!=NULL && old_trn->state!=IST_TERMINATED) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Retry Later", "An INVITE is not terminated", __LINE__); + return ; + } + + old_trn = eXosip_find_last_out_invite(jc, jd); + if (old_trn!=NULL && old_trn->state!=ICT_TERMINATED) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 491, NULL, NULL, __LINE__); + return ; + } + + osip_dialog_update_osip_cseq_as_uas(jd->d_dialog, evt->sip); + osip_dialog_update_route_set_as_uas(jd->d_dialog, evt->sip); + + eXosip_process_invite_within_call(jc, jd, transaction, evt); + } + else if (MSG_IS_BYE(evt->sip)) + { + old_trn = eXosip_find_last_inc_bye(jc, jd); + + if (old_trn!=NULL) /* && old_trn->state!=NIST_TERMINATED) */ + { /* this situation should NEVER occur?? (we can't receive + two different BYE for one call! */ + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Call Already Terminated", "A pending BYE has already terminate this call", __LINE__); + return; + } + /* osip_transaction_free(old_trn); */ + eXosip_process_bye(jc, jd, transaction, evt); + } + else if (MSG_IS_ACK(evt->sip)) + { + eXosip_process_ack(jc, jd, evt); + } + else if (MSG_IS_REFER(evt->sip)) + { + eXosip_process_refer(jc, jd, transaction, evt); + } + else if (MSG_IS_OPTIONS(evt->sip)) + { + eXosip_process_options(jc, jd, transaction, evt); + } + else if (MSG_IS_INFO(evt->sip)) + { + eXosip_process_info(jc, jd, transaction, evt); + } + else if (MSG_IS_NOTIFY(evt->sip)) + { + eXosip_process_notify_for_refer(jc, jd, transaction, evt); + } + else + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 405, NULL, "Method Not Allowed", __LINE__); + } + return ; + } + + if (MSG_IS_ACK(evt->sip)) + { + /* no transaction has been found for this ACK! */ + osip_event_free(evt); + return; + } + + if (MSG_IS_INFO(evt->sip)) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 481, NULL, NULL, __LINE__); + return; /* fixed */ + } + if (MSG_IS_OPTIONS(evt->sip)) + { + eXosip_process_new_options(transaction, evt); + return; + } + else if (MSG_IS_INVITE(evt->sip)) + { + eXosip_process_new_invite(transaction, evt); + return; + } + else if (MSG_IS_BYE(evt->sip)) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 481, NULL, NULL, __LINE__); + return; + } + + js = NULL; + /* first, look for a Dialog in the map of element */ + for (js = eXosip.j_subscribes; js!= NULL ; js=js->next) + { + for (jd = js->s_dialogs; jd!= NULL ; jd=jd->next) + { + if (jd->d_dialog!=NULL) + { + if (osip_dialog_match_as_uas(jd->d_dialog, evt->sip)==0) + break; + } + } + if (jd!=NULL) break; + } + + if (js!=NULL) + { + /* dialog found */ + osip_transaction_t *old_trn; + /* it can be: + 1: a new INVITE offer. + 2: a REFER request from one of the party. + 2: a BYE request from one of the party. + 3: a REQUEST with a wrong CSeq. + 4: a NOT-SUPPORTED method with a wrong CSeq. + */ + if (MSG_IS_MESSAGE(evt->sip)) + { + /* eXosip_process_imessage_within_subscribe_dialog(transaction, evt); */ + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, SIP_NOT_IMPLEMENTED, + NULL, "MESSAGEs within dialogs are not implemented.", __LINE__); + return; + } + else if (MSG_IS_NOTIFY(evt->sip)) + { + /* the previous transaction MUST be freed */ + old_trn = eXosip_find_last_inc_notify(js, jd); + + /* shouldn't we wait for the COMPLETED state? */ + if (old_trn!=NULL && old_trn->state!=NIST_TERMINATED) + { + /* retry later? */ + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Retry Later", "A pending NOTIFY is not terminated", __LINE__); + return ; + } + + osip_dialog_update_osip_cseq_as_uas(jd->d_dialog, evt->sip); + osip_dialog_update_route_set_as_uas(jd->d_dialog, evt->sip); + + eXosip_process_notify_within_dialog(js, jd, transaction, evt); + } + else + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 501, NULL, "Just Not Implemented", __LINE__); + } + return ; + } + + if (MSG_IS_NOTIFY(evt->sip)) + { + /* I should probably initiate a dialog with info from NOTIFY... + By now, I prefer to discard the message until an answer for + the subscribe is received, then I'll be able to answer + the NOTIFY retransmission. */ + + /* let's try to check if the NOTIFY is related to an existing + subscribe */ + js = NULL; + /* first, look for a Dialog in the map of element */ + for (js = eXosip.j_subscribes; js!= NULL ; js=js->next) + { + if (eXosip_match_notify_for_subscribe(js, evt->sip)==0) + { + i = eXosip_dialog_init_as_uac(&jd, evt->sip); + if (i!=0) + { + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_ERROR, NULL, + "eXosip: cannot establish a dialog\n")); + return; + } + + /* update local cseq from subscribe request */ + if (js->s_out_tr!=NULL && js->s_out_tr->cseq!=NULL + && js->s_out_tr->cseq->number!=NULL) + { + jd->d_dialog->local_cseq = atoi(js->s_out_tr->cseq->number); + OSIP_TRACE (osip_trace + (__FILE__, __LINE__, OSIP_INFO2, NULL, + "eXosip: local cseq has been updated\n")); + } + + ADD_ELEMENT(js->s_dialogs, jd); + eXosip_update(); + + eXosip_process_notify_within_dialog(js, jd, transaction, evt); + return; + } + } + + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(NULL, transaction, evt, 481, NULL, NULL, __LINE__); + return; + } + + jn = NULL; + /* first, look for a Dialog in the map of element */ + for (jn = eXosip.j_notifies; jn!= NULL ; jn=jn->next) + { + for (jd = jn->n_dialogs; jd!= NULL ; jd=jd->next) + { + if (jd->d_dialog!=NULL) + { + if (osip_dialog_match_as_uas(jd->d_dialog, evt->sip)==0) + break; + } + } + if (jd!=NULL) break; + } + + if (jn!=NULL) + { + /* dialog found */ + osip_transaction_t *old_trn; + /* it can be: + 1: a new INVITE offer. + 2: a REFER request from one of the party. + 2: a BYE request from one of the party. + 3: a REQUEST with a wrong CSeq. + 4: a NOT-SUPPORTED method with a wrong CSeq. + */ + if (MSG_IS_MESSAGE(evt->sip)) + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, SIP_NOT_IMPLEMENTED, + NULL, "MESSAGEs within dialogs are not implemented.", __LINE__); + return; + } + else if (MSG_IS_SUBSCRIBE(evt->sip)) + { + /* the previous transaction MUST be freed */ + old_trn = eXosip_find_last_inc_subscribe(jn, jd); + + /* shouldn't we wait for the COMPLETED state? */ + if (old_trn!=NULL && old_trn->state!=NIST_TERMINATED + && old_trn->state!=NIST_COMPLETED) + { + /* retry later? */ + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 500, "Retry Later", "A SUBSCRIBE is not terminated", __LINE__); + return ; + } + + osip_dialog_update_osip_cseq_as_uas(jd->d_dialog, evt->sip); + osip_dialog_update_route_set_as_uas(jd->d_dialog, evt->sip); + + eXosip_process_subscribe_within_call(jn, jd, transaction, evt); + } + else + { + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(jd, transaction, evt, 501, NULL, NULL, __LINE__); + } + return ; + } + + if (MSG_IS_MESSAGE(evt->sip)) + { + eXosip_process_message_outside_of_dialog(transaction , evt); + return; + } + + if (MSG_IS_SUBSCRIBE(evt->sip)) + { + + if (0==eXosip_event_package_is_supported(transaction, evt)) + { + return; + } + eXosip_process_new_subscribe(transaction, evt); + return; + } + + /* default answer */ + osip_list_add(eXosip.j_transactions, transaction, 0); + eXosip_send_default_answer(NULL, transaction, evt, 501, NULL, NULL, __LINE__); +} + +static void eXosip_process_response_out_of_transaction (osip_event_t *evt) +{ + osip_event_free(evt); +} + +static void fix_via(osip_message_t *msg, const struct sockaddr * sa, socklen_t sa_len){ + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + int err; + err=getnameinfo(sa, sa_len,host,NI_MAXHOST,serv,NI_MAXSERV, + NI_NUMERICHOST|NI_NUMERICSERV); + if (err!=0){ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "sockaddr_to_char: error in getnameinfo():%s\n",gai_strerror(err) )); + return; + } + osip_message_fix_last_via_header(msg,host,atoi(serv)); +} + +/* if second==-1 && useconds==-1 -> wait for ever + if max_message_nb<=0 -> infinite loop.... */ +int eXosip_read_message ( int max_message_nb, int sec_max, int usec_max ) +{ + fd_set osip_fdset; + struct timeval tv; + char *buf; + + tv.tv_sec = sec_max; + tv.tv_usec = usec_max; + + buf = (char *)osip_malloc(SIP_MESSAGE_MAX_LENGTH*sizeof(char)+1); + while (max_message_nb!=0 && eXosip.j_stop_ua==0) + { + int i; + int max; + int wakeup_socket = jpipe_get_read_descr(eXosip.j_socketctl); + FD_ZERO(&osip_fdset); +#if defined (WIN32) || defined (_WIN32_WCE) + FD_SET((unsigned int)eXosip.j_socket, &osip_fdset); +#else + FD_SET(eXosip.j_socket, &osip_fdset); +#endif + max = eXosip.j_socket; +#if defined (WIN32) || defined (_WIN32_WCE) + FD_SET((unsigned int)wakeup_socket, &osip_fdset); +#else + FD_SET(wakeup_socket, &osip_fdset); +#endif + if (wakeup_socket>eXosip.j_socket) + max = wakeup_socket; + if ((sec_max==-1)||(usec_max==-1)) + i = select(max+1, &osip_fdset, NULL, NULL, NULL); + else + i = select(max+1, &osip_fdset, NULL, NULL, &tv); + + if ((i == -1) && (errno == EINTR || errno == EAGAIN)) + continue; + + if ((i > 0) && FD_ISSET (wakeup_socket, &osip_fdset)) + { + char buf2[500]; + jpipe_read (eXosip.j_socketctl, buf2, 499); + } + + if (0==i || eXosip.j_stop_ua!=0) + { + } + else if (-1==i) + { + osip_free(buf); + return -2; /* error */ + } + else if (FD_ISSET (eXosip.j_socket, &osip_fdset)) + { + struct sockaddr_storage sa; +#ifdef __linux + socklen_t slen; +#else + int slen; +#endif + slen = sizeof(struct sockaddr_storage); + i = recvfrom (eXosip.j_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0, + (struct sockaddr *) &sa, &slen); + if( i > 5 ) /* we expect at least one byte, otherwise there's no doubt that it is not a sip message !*/ + { + /* Message might not end with a "\0" but we know the number of */ + /* char received! */ + osip_transaction_t *transaction = NULL; + osip_event_t *sipevent; + osip_strncpy(buf+i,"\0",1); + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Received message: \n%s\n", buf)); +#ifdef WIN32 + if (strlen(buf)>412) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Message suite: \n%s\n", buf+412)); + } +#endif + + sipevent = osip_parse(buf, i); + transaction = NULL; + if (sipevent!=NULL&&sipevent->sip!=NULL) + { + fix_via(sipevent->sip,(struct sockaddr*)&sa,slen); + i = osip_find_transaction_and_add_event(eXosip.j_osip, sipevent); + if (i!=0) + { + /* this event has no transaction, */ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "This is a request\n", buf)); + eXosip_lock(); + if (MSG_IS_REQUEST(sipevent->sip)) + eXosip_process_newrequest(sipevent); + else if (MSG_IS_RESPONSE(sipevent->sip)) + eXosip_process_response_out_of_transaction(sipevent); + eXosip_unlock(); + } + else + { + /* handled by oSIP !*/ + } + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Could not parse SIP message\n")); + osip_event_free(sipevent); + } + } + else if (i<0) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, + "Could not read socket\n")); + } + else + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Dummy SIP message received\n")); + } + } + max_message_nb--; + } + osip_free(buf); + return 0; +} + + +static int eXosip_pendingosip_transaction_exist ( eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + osip_transaction_t *tr; + int now = time(NULL); + + tr = eXosip_find_last_inc_bye(jc, jd); + if (tr!=NULL && tr->state!=NIST_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state!=NICT_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state!=IST_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state!=ICT_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state!=IST_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state!=NICT_TERMINATED) + { /* Don't want to wait forever on broken transaction!! */ + if (tr->birth_time+180state==NIST_TERMINATED || tr->state==NICT_TERMINATED )) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_finished_calls remove a dialog\n")); + /* Remove existing reference to the dialog from transactions! */ + __eXosip_call_remove_dialog_reference_in_call(jc, jd); + REMOVE_ELEMENT(jc->c_dialogs, jd); + eXosip_dialog_free(jd); + return 0; + } + return -1; +} + + + +static void +__eXosip_release_call(eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + REMOVE_ELEMENT(eXosip.j_calls, jc); + __eXosip_report_event(EXOSIP_CALL_RELEASED, jc, jd, NULL); + eXosip_call_free(jc); + __eXosip_wakeup(); +} + + +static int eXosip_release_aborted_calls ( eXosip_call_t *jc, eXosip_dialog_t *jd ) +{ + int now = time(NULL); + osip_transaction_t *tr; + tr = eXosip_find_last_inc_invite(jc, jd); + if (tr==NULL) + tr = eXosip_find_last_out_invite(jc, jd); + + if (tr==NULL) + { + if (jd!=NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls remove an empty dialog\n")); + __eXosip_call_remove_dialog_reference_in_call(jc, jd); + REMOVE_ELEMENT(jc->c_dialogs, jd); + eXosip_dialog_free(jd); + return 0; + } + return -1; + } + + if (tr!=NULL + && tr->state!=IST_TERMINATED + && tr->state!=ICT_TERMINATED + && tr->birth_time+180c_dialogs, jd); + __eXosip_report_event(EXOSIP_CALL_NOANSWER, jc, jd, NULL); + eXosip_dialog_free(jd); + __eXosip_wakeup(); + return 0; + } + } + + if (tr!=NULL + && (tr->state==IST_TERMINATED + || tr->state==ICT_TERMINATED)) + { + if (tr==jc->c_inc_tr) + { + if (jc->c_inc_tr->last_response==NULL) + { + /* OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls transaction with no answer\n")); */ + } + else if (MSG_IS_STATUS_3XX(jc->c_inc_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls answered with a 3xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_4XX(jc->c_inc_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls answered with a 4xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_5XX(jc->c_inc_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls answered with a 5xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_6XX(jc->c_inc_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls answered with a 6xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + } + else if (tr==jc->c_out_tr) + { + if (jc->c_out_tr->last_response==NULL) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls completed with no answer\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_3XX(jc->c_out_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls completed answered with 3xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_4XX(jc->c_out_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls completed answered with 4xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_5XX(jc->c_out_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls completed answered with 5xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + else if (MSG_IS_STATUS_6XX(jc->c_out_tr->last_response)) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO2,NULL, + "eXosip: eXosip_release_aborted_calls completed answered with 6xx\n")); + __eXosip_release_call(jc, jd); + return 0; + } + } + } + + return -1; +} + + +void eXosip_release_terminated_calls ( void ) +{ + eXosip_dialog_t *jd; + eXosip_dialog_t *jdnext; + eXosip_call_t *jc; + eXosip_call_t *jcnext; + int now = time(NULL); + int pos; + + + for (jc = eXosip.j_calls ; jc != NULL; ) + { + jcnext=jc->next; + /* free call terminated with a BYE */ + for (jd = jc->c_dialogs ; jd != NULL; ) + { + jdnext=jd->next; + if (0==eXosip_pendingosip_transaction_exist(jc, jd)) + { } + else if (0==eXosip_release_finished_calls(jc, jd)) + { jd = jc->c_dialogs; } + else if (0==eXosip_release_aborted_calls(jc, jd)) + { jdnext = NULL; } + else + { } + jd=jdnext; + } + jc=jcnext; + } + + for (jc = eXosip.j_calls ; jc != NULL; ) + { + jcnext=jc->next; + if (jc->c_dialogs==NULL) + { + /* release call for options requests */ + if (jc->c_inc_options_tr!=NULL) + { + if (jc->c_inc_options_tr->state==NIST_TERMINATED) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "eXosip: remove an incoming OPTIONS with no final answer\n")); + __eXosip_release_call(jc, NULL); + } + else if (jc->c_inc_options_tr->state!=NIST_TERMINATED + && jc->c_inc_options_tr->birth_time+180c_out_options_tr!=NULL) + { + if (jc->c_out_options_tr->state==NICT_TERMINATED) + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "eXosip: remove an outgoing OPTIONS with no final answer\n")); + __eXosip_release_call(jc, NULL); + } + else if (jc->c_out_options_tr->state!=NIST_TERMINATED + && jc->c_out_options_tr->birth_time+180c_inc_tr!=NULL && jc->c_inc_tr->state!=IST_TERMINATED + && jc->c_inc_tr->birth_time+180c_out_tr!=NULL && jc->c_out_tr->state!=ICT_TERMINATED + && jc->c_out_tr->birth_time+180c_inc_tr!=NULL && jc->c_inc_tr->state!=IST_TERMINATED) + { } + else if (jc->c_out_tr!=NULL && jc->c_out_tr->state!=ICT_TERMINATED) + { } + else /* no active pending transaction */ + { + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "eXosip: remove a call\n")); + __eXosip_release_call(jc, NULL); + } + } + jc = jcnext; + } + + pos = 0; + while (!osip_list_eol(eXosip.j_transactions, pos)) + { + osip_transaction_t *tr = (osip_transaction_t*) osip_list_get(eXosip.j_transactions, pos); + if (tr->state==IST_TERMINATED || tr->state==ICT_TERMINATED + || tr->state== NICT_TERMINATED || tr->state==NIST_TERMINATED) + + { /* free (transaction is already removed from the oSIP stack) */ + OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, + "Release a terminated transaction\n")); + osip_list_remove(eXosip.j_transactions, pos); + __eXosip_delete_jinfo(tr); + osip_transaction_free(tr); + } + else if (tr->birth_time+180 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/gnome/GNOME_LinphoneApplet.xml b/linphone/gnome/GNOME_LinphoneApplet.xml new file mode 100644 index 000000000..9a5350fd2 --- /dev/null +++ b/linphone/gnome/GNOME_LinphoneApplet.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/linphone/gnome/Makefile.am b/linphone/gnome/Makefile.am new file mode 100644 index 000000000..7690425e0 --- /dev/null +++ b/linphone/gnome/Makefile.am @@ -0,0 +1,80 @@ +## Process this file with automake to produce Makefile.in + +linphone_common_sources=\ + linphone.c linphone.h \ + gui_utils.c gui_utils.h \ + support.c support.h \ + interface.c interface.h \ + callbacks.c callbacks.h \ + presence.c presence.h \ + propertybox.c propertybox.h \ + addressbook.c addressbook.h \ + friends.c friends.h + + +if BUILD_GNOME + +INCLUDES = \ + -I$(top_srcdir)\ + -I$(top_srcdir)/intl \ + $(ORTP_CFLAGS) \ + -I$(top_srcdir)/coreapi \ + -I$(top_srcdir)/mediastreamer2/include \ + $(OSIP_CFLAGS) + + + +bin_PROGRAMS = linphone + +linphone_SOURCES = \ + main.c \ + $(linphone_common_sources) + +linphone_LDADD = $(LIBGNOMEUI_LIBS) $(INTLLIBS) \ + $(LIBGNOME_LIBS) \ + $(top_builddir)/coreapi/liblinphone.la \ + $(OSIP_LIBS) + +endif + +AM_CFLAGS=$(STRICT_OPTIONS) $(LIBGNOMEUI_CFLAGS) $(LIBGNOME_CFLAGS) $(GNOME_APPLETS_CFLAGS) $(IPV6_CFLAGS) + +@INTLTOOL_SERVER_RULE@ + +if BUILD_GNOME_APPLET + +gnome_appletdir=$(libexecdir) + +gnome_applet_PROGRAMS = linphone_applet + +linphone_applet_SOURCES = \ + $(linphone_common_sources)\ + applet.c + +linphone_applet_CFLAGS=$(AM_CFLAGS) -DLINPHONE_APPLET + +linphone_applet_LDADD = \ + $(GNOME_APPLETS_LIBS) \ + $(top_builddir)/coreapi/liblinphone.la \ + $(OSIP_LIBS) + + +serverdir = $(libdir)/bonobo/servers +server_in_files = GNOME_LinphoneApplet.server.in +server_DATA = $(server_in_files:.server.in=.server) + +$(server_in_files): $(server_in_files:.server.in=.server.in.in) + sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ + + +uidir = $(datadir)/gnome-2.0/ui +ui_DATA = GNOME_LinphoneApplet.xml + +endif + +EXTRA_DIST = \ + GNOME_LinphoneApplet.server.in.in \ + applet.c \ + $(ui_DATA) + +DISTCLEANFILES=GNOME_LinphoneApplet.server.in GNOME_LinphoneApplet.server diff --git a/linphone/gnome/addressbook.c b/linphone/gnome/addressbook.c new file mode 100644 index 000000000..924bc6509 --- /dev/null +++ b/linphone/gnome/addressbook.c @@ -0,0 +1,306 @@ +/*************************************************************************** + addressbook.c - + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "linphone.h" + +#define get_address_book() (&uiobj->addressbook) +#define get_main_window() (&uiobj->main_window) +#define get_core() (uiobj->core) +#define get_uiobj() (uiobj) + +void fill_address_book(GtkWidget *address_list); + +void ab_destroyed(){ + get_uiobj()->ab=NULL; +} + +void show_address_book(){ + if (get_uiobj()->ab!=NULL){ + gtk_window_present(GTK_WINDOW(get_uiobj()->ab)); + }else{ + get_uiobj()->ab=create_and_fill_address_book(); + g_signal_connect(G_OBJECT(get_uiobj()->ab),"destroy",G_CALLBACK(ab_destroyed),NULL); + gtk_widget_show(get_uiobj()->ab); + } +} + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +void contact_draw(GtkWidget *w, LinphoneProxyConfig *cfg){ + GtkWidget *table=lookup_widget(w,"table10"); + GtkWidget *combo; + combo=proxy_combo_box_new(cfg); + gtk_widget_show(combo); + gtk_table_attach(GTK_TABLE(table),combo,1,2,2,3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + GLADE_HOOKUP_OBJECT(w,combo,"proxy"); + combo=gtk_combo_box_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Wait")); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Deny")); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Accept")); + gtk_widget_show(combo); + gtk_table_attach(GTK_TABLE(table),combo,1,2,3,4, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + GLADE_HOOKUP_OBJECT(w,combo,"pol"); +} + +GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab){ + GtkWidget *w=create_contact_box(); + contact_draw(w,NULL); + gtk_widget_show(w); + g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab); + g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE)); + gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe); + return w; +} + +GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab){ + GtkWidget *w=create_contact_box(); + gchar *tmpstr; + contact_draw(w,lf->proxy); + + g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + linphone_friend_edit(lf); + tmpstr=linphone_friend_get_name(lf); + if (tmpstr!=NULL) { + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"name")),tmpstr); + g_free(tmpstr); + } + tmpstr=linphone_friend_get_addr(lf); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"sipaddr")),tmpstr); + g_free(tmpstr); + + gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe); + + gtk_widget_show(w); + if (ab!=NULL) g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab); + return w; +} + +GtkWidget * subscriber_edit(LinphoneFriend *lf){ + GtkWidget *w=contact_edit(lf,NULL); + g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE)); + return w; +} + +gint contact_ok(GtkWidget *dialog){ + gchar *name,*sipaddr; + gchar *url; + gboolean add=FALSE; + GtkWidget *ab; + LinphoneFriend *lf; + int err; + lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref"); + add=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dialog),"add")); + name=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"name")),0,-1); + sipaddr=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"sipaddr")),0,-1); + url=g_strdup_printf("%s <%s>",name,sipaddr); + /* workaround a bug in osip ? */ + /* something doesn't like addresses like "machin <>" */ + if (strchr(sipaddr,'<')==NULL){ + err=linphone_friend_set_sip_addr(lf,url); + }else err=-1; + if (err<0){ + linphone_gnome_ui_display_something(get_uiobj(),GTK_MESSAGE_WARNING,_("Bad sip address: a sip address looks like sip:user@domain")); + linphone_friend_destroy(lf); + g_free(name); + g_free(sipaddr); + g_free(url); + return -1; + } + g_free(name); + g_free(sipaddr); + g_free(url); + linphone_friend_set_proxy(lf,proxy_combo_box_get_selected(lookup_widget(dialog,"proxy"))); + linphone_friend_set_inc_subscribe_policy(lf,gtk_combo_box_get_active(GTK_COMBO_BOX(lookup_widget(dialog,"pol")))); + linphone_friend_send_subscribe(lf,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"send_subscribe")))); + if (add){ + linphone_core_add_friend(get_core(),lf); + } + else linphone_friend_done(lf); + /* ask the address book to redraw itself */ + ab=g_object_get_data(G_OBJECT(dialog),"address_book"); + if (ab!=NULL) fill_address_book(lookup_widget(ab,"address_list")); + return 0; +} + +enum{ + SIP_ADDRESS_COLUMN, + FRIEND_REFERENCE, + AB_NCOLUMNS +}; + +void choose_address_and_close(GtkWidget *ab){ + GtkTreeSelection *select; + GtkWidget *addressentry=get_main_window()->addressentry; + GtkTreeIter iter; + GtkTreeModel *model; + gchar *address=NULL; + GtkWidget *address_list=lookup_widget(ab,"address_list"); + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (select==NULL) return; + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,SIP_ADDRESS_COLUMN , &address, -1); + } + if (address!=NULL){ + gtk_entry_set_text (GTK_ENTRY(addressentry),address); + g_free(address); + } + gtk_widget_destroy(ab); +} +void +address_book_close (GtkWidget *object, + gpointer user_data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(object)); +} + +void address_selection_changed_cb(GtkTreeSelection *selection, gpointer data) +{ + +} +gboolean address_button_press(GtkWidget *widget,GdkEventButton *event,gpointer user_data) +{ + GtkWidget *ab=(GtkWidget*)user_data; + if (event->type==GDK_2BUTTON_PRESS){ + choose_address_and_close(ab); + return TRUE; + } + return FALSE; +} + +void fill_address_book(GtkWidget *address_list){ + GtkListStore *store; + GtkTreeIter iter; + GtkTreeModel *model; + MSList *elem; + gchar *tmpstr; + /* fill the store */ + elem=linphone_core_get_friend_list(get_core()); + model=gtk_tree_view_get_model(GTK_TREE_VIEW(address_list)); + store=GTK_LIST_STORE(model); + gtk_list_store_clear(store); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneFriend *lf=(LinphoneFriend*)elem->data; + tmpstr=linphone_friend_get_url(lf); + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,SIP_ADDRESS_COLUMN,tmpstr,FRIEND_REFERENCE,(gpointer)lf,-1); + ms_free(tmpstr); + } +} + +GtkWidget *create_and_fill_address_book(){ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + GtkWidget *address_list; + GtkWidget *ret=create_address_book(); + + address_list=lookup_widget(ret,"address_list"); + store = gtk_list_store_new (AB_NCOLUMNS, G_TYPE_STRING,G_TYPE_POINTER); + gtk_tree_view_set_model(GTK_TREE_VIEW(address_list),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Contact list"), + renderer, + "text", SIP_ADDRESS_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (address_list), column); + + /* Setup the selection handler */ + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT (select), "changed", + G_CALLBACK (address_selection_changed_cb), + NULL); + + /* setup handler for double click */ + g_signal_connect(G_OBJECT(address_list),"button-press-event",G_CALLBACK(address_button_press),(gpointer)ret); + + fill_address_book(address_list); + return ret; +} + +void +on_modify_address_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list"); + + /* change the address in the view */ + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + LinphoneFriend *lf=NULL; + gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1); + contact_edit(lf,gtk_widget_get_toplevel(GTK_WIDGET(button))); + } +} + +void on_add_address_clicked(GtkButton *button,gpointer user_data) +{ + LinphoneFriend *lf=linphone_friend_new(); + contact_new(lf,gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + +void on_remove_address_clicked(GtkButton *button,gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list"); + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + LinphoneFriend *lf=NULL; + gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1); + linphone_core_remove_friend(get_core(),lf); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + } +} + +void on_select_address_clicked(GtkButton *button,gpointer user_data) +{ + choose_address_and_close(gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + + +void +on_contact_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch (response_id){ + case GTK_RESPONSE_OK: + contact_ok(GTK_WIDGET(dialog)); + break; + default: + break; + } + gtk_widget_destroy(GTK_WIDGET(dialog)); +} diff --git a/linphone/gnome/addressbook.h b/linphone/gnome/addressbook.h new file mode 100644 index 000000000..f5f5431e3 --- /dev/null +++ b/linphone/gnome/addressbook.h @@ -0,0 +1,28 @@ +/*************************************************************************** + addressbook.h - + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef ADDRESSBOOK_H +#define ADDRESSBOOK_H + +GtkWidget *create_and_fill_address_book(); +void show_address_book(); +GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab); +GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab); +GtkWidget * subscriber_edit(LinphoneFriend *lf); + +#endif diff --git a/linphone/gnome/applet.c b/linphone/gnome/applet.c new file mode 100644 index 000000000..0edb30be0 --- /dev/null +++ b/linphone/gnome/applet.c @@ -0,0 +1,182 @@ +/*************************************************************************** + applet.c - Applet code for linphone's gnome + interface + ------------------- + begin : Sat Dec 14 2002 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "linphone.h" +#include + +#define get_uiobj() (uiobj) + +LinphoneCore core; +LinphoneGnomeUI ui; +static int show=0; +static gulong signal_ref; +static GtkWidget *applet_button=NULL; +static GdkPixbuf *original_icon=NULL; +static GtkWidget *icon=NULL; + +void draw_icon(GtkWidget *button, int size) +{ + GdkPixbuf *resized; + if (original_icon==NULL){ + original_icon=gdk_pixbuf_new_from_file(PACKAGE_DATA_DIR "/pixmaps/linphone/linphone2.xpm", + NULL); + g_return_if_fail( original_icon!=NULL); + } + if (icon!=NULL){ + gtk_container_remove(GTK_CONTAINER(button),icon); + gtk_widget_destroy(icon); + } + resized=gdk_pixbuf_scale_simple(original_icon,size,size,GDK_INTERP_BILINEAR); + g_return_if_fail(resized!=NULL); + icon=gtk_image_new_from_pixbuf(resized); + g_return_if_fail(icon!=NULL); + gdk_pixbuf_unref(resized); + gtk_container_add(GTK_CONTAINER(button),icon); + gtk_widget_show(icon); +} + +void linphone_applet_about_cb(gpointer p) +{ + GtkWidget *about2; + about2 = create_about2 (); + gtk_widget_show (about2); +} + + + +static void applet_change_pixel_size(GtkWidget *applet, int size) +{ + g_return_if_fail(applet_button!=NULL); + draw_icon(applet_button,size); +} + +static void applet_destroy_cb(GtkWidget *widget, gpointer data) +{ + if (get_uiobj()->main_window.window!=NULL){ + gtk_widget_destroy(get_uiobj()->main_window.window); + } + linphone_gnome_uninit(get_uiobj()); +} + +static gboolean +gui_destroy_cb (GtkWidget *widget, gpointer data) +{ + linphone_gnome_ui_uninit(get_uiobj()); + show=0; + return FALSE; +} + +static gboolean button_press_cb(GtkWidget *applet, GdkEventButton* event, gpointer data) +{ + if (event->button!=1) return FALSE; + if (show){ + g_signal_handlers_disconnect_by_func(G_OBJECT(get_uiobj()->main_window.window), + G_CALLBACK(gui_destroy_cb),NULL); + linphone_gnome_ui_hide(get_uiobj()); + + show=0; + }else { + linphone_gnome_ui_show(get_uiobj()); + signal_ref=g_signal_connect(G_OBJECT(get_uiobj()->main_window.window), + "destroy", + G_CALLBACK(gui_destroy_cb),NULL); + show=1; + } + return FALSE; +} + +const BonoboUIVerb linphone_applet_menu_verbs [] = { + BONOBO_UI_UNSAFE_VERB ("About", linphone_applet_about_cb), + BONOBO_UI_VERB_END +}; + +static gboolean +linphone_applet_fill (PanelApplet *applet) +{ + gint size=panel_applet_get_size(applet); + + applet_button=gtk_frame_new(NULL); + gtk_container_add(GTK_CONTAINER(applet),applet_button); + gtk_widget_show(applet_button); + + draw_icon(applet_button,size); + + g_signal_connect(G_OBJECT(applet),"button-press-event",G_CALLBACK(button_press_cb),NULL); + + + g_signal_connect(G_OBJECT(applet),"change_size", + G_CALLBACK(applet_change_pixel_size), + NULL); + + + g_signal_connect (G_OBJECT (applet), "destroy", + G_CALLBACK (applet_destroy_cb), NULL); + + //sizehint = panel_applet_get_size (PANEL_APPLET (applet)); + panel_applet_setup_menu_from_file (applet, + NULL, + "GNOME_LinphoneApplet.xml", + NULL, + linphone_applet_menu_verbs, + NULL); + + /* tracing for osip */ + TRACE_INITIALIZE(5,stdout); + + linphone_gnome_init(&ui,&core); + gtk_widget_show_all (GTK_WIDGET (applet)); + + return TRUE; +} + + +static gboolean +linphone_applet_factory (PanelApplet *applet, + const gchar *iid, + gpointer data) +{ + static int instances=0; + GtkWidget *dialog; + if (!strcmp (iid, "OAFIID:GNOME_LinphoneApplet")){ + if (instances>0){ + dialog = gtk_message_dialog_new (GTK_WINDOW(applet), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_CLOSE, + (const gchar*) _("Cannot run multiples instances of the linphone applet.")); + /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); + gtk_widget_show(GTK_WIDGET(dialog)); + return FALSE; + } + return linphone_applet_fill (applet); + } + return FALSE; +} + +#define GNOMELOCALEDIR PACKAGE_LOCALE_DIR + +PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_LinphoneApplet_Factory", + PANEL_TYPE_APPLET, + "linphone_applet", + "0", + linphone_applet_factory, + NULL) diff --git a/linphone/gnome/callbacks.c b/linphone/gnome/callbacks.c new file mode 100644 index 000000000..16ededc8a --- /dev/null +++ b/linphone/gnome/callbacks.c @@ -0,0 +1,695 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +callbacks.c -- gtk callbacks, and osipua callbacks. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" +#include + +#define get_core() (uiobj->core) +#define get_main_window() (&uiobj->main_window) +#define get_uiobj() (uiobj) + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + GtkWidget *about2; + about2 = create_about2 (); + gtk_widget_show (about2); +} + + +gint +on_prop1_close (GnomeDialog *gnomedialog, + gpointer user_data) +{ + LinphoneMainWindow *obj=get_main_window(); + gnome_appbar_clear_stack( GNOME_APPBAR(obj->status_bar)); + + return(FALSE); +} + +void +on_parametres1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + linphone_property_box_init(&ui->propbox); +} + + + +void +on_user_manual1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + gnome_help_display("index.xml",NULL,NULL); +} + + +gboolean +on_play_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_play_level(get_core(),vol); + return FALSE; +} + + +gboolean +on_rec_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_rec_level(get_core(),vol); + return FALSE; +} + + +gboolean +on_ring_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_ring_level(get_core(),vol); + return FALSE; +} + + +void +on_prop1_help (GnomePropertyBox *gnomepropertybox, + gint arg1, + gpointer user_data) +{ + gnome_help_display("index.html",NULL,NULL); +} + + + + +void +on_fermer1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + linphone_gnome_ui_hide(get_uiobj()); +} + + + +#if 0 +/*this is when the panel size changes*/ +void applet_change_pixel_size(GtkWidget *w, int size, gpointer data) +{ + GtkWidget *pixmap,*button; + + pixmap=gtk_object_get_data(GTK_OBJECT(applet),"applet_pixmap"); + button=(GtkWidget*)gtk_object_get_data(GTK_OBJECT(applet),"applet_button"); + if (button==NULL) + { + printf("Cannot find applet button\n"); + return; + } + if (pixmap!=NULL) gtk_widget_destroy(pixmap); + pixmap = gnome_pixmap_new_from_xpm_d_at_size(linphone2_xpm, + size-4, size-4); + gtk_object_set_data(GTK_OBJECT(applet),"applet_pixmap",pixmap); + gtk_widget_show(pixmap); + gtk_container_add(GTK_CONTAINER(button), pixmap); +} +#endif + +void +on_adresse_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + show_address_book(); +} + +void on_address_book_show(GtkWidget *widget,gpointer user_data) +{ + +} + + + +void +on_showmore_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + gint state; + GtkWidget *optioncontrols=get_main_window()->optioncontrols; + state=gtk_toggle_button_get_active(togglebutton); + if (state) gtk_widget_show(optioncontrols); + else { + gtk_widget_hide(optioncontrols); + } +} + + +void +on_useRPC_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ +#ifdef VINCENT_MAURY_RSVP + LinphoneCore *lc=get_core(); + gboolean state; + state=gtk_toggle_button_get_active(togglebutton); + /* change RPC settings according to state */ + if (state) + { + if (linphone_core_set_rpc_mode(lc,1)!=0) /* set rpc on */ + { + printf("RPC error. unable to set rpc on !\n"); + printf("Check to see if RPC server is running\n"); + gtk_toggle_button_set_active(togglebutton,FALSE); + /*linphone_core_set_rpc_mode(lc,0);*/ + } + } + else + { + if (linphone_core_set_rpc_mode(lc,0)!=0) /* set rpc off */ + printf("RPC error. That's impossible !!\n"); + } +#endif +} + +void +on_useRSVP_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ +#ifdef VINCENT_MAURY_RSVP + LinphoneCore *lc=get_core(); + LinphoneGnomeUI *ui=get_uiobj(); + gboolean state; + state=gtk_toggle_button_get_active(togglebutton); + /* change the QoS settings function of the state */ + if (state) + { + linphone_core_set_rsvp_mode(lc,1); /* set RSVP on */ + gtk_widget_show(lookup_widget(ui->propbox.prop,"useRPC")); /* show RPC checkbox */ + } + else + { + linphone_core_set_rsvp_mode(lc,0); /* set RSVP off */ + /* uncheck RPC if necessary and hide RPC checkbox */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( + lookup_widget(ui->propbox.prop,"useRPC")),FALSE); + gtk_widget_hide(lookup_widget(ui->propbox.prop,"useRPC")); + } +#endif +} + +#ifdef VINCENT_MAURY_RSVP +/* callback called when you click the yes/no dialog box + * send yes or no to the core_change_qos which knows the question + * and will be able to ajust qos */ +void dialog_click (GtkDialog *dialog,gint arg1,gpointer user_data) +{ + LinphoneCore *lc=get_core(); + if (lc->call==NULL) + return; + + if (arg1==GTK_RESPONSE_YES) + { + printf("YES\n"); + linphone_core_change_qos(lc, 1); /* 1 = yes */ + } + else + { + printf("NO\n"); + linphone_core_change_qos(lc, 0); /* 0 = no */ + } + gtk_widget_destroy((GtkWidget*)dialog); +} +#endif + + +void +on_alt_href_clicked (GtkButton *button, + gpointer user_data) +{ + gchar *url; + GtkWidget *label; + osip_from_t * from; + LinphoneGnomeUI *ui=get_uiobj(); + label=GTK_BIN(button)->child; + gtk_label_get(GTK_LABEL(label),&url); + osip_from_init(&from); + if ( osip_from_parse(from,url) <0){ + /* do something here */ + }else + { /* it was a sip url, so display it in the entry*/ + gtk_entry_set_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(ui->main_window.addressentry))),url); + } + osip_from_free(from); +} + +void +on_alt_href_realize (GtkWidget *widget, + gpointer user_data) +{ + GdkCursor *cursor = gdk_cursor_new(GDK_HAND2); + gdk_window_set_cursor(widget->window, cursor); + gdk_cursor_destroy(cursor); +} + + +void +on_dtmf_3_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"3"); +} + + +void +on_dmtf_2_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"2"); +} + + +void +on_dtmf_1_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"1"); +} + + +void +on_dtmf_4_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"4"); +} + + +void +on_dtmf_5_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"5"); +} + + +void +on_dtmf_6_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"6"); +} + + +void +on_dtmf_7_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"7"); +} + + +void +on_dtmf_8_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"8"); + +} + + +void +on_dtmf_9_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"9"); + +} + + +void +on_dtmf_star_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"*"); + +} + + +void +on_dtmf_0_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"0"); + +} + + +void +on_dtmf_pound_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"#"); + +} + + +void +on_dtmf_entry_changed (GtkEditable *editable, + gpointer user_data) +{ + gchar *dtmfs; + gint len; + /* get the last entry in the text box and plays it */ + dtmfs=gtk_editable_get_chars(editable,0,-1); + g_return_if_fail(dtmfs!=NULL); + len=strlen(dtmfs); + if (len>0){ + g_message("Sending dtmf %c",dtmfs[len-1]); + linphone_core_send_dtmf(get_uiobj()->core,dtmfs[len-1]); + } + g_free(dtmfs); +} + + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ +#ifdef LINPHONE_APPLET +#else + gtk_widget_destroy(get_uiobj()->main_window.window); +#endif +} + + +void on_app1_destroy(GtkWidget *app1, gpointer user_data) +{ +#ifdef LINPHONE_APPLET +#else + gtk_main_quit(); +#endif +} + +void +on_display_ab_clicked (GtkButton *button, + gpointer user_data) +{ + show_address_book(); +} + + +void +on_inc_subscr_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + LinphoneFriend *lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref"); + switch(response_id){ + case GTK_RESPONSE_ACCEPT: + subscriber_edit(lf); + break; + case GTK_RESPONSE_REJECT: + linphone_core_reject_subscriber(get_core(),lf); + break; + } + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +void authentication_dialog_ok(GtkWidget *w) +{ + gchar *realm,*username,*userid,*passwd; + LinphoneAuthInfo *info; + realm=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"realm")),0,-1); + username=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"username")),0,-1); + userid=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"userid")),0,-1); + passwd=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"passwd")),0,-1); + info=linphone_auth_info_new(username,userid,passwd,NULL,realm); + linphone_core_add_auth_info(get_core(),info); + g_free(username); + g_free(userid); + g_free(passwd); + g_free(realm); +} + +void +on_authentication_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch(response_id){ + case GTK_RESPONSE_OK: + authentication_dialog_ok(GTK_WIDGET(dialog)); + gtk_widget_destroy(GTK_WIDGET(dialog)); + break; + } +} + +void +on_clear_auth_info_clicked (GtkButton *button, + gpointer user_data) +{ + linphone_core_clear_all_auth_info(get_core()); +} + + +void +on_call_history_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + linphone_gnome_show_call_logs_window(get_uiobj()); +} + + +void +on_call_logs_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + + +void +on_call_logs_destroy (GtkObject *object, + gpointer user_data) +{ + get_uiobj()->logs=NULL; +} + + +static void completion_add_text(GtkEntry *entry, const char *text){ + GtkTreeIter iter; + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry)); + + if (gtk_tree_model_get_iter_first(model,&iter)){ + do { + gchar *uri=NULL; + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri!=NULL){ + if (strcmp(uri,text)==0) { + /*remove text */ + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + g_free(uri); + break; + } + g_free(uri); + } + }while (gtk_tree_model_iter_next(model,&iter)); + } + /* and prepend it on top of the list */ + gtk_list_store_prepend(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1); +} + + +void +on_callbutton_clicked (GtkButton *button, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + LinphoneCore *lc=get_core(); + GtkEntry *entry=GTK_ENTRY(ui->main_window.addressentry); + + if (lc->call==NULL){ + const gchar *sipurl=NULL; + int err; + /* we have no dialog in progress */ + /* get the url to call */ + sipurl=gtk_entry_get_text(entry); + err=linphone_core_invite(lc,sipurl); + if (err==0) completion_add_text(entry,sipurl); + }else { + linphone_core_accept_call(lc,NULL); + } +} + +void +on_hangup_clicked (GtkButton *button, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + LinphoneCore *lc=get_core(); + if (lc->call!=NULL){ + /* same trick here as for linphone_core_accept_dialog: defer it to gtk's idle loop */ + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone"); + linphone_core_terminate_call(lc,NULL); + } +} + +GtkWidget *chatroom_new(const gchar *url, LinphoneChatRoom *cr){ + GtkWidget *gcr=NULL; + if (cr==NULL) + cr=linphone_core_create_chat_room(get_core(),url); + if (cr!=NULL){ + gchar *tmp; + gcr=create_chatroom(); + g_object_set_data(G_OBJECT(gcr),"chatroom",(gpointer)cr); + linphone_chat_room_set_user_data(cr,(gpointer)gcr); + tmp=g_strdup_printf(_("Chat with %s"),url); + gtk_window_set_title(GTK_WINDOW(gcr),tmp); + g_free(tmp); + } + return gcr; +} + +void chatroom_append(GtkWidget *gcr, const gchar *from, const gchar *message){ + GtkTextBuffer *tb; + gchar *str; + GtkTextIter enditer; + GtkTextView *tv=GTK_TEXT_VIEW(lookup_widget(gcr,"chattext")); + tb=gtk_text_view_get_buffer(tv); + g_return_if_fail(tb!=NULL); + gtk_text_buffer_get_end_iter(tb,&enditer); + str=g_strdup_printf("[%s]\t:%s\n",from,message); + gtk_text_buffer_insert(tb,&enditer,str,strlen(str)); + g_free(str); +} + +void chatroom_close(GtkWidget *gcr){ + LinphoneChatRoom *cr; + cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom"); + linphone_chat_room_destroy(cr); +} + + +void +on_chat_clicked (GtkButton *button, + gpointer user_data) +{ + gchar *sipurl; + + sipurl=gtk_editable_get_chars(GTK_EDITABLE(get_main_window()->addressentry),0,-1); + GtkWidget *gcr=chatroom_new(sipurl,NULL); + if (gcr!=NULL) gtk_widget_show(gcr); + g_free(sipurl); +} + + +void +on_chatbox_clicked (GtkButton *button, + gpointer user_data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + + + +void +on_chatentry_activate (GtkEntry *entry, + gpointer user_data) +{ + LinphoneChatRoom *cr; + gchar *text; + text=gtk_editable_get_chars(GTK_EDITABLE(entry),0,-1); + if (strlen(text)>0){ + GtkWidget *gcr=gtk_widget_get_toplevel(GTK_WIDGET(entry)); + cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom"); + linphone_chat_room_send_message(cr,text); + chatroom_append(gcr,linphone_core_get_primary_contact(get_core()),text); + gtk_editable_delete_text(GTK_EDITABLE(entry),0,-1); + } +} + +void +on_chatroom_destroy (GtkObject *object, + gpointer user_data) +{ + chatroom_close(GTK_WIDGET(object)); +} + + + +void +on_addressentry_activate (GtkEntry *entry, + gpointer user_data) +{ + on_callbutton_clicked(NULL,NULL); +} + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data) +{ + linphone_gnome_save_uri_history(get_uiobj()); +} + +void +on_video_enabled_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + linphone_core_enable_video(get_core(),gtk_toggle_button_get_active(togglebutton)); +} + + +void +on_echocancelation_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + linphone_core_enable_echo_cancelation(get_core(), + gtk_toggle_button_get_active(togglebutton)); +} + + + + diff --git a/linphone/gnome/callbacks.h b/linphone/gnome/callbacks.h new file mode 100644 index 000000000..11704a6a9 --- /dev/null +++ b/linphone/gnome/callbacks.h @@ -0,0 +1,540 @@ +#include + + +void +on_app1_destroy (GtkObject *object, + gpointer user_data); + +void +on_adresse_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_parametres1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_fermer1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_user_manual1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_greenbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_redbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_showmore_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +gboolean +on_play_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_rec_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_ring_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +void +on_reachable (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_busy (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_minutesaway_changed (GtkEditable *editable, + gpointer user_data); + +void +on_away (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_do_not_disturb (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_moved_tmply (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_alt_serv (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_contact_field_changed (GtkEditable *editable, + gpointer user_data); + +void +on_presence_validate_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_entry_changed (GtkEditable *editable, + gpointer user_data); + +void +on_dtmf_3_clicked (GtkButton *button, + gpointer user_data); + +void +on_dmtf_2_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_1_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_4_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_5_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_6_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_7_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_8_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_9_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_star_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_0_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_pound_clicked (GtkButton *button, + gpointer user_data); + +void +on_propertybox1_apply (GnomePropertyBox *propertybox, + gint page_num, + gpointer user_data); + +gboolean +on_prop1_close (GnomeDialog *gnomedialog, + gpointer user_data); + +void +on_prop1_help (GnomePropertyBox *propertybox, + gint page_num, + gpointer user_data); + +gboolean +on_hscale1_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +void +on_audioport_changed (GtkEditable *editable, + gpointer user_data); + +void +on_sipport_changed (GtkEditable *editable, + gpointer user_data); + +void +on_user_name_changed (GtkEditable *editable, + gpointer user_data); + +void +on_domain_name_changed (GtkEditable *editable, + gpointer user_data); + +void +on_registrar_checked_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_rsvp_checked_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + + +void +on_redirect_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_proxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_obproxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_registrar_addr_changed (GtkEditable *editable, + gpointer user_data); + +void +on_reg_passwd_changed (GtkEditable *editable, + gpointer user_data); + +void +on_address_of_record_changed (GtkEditable *editable, + gpointer user_data); + +void +on_aucodec_up_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_down_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_enable_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_disable_clicked (GtkButton *button, + gpointer user_data); + +void +on_sounddriver_changed (GtkEditable *editable, + gpointer user_data); + +void +on_source_changed (GtkEditable *editable, + gpointer user_data); + +void +on_autokill_button1_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_address_book_show (GtkWidget *widget, + gpointer user_data); + +void +on_add_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_remove_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_select_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_modify_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_alt_href_clicked (GtkButton *button, + gpointer user_data); + +void +on_alt_href_realize (GtkWidget *widget, + gpointer user_data); + + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +address_book_close (GtkButton *button, + gpointer user_data); + +void +on_card_changed (GtkEditable *editable, + gpointer user_data); + +void +on_audio_jittcomp_value_changed (GtkRange *range, + gpointer user_data); + +void +on_enable_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_nat_address_changed (GtkEditable *editable, + gpointer user_data); + +void +on_display_ab_clicked (GtkButton *button, + gpointer user_data); + +void +on_ringfileentry_changed (GtkEditable *editable, + gpointer user_data); + +void +on_ringpreview_clicked (GtkButton *button, + gpointer user_data); + +gboolean +on_property_box_closed (GnomeDialog *gnomedialog, + gpointer user_data); + +void +on_address_book_close (GtkObject *object, + gpointer user_data); + +#ifndef VERSION +# define VERSION LINPHONE_VERSION +#endif + +void +on_addfriend_clicked (GtkButton *button, + gpointer user_data); + +void +on_removefriend_clicked (GtkButton *button, + gpointer user_data); + +void +on_add_adbk_clicked (GtkButton *button, + gpointer user_data); + +void +on_addfriend_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_friendlist_row_activated (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data); +void +on_useRSVP_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_useRPC_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +#ifdef VINCENT_MAURY_RSVP +void +dialog_click (GtkDialog *dialog, + gint arg1, + gpointer user_data); +#endif + +void +on_proxy_config_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_removeproxy_button_clicked (GtkButton *button, + gpointer user_data); + +void +on_addproxy_button_clicked (GtkButton *button, + gpointer user_data); + +void +on_editproxy_button_clicked (GtkButton *button, + gpointer user_data); + + +void +on_contact_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_inc_subscr_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_ob_proxy_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_authentication_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_clear_auth_info_clicked (GtkButton *button, + gpointer user_data); + +void +on_use_sipinfo_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_guess_hostname_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_call_history_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_call_logs_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_call_logs_destroy (GtkObject *object, + gpointer user_data); + +void +on_enable_ipv6_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_play_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_capt_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_callbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatbox_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatentry_activate (GtkEntry *entry, + gpointer user_data); + +void +on_hangup_clicked (GtkButton *button, + gpointer user_data); + +void +on_chat_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatroom_destroy (GtkObject *object, + gpointer user_data); + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_addressentry_editing_done (GtkCellEditable *celleditable, + gpointer user_data); + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data); + +gboolean +on_addressentry_key_pressed (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); + +void +on_addressentry_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_addressentry_activate (GtkEntry *entry, + gpointer user_data); + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data); + +void +on_download_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); + +void +on_download_bw_editing_done (GtkCellEditable *celleditable, + gpointer user_data); + +void +on_download_bw_changed (GtkEditable *editable, + gpointer user_data); + +gboolean +on_upload_bw_output (GtkSpinButton *spinbutton, + gpointer user_data); + +void +on_upload_bw_change_value (GtkSpinButton *spinbutton, + GtkScrollType scroll, + gpointer user_data); + +void +on_upload_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); + +gboolean +on_upload_bw_leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer user_data); + +void +on_video_enabled_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_echocancelation_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_no_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_use_stun_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_static_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_stun_server_changed (GtkEditable *editable, + gpointer user_data); diff --git a/linphone/gnome/friends.c b/linphone/gnome/friends.c new file mode 100644 index 000000000..d4da7828e --- /dev/null +++ b/linphone/gnome/friends.c @@ -0,0 +1,127 @@ +/*************************************************************************** + friends.c - display of friend's list + + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "linphone.h" + + +#define get_friend_list() (&uiobj->main_window.friendlist) +#define get_core() (uiobj->core) +#define get_main_window() (&uiobj->main_window) + +enum{ + FRIEND_PRESENCE_IMG, + FRIEND_SIP_ADDRESS, + FRIEND_PRESENCE_STATUS, + FRIEND_ID, + FRIEND_LIST_NCOL +}; + +void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){ + GtkTreeIter iter; + LinphoneFriend *tmp=0; + gboolean found=FALSE; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(fl->friendlist)); + if (gtk_tree_model_get_iter_first(model,&iter)) { + do{ + gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1); + //printf("tmp=%i, fid=%i",tmp,fid); + if (fid==tmp) { + GdkPixbuf *pixbuf; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1); + pixbuf = create_pixbuf(img); + if (pixbuf) + { + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } + found=TRUE; + } + }while(gtk_tree_model_iter_next(model,&iter)); + } + if (found==FALSE){ + //printf("Adding new notifier\n"); + GdkPixbuf *pixbuf; + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_SIP_ADDRESS, url, FRIEND_PRESENCE_STATUS,status,FRIEND_ID,fid,-1); + pixbuf = create_pixbuf(img); + if (pixbuf) gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } +} + + +void +on_friendlist_row_activated (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + gchar* friend; + select = gtk_tree_view_get_selection (treeview); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,FRIEND_SIP_ADDRESS , &friend, -1); + gtk_entry_set_text(GTK_ENTRY(get_main_window()->addressentry),friend); + g_free(friend); + } +} + +void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + + + store = gtk_list_store_new (FRIEND_LIST_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + fl->lc=lc; + fl->friendlist=lookup_widget(mainwidget,"friendlist"); + /* need to add friends to the store here ...*/ + + gtk_tree_view_set_model(GTK_TREE_VIEW(fl->friendlist),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes (NULL, + renderer, + "pixbuf", FRIEND_PRESENCE_IMG, + NULL); + gtk_tree_view_column_set_min_width (column, 29); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", FRIEND_SIP_ADDRESS, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + column = gtk_tree_view_column_new_with_attributes (_("Presence status"), + renderer, + "text", FRIEND_PRESENCE_STATUS, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (fl->friendlist)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + +} diff --git a/linphone/gnome/friends.h b/linphone/gnome/friends.h new file mode 100644 index 000000000..02bf65cb0 --- /dev/null +++ b/linphone/gnome/friends.h @@ -0,0 +1,29 @@ +/*************************************************************************** + friends.h - display of friend's list + + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +struct _FriendList { + LinphoneCore *lc; + GtkWidget *friendlist; +}; + +typedef struct _FriendList FriendList; + +void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget); +void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img); diff --git a/linphone/gnome/gui_utils.c b/linphone/gnome/gui_utils.c new file mode 100644 index 000000000..f58390bc2 --- /dev/null +++ b/linphone/gnome/gui_utils.c @@ -0,0 +1,102 @@ +/* +applet.c - some utils functions that cannot be set in interface.c. + +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "linphone.h" + + +/* creates the applet button* +GtkWidget *create_applet() +{ + GtkWidget *frame; + GtkWidget *button; + GtkWidget *vbox; + GtkWidget *applet; + + applet = applet_widget_new("linphone_applet"); + + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + gtk_widget_show(frame); + + vbox = gtk_vbox_new(FALSE, FALSE); + gtk_container_add(GTK_CONTAINER(frame), vbox); + gtk_widget_show(vbox); + + button = gtk_button_new(); + gtk_widget_ref(button); + GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_DEFAULT); + GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS); + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, TRUE, 0); + + + gtk_widget_show(button); + applet_widget_add (APPLET_WIDGET (applet), frame); + gtk_object_set_data_full(GTK_OBJECT(applet),"applet_button",button,(GtkDestroyNotify)gtk_widget_unref); + gtk_signal_connect(GTK_OBJECT(button), "button_press_event", + GTK_SIGNAL_FUNC(on_applet_clicked), NULL); + gtk_signal_connect(GTK_OBJECT(applet), "change_pixel_size", + GTK_SIGNAL_FUNC(applet_change_pixel_size), NULL); + applet_widget_set_tooltip( APPLET_WIDGET (applet),_("linphone")); + gtk_widget_show(applet); + return(applet); +}; + +*/ +/* this just sets level adjustements for startup*/ +void set_levels(LinphoneGnomeUI *ui,gint reclev, gint playlev, gint ringlev) +{ + GtkWidget *range; + GtkWidget *window=ui->main_window.window; + return; + if (window) + { + range=lookup_widget(window,"rec_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)reclev); + range=lookup_widget(window,"play_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)playlev); + range=lookup_widget(window,"ring_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)ringlev); + } +} + + +void alt_ressource_display(LinphoneGnomeUI *ui,const gchar *url) +{ + GtkWidget *href; + GtkWidget *altdisplay; + GtkLabel *label; + gchar *pattern; + + altdisplay=create_altressource(); + g_object_set_data(G_OBJECT(altdisplay),"ui",(gpointer)ui); + href=lookup_widget(altdisplay,"alt_href"); + label=GTK_LABEL(GTK_BIN(href)->child); + gtk_label_set_text(label,url); + /* pattern used to set underline for string */ + pattern = g_strnfill(strlen(url), '_'); + gtk_label_set_pattern(label,pattern); + g_free(pattern); + gtk_widget_show(altdisplay); +} + + + + diff --git a/linphone/gnome/gui_utils.h b/linphone/gnome/gui_utils.h new file mode 100644 index 000000000..426de9c3d --- /dev/null +++ b/linphone/gnome/gui_utils.h @@ -0,0 +1,33 @@ +/* +applet.h - ome utils functions that cannot be set in interface.c. + +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef GUI_UTILS_H +#define GUI_UTILS_H + +#include "linphone.h" + +/* set audio levels on the main window*/ +void set_levels(LinphoneGnomeUI *ui,gint reclev, gint playlev, gint ringlev); + +/* display an alternate url (used in 380 response) */ +void alt_ressource_display(LinphoneGnomeUI *ui, const gchar *url); + +#endif + diff --git a/linphone/gnome/interface.c b/linphone/gnome/interface.c new file mode 100644 index 000000000..05c3136ae --- /dev/null +++ b/linphone/gnome/interface.c @@ -0,0 +1,2919 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +static GnomeUIInfo connexion1_menu_uiinfo[] = +{ + { + GNOME_APP_UI_ITEM, N_("Address book"), + NULL, + (gpointer) on_adresse_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, "gnome-stock-book-open", + 0, (GdkModifierType) 0, NULL + }, + GNOMEUIINFO_MENU_PREFERENCES_ITEM (on_parametres1_activate, NULL), + { + GNOME_APP_UI_ITEM, N_("Call history"), + N_("Shows calls"), + (gpointer) on_call_history_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, "gtk-justify-fill", + 0, (GdkModifierType) 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_MENU_EXIT_ITEM (on_exit1_activate, NULL), + GNOMEUIINFO_END +}; + +static GnomeUIInfo help1_menu_uiinfo[] = +{ + GNOMEUIINFO_MENU_ABOUT_ITEM (on_about1_activate, NULL), + { + GNOME_APP_UI_ITEM, N_("User manual"), + NULL, + (gpointer) on_user_manual1_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, "gtk-help", + 0, (GdkModifierType) 0, NULL + }, + GNOMEUIINFO_END +}; + +static GnomeUIInfo menubar1_uiinfo[] = +{ + { + GNOME_APP_UI_SUBTREE, N_("Go"), + NULL, + connexion1_menu_uiinfo, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, (GdkModifierType) 0, NULL + }, + GNOMEUIINFO_MENU_HELP_TREE (help1_menu_uiinfo), + GNOMEUIINFO_END +}; + +GtkWidget* +create_app1 (void) +{ + GtkWidget *app1; + GdkPixbuf *app1_icon_pixbuf; + GtkWidget *dock1; + GtkWidget *frame6; + GtkWidget *vbox4; + GtkWidget *vbox24; + GtkWidget *hbox15; + GtkWidget *frame7; + GtkWidget *addressentry; + GtkWidget *label1; + GtkWidget *display_ab; + GtkWidget *alignment22; + GtkWidget *hbox36; + GtkWidget *image33; + GtkWidget *label108; + GtkWidget *proxy_hbox; + GtkWidget *proxytouse_label; + GtkWidget *hbox2; + GtkWidget *callbutton; + GtkWidget *button14; + GtkWidget *button18; + GtkWidget *showmore; + GtkWidget *alignment5; + GtkWidget *hbox17; + GtkWidget *image12; + GtkWidget *label60; + GtkWidget *optioncontrols; + GtkWidget *vbox31; + GtkWidget *frame8; + GtkWidget *vbox5; + GtkWidget *label30; + GtkWidget *play_vol; + GtkWidget *label31; + GtkWidget *rec_vol; + GtkWidget *label110; + GtkWidget *ring_vol; + GtkWidget *label113; + GtkWidget *frame27; + GtkWidget *alignment23; + GtkWidget *vbox32; + GtkWidget *video_enabled; + GtkWidget *label114; + GtkWidget *label33; + GtkWidget *vbox6; + GtkWidget *presence_frame; + GtkWidget *presence_vbox; + GtkWidget *presence_reachable; + GSList *presence_reachable_group = NULL; + GtkWidget *hbox4; + GtkWidget *radiobutton2; + GtkWidget *minutesaway; + GtkWidget *label35; + GtkWidget *radiobutton3; + GtkWidget *radiobutton4; + GtkWidget *radiobutton5; + GtkWidget *radiobutton6; + GtkWidget *hbox5; + GtkWidget *label36; + GtkWidget *contact_field; + GtkWidget *label34; + GtkWidget *frame19; + GtkWidget *vbox18; + GtkWidget *dtmf_entry; + GtkWidget *table5; + GtkWidget *dtmf_3; + GtkWidget *dmtf_2; + GtkWidget *dtmf_1; + GtkWidget *dtmf_4; + GtkWidget *dtmf_5; + GtkWidget *dtmf_6; + GtkWidget *dtmf_7; + GtkWidget *dtmf_8; + GtkWidget *dtmf_9; + GtkWidget *dtmf_star; + GtkWidget *dtmf_0; + GtkWidget *dtmf_pound; + GtkWidget *label38; + GtkWidget *vbox22; + GtkWidget *scrolledwindow3; + GtkWidget *friendlist; + GtkWidget *label65; + GtkWidget *appbar1; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + app1 = gnome_app_new ("Linphone", _("linphone")); + gtk_window_set_resizable (GTK_WINDOW (app1), FALSE); + app1_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (app1_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (app1), app1_icon_pixbuf); + gdk_pixbuf_unref (app1_icon_pixbuf); + } + + dock1 = GNOME_APP (app1)->dock; + gtk_widget_show (dock1); + + gnome_app_create_menus (GNOME_APP (app1), menubar1_uiinfo); + + frame6 = gtk_frame_new (NULL); + gtk_widget_show (frame6); + gnome_app_set_contents (GNOME_APP (app1), frame6); + gtk_container_set_border_width (GTK_CONTAINER (frame6), 9); + + vbox4 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox4); + gtk_container_add (GTK_CONTAINER (frame6), vbox4); + + vbox24 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox24); + gtk_box_pack_start (GTK_BOX (vbox4), vbox24, TRUE, TRUE, 0); + + hbox15 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox15); + gtk_box_pack_start (GTK_BOX (vbox24), hbox15, TRUE, TRUE, 0); + + frame7 = gtk_frame_new (NULL); + gtk_widget_show (frame7); + gtk_box_pack_start (GTK_BOX (hbox15), frame7, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame7), 5); + + addressentry = gtk_entry_new (); + gtk_widget_show (addressentry); + gtk_container_add (GTK_CONTAINER (frame7), addressentry); + gtk_tooltips_set_tip (tooltips, addressentry, _("enter sip uri here"), NULL); + gtk_entry_set_text (GTK_ENTRY (addressentry), _("sip:")); + + label1 = gtk_label_new (_("Sip address:")); + gtk_widget_show (label1); + gtk_frame_set_label_widget (GTK_FRAME (frame7), label1); + + display_ab = gtk_button_new (); + gtk_widget_show (display_ab); + gtk_box_pack_start (GTK_BOX (hbox15), display_ab, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (display_ab), 15); + gtk_tooltips_set_tip (tooltips, display_ab, _("Shows the address book"), NULL); + + alignment22 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment22); + gtk_container_add (GTK_CONTAINER (display_ab), alignment22); + + hbox36 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox36); + gtk_container_add (GTK_CONTAINER (alignment22), hbox36); + + image33 = gtk_image_new_from_stock ("gnome-stock-book-open", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image33); + gtk_box_pack_start (GTK_BOX (hbox36), image33, FALSE, FALSE, 0); + + label108 = gtk_label_new_with_mnemonic (_("...")); + gtk_widget_show (label108); + gtk_box_pack_start (GTK_BOX (hbox36), label108, FALSE, FALSE, 0); + + proxy_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show (proxy_hbox); + gtk_box_pack_start (GTK_BOX (vbox24), proxy_hbox, TRUE, TRUE, 0); + + proxytouse_label = gtk_label_new (_("Proxy to use:")); + gtk_widget_show (proxytouse_label); + gtk_box_pack_start (GTK_BOX (proxy_hbox), proxytouse_label, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (proxytouse_label), GTK_JUSTIFY_CENTER); + + hbox2 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox2); + gtk_box_pack_start (GTK_BOX (vbox4), hbox2, TRUE, TRUE, 0); + + callbutton = gtk_button_new_with_mnemonic (_("Call or\nanswer")); + gtk_widget_show (callbutton); + gtk_box_pack_start (GTK_BOX (hbox2), callbutton, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (callbutton), 8); + + button14 = gtk_button_new_with_mnemonic (_("Hangup\nor refuse")); + gtk_widget_show (button14); + gtk_box_pack_start (GTK_BOX (hbox2), button14, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (button14), 8); + + button18 = gtk_button_new_with_mnemonic (_("Or chat !")); + gtk_widget_show (button18); + gtk_box_pack_start (GTK_BOX (vbox4), button18, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (button18), 8); + + showmore = gtk_check_button_new (); + gtk_widget_show (showmore); + gtk_box_pack_start (GTK_BOX (vbox4), showmore, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (showmore), TRUE); + + alignment5 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment5); + gtk_container_add (GTK_CONTAINER (showmore), alignment5); + + hbox17 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox17); + gtk_container_add (GTK_CONTAINER (alignment5), hbox17); + + image12 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image12); + gtk_box_pack_start (GTK_BOX (hbox17), image12, FALSE, FALSE, 0); + + label60 = gtk_label_new_with_mnemonic (_("Show more...")); + gtk_widget_show (label60); + gtk_box_pack_start (GTK_BOX (hbox17), label60, FALSE, FALSE, 0); + + optioncontrols = gtk_notebook_new (); + gtk_widget_show (optioncontrols); + gtk_box_pack_start (GTK_BOX (vbox4), optioncontrols, TRUE, TRUE, 0); + + vbox31 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox31); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox31); + + frame8 = gtk_frame_new (NULL); + gtk_widget_show (frame8); + gtk_box_pack_start (GTK_BOX (vbox31), frame8, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame8), 11); + + vbox5 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox5); + gtk_container_add (GTK_CONTAINER (frame8), vbox5); + gtk_container_set_border_width (GTK_CONTAINER (vbox5), 2); + + label30 = gtk_label_new (_("Playback level:")); + gtk_widget_show (label30); + gtk_box_pack_start (GTK_BOX (vbox5), label30, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label30), 7.45058e-09, 0.5); + + play_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (play_vol); + gtk_box_pack_start (GTK_BOX (vbox5), play_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (play_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (play_vol), 0); + + label31 = gtk_label_new (_("Recording level:")); + gtk_widget_show (label31); + gtk_box_pack_start (GTK_BOX (vbox5), label31, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label31), 7.45058e-09, 0.5); + + rec_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (rec_vol); + gtk_box_pack_start (GTK_BOX (vbox5), rec_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (rec_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (rec_vol), 0); + + label110 = gtk_label_new (_("Ring level:")); + gtk_widget_show (label110); + gtk_box_pack_start (GTK_BOX (vbox5), label110, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label110), 7.45058e-09, 0.5); + + ring_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (ring_vol); + gtk_box_pack_start (GTK_BOX (vbox5), ring_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (ring_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (ring_vol), 0); + + label113 = gtk_label_new (_("Sound")); + gtk_widget_show (label113); + gtk_frame_set_label_widget (GTK_FRAME (frame8), label113); + + frame27 = gtk_frame_new (NULL); + gtk_widget_show (frame27); + gtk_box_pack_start (GTK_BOX (vbox31), frame27, FALSE, FALSE, 0); + + alignment23 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment23); + gtk_container_add (GTK_CONTAINER (frame27), alignment23); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment23), 0, 0, 12, 0); + + vbox32 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox32); + gtk_container_add (GTK_CONTAINER (alignment23), vbox32); + + video_enabled = gtk_check_button_new_with_mnemonic (_("Enable video")); + gtk_widget_show (video_enabled); + gtk_box_pack_start (GTK_BOX (vbox32), video_enabled, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (video_enabled), TRUE); + + label114 = gtk_label_new (_("Video")); + gtk_widget_show (label114); + gtk_frame_set_label_widget (GTK_FRAME (frame27), label114); + gtk_label_set_use_markup (GTK_LABEL (label114), TRUE); + + label33 = gtk_label_new (_("Controls")); + gtk_widget_show (label33); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 0), label33); + gtk_label_set_justify (GTK_LABEL (label33), GTK_JUSTIFY_CENTER); + + vbox6 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox6); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox6); + + presence_frame = gtk_frame_new (NULL); + gtk_widget_show (presence_frame); + gtk_box_pack_start (GTK_BOX (vbox6), presence_frame, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (presence_frame), 11); + + presence_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (presence_vbox); + gtk_container_add (GTK_CONTAINER (presence_frame), presence_vbox); + + presence_reachable = gtk_radio_button_new_with_mnemonic (NULL, _("Reachable")); + gtk_widget_show (presence_reachable); + gtk_box_pack_start (GTK_BOX (presence_vbox), presence_reachable, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (presence_reachable), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (presence_reachable)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (presence_reachable), TRUE); + + hbox4 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox4); + gtk_box_pack_start (GTK_BOX (presence_vbox), hbox4, FALSE, TRUE, 0); + + radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, _("Busy, I'll be back in ")); + gtk_widget_show (radiobutton2); + gtk_box_pack_start (GTK_BOX (hbox4), radiobutton2, TRUE, TRUE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2)); + + minutesaway = gtk_entry_new (); + gtk_widget_show (minutesaway); + gtk_box_pack_start (GTK_BOX (hbox4), minutesaway, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, minutesaway, _("The other party will be informed that you'll be back in X minutes"), NULL); + gtk_entry_set_text (GTK_ENTRY (minutesaway), _("5")); + + label35 = gtk_label_new (_("mn")); + gtk_widget_show (label35); + gtk_box_pack_start (GTK_BOX (hbox4), label35, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label35), GTK_JUSTIFY_CENTER); + + radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("Away")); + gtk_widget_show (radiobutton3); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton3, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3)); + + radiobutton4 = gtk_radio_button_new_with_mnemonic (NULL, _("Do not disturb")); + gtk_widget_show (radiobutton4); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton4, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton4), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton4)); + + radiobutton5 = gtk_radio_button_new_with_mnemonic (NULL, _("Moved temporarily")); + gtk_widget_show (radiobutton5); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton5, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton5), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton5)); + + radiobutton6 = gtk_radio_button_new_with_mnemonic (NULL, _("Alternative service")); + gtk_widget_show (radiobutton6); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton6, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton6), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton6)); + + hbox5 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox5); + gtk_box_pack_start (GTK_BOX (presence_vbox), hbox5, FALSE, TRUE, 0); + + label36 = gtk_label_new (_("URL:")); + gtk_widget_show (label36); + gtk_box_pack_start (GTK_BOX (hbox5), label36, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label36), GTK_JUSTIFY_CENTER); + + contact_field = gtk_entry_new (); + gtk_widget_show (contact_field); + gtk_box_pack_start (GTK_BOX (hbox5), contact_field, FALSE, FALSE, 0); + + label34 = gtk_label_new (_("Presence")); + gtk_widget_show (label34); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 1), label34); + gtk_label_set_justify (GTK_LABEL (label34), GTK_JUSTIFY_CENTER); + + frame19 = gtk_frame_new (NULL); + gtk_widget_show (frame19); + gtk_container_add (GTK_CONTAINER (optioncontrols), frame19); + gtk_container_set_border_width (GTK_CONTAINER (frame19), 15); + + vbox18 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox18); + gtk_container_add (GTK_CONTAINER (frame19), vbox18); + + dtmf_entry = gtk_entry_new (); + gtk_widget_show (dtmf_entry); + gtk_box_pack_start (GTK_BOX (vbox18), dtmf_entry, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, dtmf_entry, _("Press digits to send DTMFs."), NULL); + + table5 = gtk_table_new (4, 3, TRUE); + gtk_widget_show (table5); + gtk_box_pack_start (GTK_BOX (vbox18), table5, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (table5), 14); + gtk_table_set_row_spacings (GTK_TABLE (table5), 10); + gtk_table_set_col_spacings (GTK_TABLE (table5), 10); + + dtmf_3 = gtk_button_new_with_mnemonic (_(" 3\ndef")); + gtk_widget_show (dtmf_3); + gtk_table_attach (GTK_TABLE (table5), dtmf_3, 2, 3, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dmtf_2 = gtk_button_new_with_mnemonic (_(" 2\nabc")); + gtk_widget_show (dmtf_2); + gtk_table_attach (GTK_TABLE (table5), dmtf_2, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_1 = gtk_button_new_with_mnemonic (_("1")); + gtk_widget_show (dtmf_1); + gtk_table_attach (GTK_TABLE (table5), dtmf_1, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_4 = gtk_button_new_with_mnemonic (_(" 4\nghi")); + gtk_widget_show (dtmf_4); + gtk_table_attach (GTK_TABLE (table5), dtmf_4, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_5 = gtk_button_new_with_mnemonic (_(" 5\njkl")); + gtk_widget_show (dtmf_5); + gtk_table_attach (GTK_TABLE (table5), dtmf_5, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_6 = gtk_button_new_with_mnemonic (_(" 6\nmno")); + gtk_widget_show (dtmf_6); + gtk_table_attach (GTK_TABLE (table5), dtmf_6, 2, 3, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_7 = gtk_button_new_with_mnemonic (_(" 7\npqrs")); + gtk_widget_show (dtmf_7); + gtk_table_attach (GTK_TABLE (table5), dtmf_7, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_8 = gtk_button_new_with_mnemonic (_(" 8\ntuv")); + gtk_widget_show (dtmf_8); + gtk_table_attach (GTK_TABLE (table5), dtmf_8, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_9 = gtk_button_new_with_mnemonic (_(" 9\nwxyz")); + gtk_widget_show (dtmf_9); + gtk_table_attach (GTK_TABLE (table5), dtmf_9, 2, 3, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_star = gtk_button_new_with_mnemonic (_("*")); + gtk_widget_show (dtmf_star); + gtk_table_attach (GTK_TABLE (table5), dtmf_star, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_0 = gtk_button_new_with_mnemonic (_("0")); + gtk_widget_show (dtmf_0); + gtk_table_attach (GTK_TABLE (table5), dtmf_0, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_pound = gtk_button_new_with_mnemonic (_("#")); + gtk_widget_show (dtmf_pound); + gtk_table_attach (GTK_TABLE (table5), dtmf_pound, 2, 3, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + label38 = gtk_label_new (_("DTMF")); + gtk_widget_show (label38); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 2), label38); + gtk_label_set_justify (GTK_LABEL (label38), GTK_JUSTIFY_CENTER); + + vbox22 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox22); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox22); + + scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow3); + gtk_box_pack_start (GTK_BOX (vbox22), scrolledwindow3, TRUE, TRUE, 0); + + friendlist = gtk_tree_view_new (); + gtk_widget_show (friendlist); + gtk_container_add (GTK_CONTAINER (scrolledwindow3), friendlist); + + label65 = gtk_label_new (_("My online friends")); + gtk_widget_show (label65); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 3), label65); + + appbar1 = gnome_appbar_new (FALSE, TRUE, GNOME_PREFERENCES_NEVER); + gtk_widget_show (appbar1); + gnome_app_set_statusbar (GNOME_APP (app1), appbar1); + + g_signal_connect ((gpointer) app1, "destroy", + G_CALLBACK (on_app1_destroy), + NULL); + gnome_app_install_menu_hints (GNOME_APP (app1), menubar1_uiinfo); + g_signal_connect ((gpointer) addressentry, "activate", + G_CALLBACK (on_addressentry_activate), + NULL); + g_signal_connect ((gpointer) addressentry, "destroy", + G_CALLBACK (on_addressentry_destroy), + NULL); + g_signal_connect ((gpointer) display_ab, "clicked", + G_CALLBACK (on_display_ab_clicked), + NULL); + g_signal_connect ((gpointer) callbutton, "clicked", + G_CALLBACK (on_callbutton_clicked), + NULL); + g_signal_connect ((gpointer) button14, "clicked", + G_CALLBACK (on_hangup_clicked), + NULL); + g_signal_connect ((gpointer) button18, "clicked", + G_CALLBACK (on_chat_clicked), + NULL); + g_signal_connect ((gpointer) showmore, "toggled", + G_CALLBACK (on_showmore_toggled), + NULL); + g_signal_connect ((gpointer) play_vol, "button_release_event", + G_CALLBACK (on_play_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) rec_vol, "button_release_event", + G_CALLBACK (on_rec_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) ring_vol, "button_release_event", + G_CALLBACK (on_rec_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) video_enabled, "toggled", + G_CALLBACK (on_video_enabled_toggled), + NULL); + g_signal_connect ((gpointer) presence_reachable, "toggled", + G_CALLBACK (on_reachable), + NULL); + g_signal_connect ((gpointer) radiobutton2, "toggled", + G_CALLBACK (on_busy), + NULL); + g_signal_connect ((gpointer) minutesaway, "changed", + G_CALLBACK (on_minutesaway_changed), + NULL); + g_signal_connect ((gpointer) radiobutton3, "toggled", + G_CALLBACK (on_away), + NULL); + g_signal_connect ((gpointer) radiobutton4, "toggled", + G_CALLBACK (on_do_not_disturb), + NULL); + g_signal_connect ((gpointer) radiobutton5, "toggled", + G_CALLBACK (on_moved_tmply), + NULL); + g_signal_connect ((gpointer) radiobutton6, "toggled", + G_CALLBACK (on_alt_serv), + NULL); + g_signal_connect ((gpointer) contact_field, "changed", + G_CALLBACK (on_contact_field_changed), + NULL); + g_signal_connect ((gpointer) dtmf_entry, "changed", + G_CALLBACK (on_dtmf_entry_changed), + NULL); + g_signal_connect ((gpointer) dtmf_3, "clicked", + G_CALLBACK (on_dtmf_3_clicked), + NULL); + g_signal_connect ((gpointer) dmtf_2, "clicked", + G_CALLBACK (on_dmtf_2_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_1, "clicked", + G_CALLBACK (on_dtmf_1_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_4, "clicked", + G_CALLBACK (on_dtmf_4_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_5, "clicked", + G_CALLBACK (on_dtmf_5_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_6, "clicked", + G_CALLBACK (on_dtmf_6_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_7, "clicked", + G_CALLBACK (on_dtmf_7_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_8, "clicked", + G_CALLBACK (on_dtmf_8_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_9, "clicked", + G_CALLBACK (on_dtmf_9_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_star, "clicked", + G_CALLBACK (on_dtmf_star_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_0, "clicked", + G_CALLBACK (on_dtmf_0_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_pound, "clicked", + G_CALLBACK (on_dtmf_pound_clicked), + NULL); + g_signal_connect ((gpointer) friendlist, "row_activated", + G_CALLBACK (on_friendlist_row_activated), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (app1, app1, "app1"); + GLADE_HOOKUP_OBJECT (app1, dock1, "dock1"); + GLADE_HOOKUP_OBJECT (app1, menubar1_uiinfo[0].widget, "connexion1"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu_uiinfo[0].widget, "addresse1"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu_uiinfo[1].widget, "parametres1"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu_uiinfo[2].widget, "call_history"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu_uiinfo[3].widget, "separator1"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu_uiinfo[4].widget, "exit1"); + GLADE_HOOKUP_OBJECT (app1, menubar1_uiinfo[1].widget, "help1"); + GLADE_HOOKUP_OBJECT (app1, help1_menu_uiinfo[0].widget, "about1"); + GLADE_HOOKUP_OBJECT (app1, help1_menu_uiinfo[1].widget, "user_manual1"); + GLADE_HOOKUP_OBJECT (app1, frame6, "frame6"); + GLADE_HOOKUP_OBJECT (app1, vbox4, "vbox4"); + GLADE_HOOKUP_OBJECT (app1, vbox24, "vbox24"); + GLADE_HOOKUP_OBJECT (app1, hbox15, "hbox15"); + GLADE_HOOKUP_OBJECT (app1, frame7, "frame7"); + GLADE_HOOKUP_OBJECT (app1, addressentry, "addressentry"); + GLADE_HOOKUP_OBJECT (app1, label1, "label1"); + GLADE_HOOKUP_OBJECT (app1, display_ab, "display_ab"); + GLADE_HOOKUP_OBJECT (app1, alignment22, "alignment22"); + GLADE_HOOKUP_OBJECT (app1, hbox36, "hbox36"); + GLADE_HOOKUP_OBJECT (app1, image33, "image33"); + GLADE_HOOKUP_OBJECT (app1, label108, "label108"); + GLADE_HOOKUP_OBJECT (app1, proxy_hbox, "proxy_hbox"); + GLADE_HOOKUP_OBJECT (app1, proxytouse_label, "proxytouse_label"); + GLADE_HOOKUP_OBJECT (app1, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (app1, callbutton, "callbutton"); + GLADE_HOOKUP_OBJECT (app1, button14, "button14"); + GLADE_HOOKUP_OBJECT (app1, button18, "button18"); + GLADE_HOOKUP_OBJECT (app1, showmore, "showmore"); + GLADE_HOOKUP_OBJECT (app1, alignment5, "alignment5"); + GLADE_HOOKUP_OBJECT (app1, hbox17, "hbox17"); + GLADE_HOOKUP_OBJECT (app1, image12, "image12"); + GLADE_HOOKUP_OBJECT (app1, label60, "label60"); + GLADE_HOOKUP_OBJECT (app1, optioncontrols, "optioncontrols"); + GLADE_HOOKUP_OBJECT (app1, vbox31, "vbox31"); + GLADE_HOOKUP_OBJECT (app1, frame8, "frame8"); + GLADE_HOOKUP_OBJECT (app1, vbox5, "vbox5"); + GLADE_HOOKUP_OBJECT (app1, label30, "label30"); + GLADE_HOOKUP_OBJECT (app1, play_vol, "play_vol"); + GLADE_HOOKUP_OBJECT (app1, label31, "label31"); + GLADE_HOOKUP_OBJECT (app1, rec_vol, "rec_vol"); + GLADE_HOOKUP_OBJECT (app1, label110, "label110"); + GLADE_HOOKUP_OBJECT (app1, ring_vol, "ring_vol"); + GLADE_HOOKUP_OBJECT (app1, label113, "label113"); + GLADE_HOOKUP_OBJECT (app1, frame27, "frame27"); + GLADE_HOOKUP_OBJECT (app1, alignment23, "alignment23"); + GLADE_HOOKUP_OBJECT (app1, vbox32, "vbox32"); + GLADE_HOOKUP_OBJECT (app1, video_enabled, "video_enabled"); + GLADE_HOOKUP_OBJECT (app1, label114, "label114"); + GLADE_HOOKUP_OBJECT (app1, label33, "label33"); + GLADE_HOOKUP_OBJECT (app1, vbox6, "vbox6"); + GLADE_HOOKUP_OBJECT (app1, presence_frame, "presence_frame"); + GLADE_HOOKUP_OBJECT (app1, presence_vbox, "presence_vbox"); + GLADE_HOOKUP_OBJECT (app1, presence_reachable, "presence_reachable"); + GLADE_HOOKUP_OBJECT (app1, hbox4, "hbox4"); + GLADE_HOOKUP_OBJECT (app1, radiobutton2, "radiobutton2"); + GLADE_HOOKUP_OBJECT (app1, minutesaway, "minutesaway"); + GLADE_HOOKUP_OBJECT (app1, label35, "label35"); + GLADE_HOOKUP_OBJECT (app1, radiobutton3, "radiobutton3"); + GLADE_HOOKUP_OBJECT (app1, radiobutton4, "radiobutton4"); + GLADE_HOOKUP_OBJECT (app1, radiobutton5, "radiobutton5"); + GLADE_HOOKUP_OBJECT (app1, radiobutton6, "radiobutton6"); + GLADE_HOOKUP_OBJECT (app1, hbox5, "hbox5"); + GLADE_HOOKUP_OBJECT (app1, label36, "label36"); + GLADE_HOOKUP_OBJECT (app1, contact_field, "contact_field"); + GLADE_HOOKUP_OBJECT (app1, label34, "label34"); + GLADE_HOOKUP_OBJECT (app1, frame19, "frame19"); + GLADE_HOOKUP_OBJECT (app1, vbox18, "vbox18"); + GLADE_HOOKUP_OBJECT (app1, dtmf_entry, "dtmf_entry"); + GLADE_HOOKUP_OBJECT (app1, table5, "table5"); + GLADE_HOOKUP_OBJECT (app1, dtmf_3, "dtmf_3"); + GLADE_HOOKUP_OBJECT (app1, dmtf_2, "dmtf_2"); + GLADE_HOOKUP_OBJECT (app1, dtmf_1, "dtmf_1"); + GLADE_HOOKUP_OBJECT (app1, dtmf_4, "dtmf_4"); + GLADE_HOOKUP_OBJECT (app1, dtmf_5, "dtmf_5"); + GLADE_HOOKUP_OBJECT (app1, dtmf_6, "dtmf_6"); + GLADE_HOOKUP_OBJECT (app1, dtmf_7, "dtmf_7"); + GLADE_HOOKUP_OBJECT (app1, dtmf_8, "dtmf_8"); + GLADE_HOOKUP_OBJECT (app1, dtmf_9, "dtmf_9"); + GLADE_HOOKUP_OBJECT (app1, dtmf_star, "dtmf_star"); + GLADE_HOOKUP_OBJECT (app1, dtmf_0, "dtmf_0"); + GLADE_HOOKUP_OBJECT (app1, dtmf_pound, "dtmf_pound"); + GLADE_HOOKUP_OBJECT (app1, label38, "label38"); + GLADE_HOOKUP_OBJECT (app1, vbox22, "vbox22"); + GLADE_HOOKUP_OBJECT (app1, scrolledwindow3, "scrolledwindow3"); + GLADE_HOOKUP_OBJECT (app1, friendlist, "friendlist"); + GLADE_HOOKUP_OBJECT (app1, label65, "label65"); + GLADE_HOOKUP_OBJECT (app1, appbar1, "appbar1"); + GLADE_HOOKUP_OBJECT_NO_REF (app1, tooltips, "tooltips"); + + gtk_widget_grab_focus (appbar1); + return app1; +} + +GtkWidget* +create_about2 (void) +{ + const gchar *authors[] = { + "Simon MORLAT", + "Aymeric Moizard", + "Sharath K Udupa", + NULL + }; + const gchar *documenters[] = { + "Simon MORLAT", + "Philippe Beau", + NULL + }; + gchar *translators = "it: Alberto Zanoni\nde: Jean Jacques Sarton\nfr: Simon Morlat\nes: Jesus Benitez\nja: Yamaguchi Yoshiya\npl: obert Nasiadek \npt_BR: Rafael Caesar Lenzi \nsv: Daniel Nylander "; + GdkPixbuf *about2_logo_pixbuf; + GtkWidget *about2; + GdkPixbuf *about2_icon_pixbuf; + + about2_logo_pixbuf = create_pixbuf ("linphone/linphone.png"); + about2 = gnome_about_new ("Linphone", VERSION, + _("C: 2001\nMade in Old Europe"), + _("Linphone is a web-phone.\nIt is compatible with SIP and RTP protocols."), + authors, + documenters, + translators, + about2_logo_pixbuf); + gtk_container_set_border_width (GTK_CONTAINER (about2), 5); + gtk_window_set_destroy_with_parent (GTK_WINDOW (about2), TRUE); + about2_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (about2_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (about2), about2_icon_pixbuf); + gdk_pixbuf_unref (about2_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (about2), GDK_WINDOW_TYPE_HINT_DIALOG); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (about2, about2, "about2"); + + return about2; +} + +GtkWidget* +create_prop1 (void) +{ + GtkWidget *prop1; + GdkPixbuf *prop1_icon_pixbuf; + GtkWidget *notebook1; + GtkWidget *vbox9; + GtkWidget *frame26; + GtkWidget *alignment21; + GtkWidget *vbox29; + GtkWidget *enable_ipv6; + GtkWidget *label105; + GtkWidget *frame21; + GtkWidget *vbox21; + GtkWidget *label56; + GtkWidget *table13; + GtkWidget *no_nat; + GSList *no_nat_group = NULL; + GtkWidget *use_stun; + GtkWidget *static_nat; + GtkWidget *nat_address; + GtkWidget *stun_server; + GtkWidget *label55; + GtkWidget *frame20; + GtkWidget *table6; + GtkWidget *audio_jittcomp; + GtkObject *audioport_adj; + GtkWidget *audioport; + GtkWidget *label52; + GtkWidget *label53; + GtkWidget *label54; + GtkWidget *frame25; + GtkWidget *alignment20; + GtkWidget *vbox28; + GtkWidget *use_sipinfo; + GtkWidget *label103; + GtkWidget *network; + GtkWidget *vbox12; + GtkWidget *vbox20; + GtkWidget *frame17; + GtkWidget *vbox16; + GtkWidget *table4; + GtkWidget *label10; + GtkWidget *combo3; + GList *combo3_items = NULL; + GtkWidget *rec_source; + GtkWidget *label106; + GtkWidget *play_card; + GtkWidget *capt_card; + GtkWidget *hbox20; + GtkWidget *ringfileentry; + GtkWidget *combo_entry1; + GtkWidget *ringpreview; + GtkWidget *alignment8; + GtkWidget *hbox21; + GtkWidget *image15; + GtkWidget *label64; + GtkWidget *label11; + GtkWidget *ringsnddev_label; + GtkWidget *label63; + GtkWidget *ring_card; + GtkWidget *echocancelation; + GtkWidget *label115; + GtkWidget *label48; + GtkWidget *sound; + GtkWidget *vbox7; + GtkWidget *frame10; + GtkWidget *hbox6; + GtkWidget *label13; + GtkObject *sip_port_adj; + GtkWidget *sip_port; + GtkWidget *label43; + GtkWidget *frame11; + GtkWidget *vbox27; + GtkWidget *hbox7; + GtkWidget *label26; + GtkWidget *label27; + GtkWidget *user_name; + GtkWidget *label28; + GtkWidget *domain_name; + GtkWidget *guess_hostname; + GtkWidget *label44; + GtkWidget *frame1; + GtkWidget *vbox23; + GtkWidget *scrolledwindow4; + GtkWidget *proxy_list; + GtkWidget *hbuttonbox6; + GtkWidget *addproxy_button; + GtkWidget *alignment12; + GtkWidget *hbox25; + GtkWidget *image19; + GtkWidget *label77; + GtkWidget *editproxy_button; + GtkWidget *alignment13; + GtkWidget *hbox26; + GtkWidget *image20; + GtkWidget *label78; + GtkWidget *removeproxy_button; + GtkWidget *alignment14; + GtkWidget *hbox27; + GtkWidget *image21; + GtkWidget *label79; + GtkWidget *label45; + GtkWidget *frame24; + GtkWidget *alignment18; + GtkWidget *clear_auth_info; + GtkWidget *alignment19; + GtkWidget *hbox34; + GtkWidget *image27; + GtkWidget *label102; + GtkWidget *label101; + GtkWidget *sip_pref; + GtkWidget *vbox13; + GtkWidget *frame16; + GtkWidget *hbox9; + GtkWidget *vbox14; + GtkWidget *label9; + GtkWidget *codec_notebook; + GtkWidget *scrolledwindow2; + GtkWidget *au_codec_list; + GtkWidget *label116; + GtkWidget *scrolledwindow7; + GtkWidget *vid_codec_list; + GtkWidget *label117; + GtkWidget *hbuttonbox4; + GtkWidget *aucodec_up; + GtkWidget *aucodec_down; + GtkWidget *aucodec_enable; + GtkWidget *alignment1; + GtkWidget *hbox11; + GtkWidget *image4; + GtkWidget *label50; + GtkWidget *aucodec_disable; + GtkWidget *alignment2; + GtkWidget *hbox12; + GtkWidget *image5; + GtkWidget *label51; + GtkWidget *table12; + GtkWidget *label112; + GtkWidget *label111; + GtkObject *download_bw_adj; + GtkWidget *download_bw; + GtkObject *upload_bw_adj; + GtkWidget *upload_bw; + GtkWidget *vbox17; + GtkWidget *label22; + GtkWidget *frame18; + GtkWidget *codec_info; + GtkWidget *label47; + GtkWidget *label46; + GtkWidget *codecs_pref; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + prop1 = gnome_property_box_new (); + gtk_window_set_title (GTK_WINDOW (prop1), _("Parameters")); + gtk_window_set_resizable (GTK_WINDOW (prop1), FALSE); + prop1_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (prop1_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (prop1), prop1_icon_pixbuf); + gdk_pixbuf_unref (prop1_icon_pixbuf); + } + + notebook1 = GNOME_PROPERTY_BOX (prop1)->notebook; + gtk_widget_show (notebook1); + + vbox9 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox9); + gtk_container_add (GTK_CONTAINER (notebook1), vbox9); + + frame26 = gtk_frame_new (NULL); + gtk_widget_show (frame26); + gtk_box_pack_start (GTK_BOX (vbox9), frame26, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame26), 6); + + alignment21 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment21); + gtk_container_add (GTK_CONTAINER (frame26), alignment21); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment21), 0, 0, 12, 0); + + vbox29 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox29); + gtk_container_add (GTK_CONTAINER (alignment21), vbox29); + + enable_ipv6 = gtk_check_button_new_with_mnemonic (_("Use IPv6 network (if available)")); + gtk_widget_show (enable_ipv6); + gtk_box_pack_start (GTK_BOX (vbox29), enable_ipv6, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, enable_ipv6, _("Toggle this if you are on an ipv6 network and you wish linphone to use it."), NULL); + + label105 = gtk_label_new (_("Global")); + gtk_widget_show (label105); + gtk_frame_set_label_widget (GTK_FRAME (frame26), label105); + gtk_label_set_use_markup (GTK_LABEL (label105), TRUE); + + frame21 = gtk_frame_new (NULL); + gtk_widget_show (frame21); + gtk_box_pack_start (GTK_BOX (vbox9), frame21, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame21), 5); + + vbox21 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox21); + gtk_container_add (GTK_CONTAINER (frame21), vbox21); + gtk_container_set_border_width (GTK_CONTAINER (vbox21), 6); + + label56 = gtk_label_new (_("These options is only for users in a private network, behind a gateway. If you are not in this situation, then leave this empty.")); + gtk_widget_show (label56); + gtk_box_pack_start (GTK_BOX (vbox21), label56, TRUE, TRUE, 0); + gtk_label_set_line_wrap (GTK_LABEL (label56), TRUE); + gtk_misc_set_padding (GTK_MISC (label56), 0, 12); + + table13 = gtk_table_new (3, 2, FALSE); + gtk_widget_show (table13); + gtk_box_pack_start (GTK_BOX (vbox21), table13, FALSE, FALSE, 0); + + no_nat = gtk_radio_button_new_with_mnemonic (NULL, _("No firewall")); + gtk_widget_show (no_nat); + gtk_table_attach (GTK_TABLE (table13), no_nat, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (no_nat), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (no_nat)); + + use_stun = gtk_radio_button_new_with_mnemonic (NULL, _("Use this STUN server to guess firewall address :")); + gtk_widget_show (use_stun); + gtk_table_attach (GTK_TABLE (table13), use_stun, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (use_stun), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (use_stun)); + + static_nat = gtk_radio_button_new_with_mnemonic (NULL, _("Specify firewall address manually:")); + gtk_widget_show (static_nat); + gtk_table_attach (GTK_TABLE (table13), static_nat, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (static_nat), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (static_nat)); + + nat_address = gtk_entry_new (); + gtk_widget_show (nat_address); + gtk_table_attach (GTK_TABLE (table13), nat_address, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + stun_server = gtk_entry_new (); + gtk_widget_show (stun_server); + gtk_table_attach (GTK_TABLE (table13), stun_server, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label55 = gtk_label_new (_("NAT traversal options (experimental)")); + gtk_widget_show (label55); + gtk_frame_set_label_widget (GTK_FRAME (frame21), label55); + + frame20 = gtk_frame_new (NULL); + gtk_widget_show (frame20); + gtk_box_pack_start (GTK_BOX (vbox9), frame20, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame20), 5); + + table6 = gtk_table_new (2, 2, FALSE); + gtk_widget_show (table6); + gtk_container_add (GTK_CONTAINER (frame20), table6); + + audio_jittcomp = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (150, 60, 512, 10, 0, 0))); + gtk_widget_show (audio_jittcomp); + gtk_table_attach (GTK_TABLE (table6), audio_jittcomp, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND), 20, 0); + gtk_scale_set_value_pos (GTK_SCALE (audio_jittcomp), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (audio_jittcomp), 0); + + audioport_adj = gtk_adjustment_new (7000, 5000, 65535, 1, 10, 10); + audioport = gtk_spin_button_new (GTK_ADJUSTMENT (audioport_adj), 4, 0); + gtk_widget_show (audioport); + gtk_table_attach (GTK_TABLE (table6), audioport, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND), 20, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (audioport), TRUE); + + label52 = gtk_label_new (_("Number of buffered miliseconds (jitter compensation):")); + gtk_widget_show (label52); + gtk_table_attach (GTK_TABLE (table6), label52, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label52), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label52), TRUE); + + label53 = gtk_label_new (_("RTP port used for audio:")); + gtk_widget_show (label53); + gtk_table_attach (GTK_TABLE (table6), label53, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_label_set_justify (GTK_LABEL (label53), GTK_JUSTIFY_CENTER); + + label54 = gtk_label_new (_("RTP properties")); + gtk_widget_show (label54); + gtk_frame_set_label_widget (GTK_FRAME (frame20), label54); + + frame25 = gtk_frame_new (NULL); + gtk_widget_show (frame25); + gtk_box_pack_start (GTK_BOX (vbox9), frame25, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame25), 5); + + alignment20 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment20); + gtk_container_add (GTK_CONTAINER (frame25), alignment20); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment20), 0, 0, 12, 0); + + vbox28 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox28); + gtk_container_add (GTK_CONTAINER (alignment20), vbox28); + + use_sipinfo = gtk_check_button_new_with_mnemonic (_("Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting")); + gtk_widget_show (use_sipinfo); + gtk_box_pack_start (GTK_BOX (vbox28), use_sipinfo, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, use_sipinfo, _("RTP-RFC2833 is the recommended way."), NULL); + + label103 = gtk_label_new (_("Other")); + gtk_widget_show (label103); + gtk_frame_set_label_widget (GTK_FRAME (frame25), label103); + gtk_label_set_use_markup (GTK_LABEL (label103), TRUE); + + network = gtk_label_new (_("Network")); + gtk_widget_show (network); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), network); + gtk_label_set_justify (GTK_LABEL (network), GTK_JUSTIFY_CENTER); + + vbox12 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox12); + gtk_container_add (GTK_CONTAINER (notebook1), vbox12); + + vbox20 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox20); + gtk_box_pack_start (GTK_BOX (vbox12), vbox20, FALSE, TRUE, 0); + + frame17 = gtk_frame_new (NULL); + gtk_widget_show (frame17); + gtk_box_pack_start (GTK_BOX (vbox20), frame17, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame17), 10); + + vbox16 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox16); + gtk_container_add (GTK_CONTAINER (frame17), vbox16); + + table4 = gtk_table_new (6, 2, FALSE); + gtk_widget_show (table4); + gtk_box_pack_start (GTK_BOX (vbox16), table4, TRUE, TRUE, 0); + + label10 = gtk_label_new (_("Playback sound device:")); + gtk_widget_show (label10); + gtk_table_attach (GTK_TABLE (table4), label10, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (GTK_EXPAND), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label10), 0, 0.5); + + combo3 = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (combo3)->popwin), + "GladeParentKey", combo3); + gtk_widget_show (combo3); + gtk_table_attach (GTK_TABLE (table4), combo3, 1, 2, 2, 3, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_combo_set_value_in_list (GTK_COMBO (combo3), TRUE, FALSE); + combo3_items = g_list_append (combo3_items, (gpointer) _("micro")); + combo3_items = g_list_append (combo3_items, (gpointer) _("line")); + combo3_items = g_list_append (combo3_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (combo3), combo3_items); + g_list_free (combo3_items); + + rec_source = GTK_COMBO (combo3)->entry; + gtk_widget_show (rec_source); + gtk_editable_set_editable (GTK_EDITABLE (rec_source), FALSE); + + label106 = gtk_label_new (_("Capture sound device:")); + gtk_widget_show (label106); + gtk_table_attach (GTK_TABLE (table4), label106, 0, 1, 1, 2, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label106), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label106), 0, 0.5); + + play_card = gtk_combo_box_new_text (); + gtk_widget_show (play_card); + gtk_table_attach (GTK_TABLE (table4), play_card, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + capt_card = gtk_combo_box_new_text (); + gtk_widget_show (capt_card); + gtk_table_attach (GTK_TABLE (table4), capt_card, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + hbox20 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox20); + gtk_table_attach (GTK_TABLE (table4), hbox20, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + ringfileentry = gnome_file_entry_new (NULL, _("Ring sound selection")); + gtk_widget_show (ringfileentry); + gtk_box_pack_start (GTK_BOX (hbox20), ringfileentry, TRUE, TRUE, 0); + gnome_file_entry_set_modal (GNOME_FILE_ENTRY (ringfileentry), TRUE); + + combo_entry1 = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (ringfileentry)); + gtk_widget_show (combo_entry1); + + ringpreview = gtk_button_new (); + gtk_widget_show (ringpreview); + gtk_box_pack_start (GTK_BOX (hbox20), ringpreview, FALSE, FALSE, 10); + + alignment8 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment8); + gtk_container_add (GTK_CONTAINER (ringpreview), alignment8); + + hbox21 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox21); + gtk_container_add (GTK_CONTAINER (alignment8), hbox21); + + image15 = gtk_image_new_from_stock ("gnome-stock-volume", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image15); + gtk_box_pack_start (GTK_BOX (hbox21), image15, FALSE, FALSE, 0); + + label64 = gtk_label_new_with_mnemonic (_("Listen")); + gtk_widget_show (label64); + gtk_box_pack_start (GTK_BOX (hbox21), label64, FALSE, FALSE, 0); + + label11 = gtk_label_new (_("Recording source:")); + gtk_widget_show (label11); + gtk_table_attach (GTK_TABLE (table4), label11, 0, 1, 2, 3, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5); + + ringsnddev_label = gtk_label_new (_("Ring sound device")); + gtk_widget_show (ringsnddev_label); + gtk_table_attach (GTK_TABLE (table4), ringsnddev_label, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (ringsnddev_label), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (ringsnddev_label), 0, 0.5); + + label63 = gtk_label_new (_("Ring sound:")); + gtk_widget_show (label63); + gtk_table_attach (GTK_TABLE (table4), label63, 0, 1, 4, 5, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label63), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label63), 0, 0.5); + + ring_card = gtk_combo_box_new_text (); + gtk_widget_show (ring_card); + gtk_table_attach (GTK_TABLE (table4), ring_card, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + echocancelation = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (echocancelation); + gtk_table_attach (GTK_TABLE (table4), echocancelation, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label115 = gtk_label_new (_("Enable echo-canceler (cancels the echo heard by the remote party)")); + gtk_widget_show (label115); + gtk_table_attach (GTK_TABLE (table4), label115, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_label_set_justify (GTK_LABEL (label115), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label115), 0, 0.5); + + label48 = gtk_label_new (_("Sound properties")); + gtk_widget_show (label48); + gtk_frame_set_label_widget (GTK_FRAME (frame17), label48); + + sound = gtk_label_new (_("Sound device")); + gtk_widget_show (sound); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), sound); + gtk_label_set_justify (GTK_LABEL (sound), GTK_JUSTIFY_CENTER); + + vbox7 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox7); + gtk_container_add (GTK_CONTAINER (notebook1), vbox7); + + frame10 = gtk_frame_new (NULL); + gtk_widget_show (frame10); + gtk_box_pack_start (GTK_BOX (vbox7), frame10, FALSE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame10), 10); + + hbox6 = gtk_hbox_new (FALSE, 67); + gtk_widget_show (hbox6); + gtk_container_add (GTK_CONTAINER (frame10), hbox6); + + label13 = gtk_label_new (_("Run sip user agent on port:")); + gtk_widget_show (label13); + gtk_box_pack_start (GTK_BOX (hbox6), label13, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label13), GTK_JUSTIFY_CENTER); + + sip_port_adj = gtk_adjustment_new (5060, 5000, 65535, 1, 10, 10); + sip_port = gtk_spin_button_new (GTK_ADJUSTMENT (sip_port_adj), 4, 0); + gtk_widget_show (sip_port); + gtk_box_pack_start (GTK_BOX (hbox6), sip_port, TRUE, TRUE, 32); + gtk_tooltips_set_tip (tooltips, sip_port, _("It is strongly recommended to use port 5060."), NULL); + + label43 = gtk_label_new (_("SIP port")); + gtk_widget_show (label43); + gtk_frame_set_label_widget (GTK_FRAME (frame10), label43); + + frame11 = gtk_frame_new (NULL); + gtk_widget_show (frame11); + gtk_box_pack_start (GTK_BOX (vbox7), frame11, FALSE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame11), 10); + + vbox27 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox27); + gtk_container_add (GTK_CONTAINER (frame11), vbox27); + + hbox7 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox7); + gtk_box_pack_start (GTK_BOX (vbox27), hbox7, TRUE, TRUE, 0); + + label26 = gtk_label_new (_("Your sip address:")); + gtk_widget_show (label26); + gtk_box_pack_start (GTK_BOX (hbox7), label26, TRUE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label26), GTK_JUSTIFY_CENTER); + + label27 = gtk_label_new (_("sip:")); + gtk_widget_show (label27); + gtk_box_pack_start (GTK_BOX (hbox7), label27, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label27), GTK_JUSTIFY_RIGHT); + + user_name = gtk_entry_new (); + gtk_widget_show (user_name); + gtk_box_pack_start (GTK_BOX (hbox7), user_name, FALSE, FALSE, 0); + + label28 = gtk_label_new (_("@")); + gtk_widget_show (label28); + gtk_box_pack_start (GTK_BOX (hbox7), label28, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label28), GTK_JUSTIFY_CENTER); + + domain_name = gtk_entry_new (); + gtk_widget_show (domain_name); + gtk_box_pack_start (GTK_BOX (hbox7), domain_name, FALSE, TRUE, 0); + + guess_hostname = gtk_check_button_new_with_mnemonic (_("Automatically guess a valid hostname")); + gtk_widget_show (guess_hostname); + gtk_box_pack_start (GTK_BOX (vbox27), guess_hostname, TRUE, TRUE, 0); + + label44 = gtk_label_new (_("Identity")); + gtk_widget_show (label44); + gtk_frame_set_label_widget (GTK_FRAME (frame11), label44); + + frame1 = gtk_frame_new (NULL); + gtk_widget_show (frame1); + gtk_box_pack_start (GTK_BOX (vbox7), frame1, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame1), 10); + + vbox23 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox23); + gtk_container_add (GTK_CONTAINER (frame1), vbox23); + + scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow4); + gtk_box_pack_start (GTK_BOX (vbox23), scrolledwindow4, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_SHADOW_ETCHED_OUT); + + proxy_list = gtk_tree_view_new (); + gtk_widget_show (proxy_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow4), proxy_list); + gtk_widget_set_size_request (proxy_list, -1, 100); + + hbuttonbox6 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox6); + gtk_box_pack_start (GTK_BOX (vbox23), hbuttonbox6, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox6), 5); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox6), GTK_BUTTONBOX_SPREAD); + + addproxy_button = gtk_button_new (); + gtk_widget_show (addproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), addproxy_button); + GTK_WIDGET_SET_FLAGS (addproxy_button, GTK_CAN_DEFAULT); + + alignment12 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment12); + gtk_container_add (GTK_CONTAINER (addproxy_button), alignment12); + + hbox25 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox25); + gtk_container_add (GTK_CONTAINER (alignment12), hbox25); + + image19 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image19); + gtk_box_pack_start (GTK_BOX (hbox25), image19, FALSE, FALSE, 0); + + label77 = gtk_label_new_with_mnemonic (_("Add proxy/registrar")); + gtk_widget_show (label77); + gtk_box_pack_start (GTK_BOX (hbox25), label77, FALSE, FALSE, 0); + + editproxy_button = gtk_button_new (); + gtk_widget_show (editproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), editproxy_button); + GTK_WIDGET_SET_FLAGS (editproxy_button, GTK_CAN_DEFAULT); + + alignment13 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment13); + gtk_container_add (GTK_CONTAINER (editproxy_button), alignment13); + + hbox26 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox26); + gtk_container_add (GTK_CONTAINER (alignment13), hbox26); + + image20 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image20); + gtk_box_pack_start (GTK_BOX (hbox26), image20, FALSE, FALSE, 0); + + label78 = gtk_label_new_with_mnemonic (_("Edit")); + gtk_widget_show (label78); + gtk_box_pack_start (GTK_BOX (hbox26), label78, FALSE, FALSE, 0); + + removeproxy_button = gtk_button_new (); + gtk_widget_show (removeproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), removeproxy_button); + GTK_WIDGET_SET_FLAGS (removeproxy_button, GTK_CAN_DEFAULT); + + alignment14 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment14); + gtk_container_add (GTK_CONTAINER (removeproxy_button), alignment14); + + hbox27 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox27); + gtk_container_add (GTK_CONTAINER (alignment14), hbox27); + + image21 = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image21); + gtk_box_pack_start (GTK_BOX (hbox27), image21, FALSE, FALSE, 0); + + label79 = gtk_label_new_with_mnemonic (_("Remove")); + gtk_widget_show (label79); + gtk_box_pack_start (GTK_BOX (hbox27), label79, FALSE, FALSE, 0); + + label45 = gtk_label_new (_("Remote services")); + gtk_widget_show (label45); + gtk_frame_set_label_widget (GTK_FRAME (frame1), label45); + + frame24 = gtk_frame_new (NULL); + gtk_widget_show (frame24); + gtk_box_pack_start (GTK_BOX (vbox7), frame24, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame24), 10); + + alignment18 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment18); + gtk_container_add (GTK_CONTAINER (frame24), alignment18); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment18), 0, 0, 12, 0); + + clear_auth_info = gtk_button_new (); + gtk_widget_show (clear_auth_info); + gtk_container_add (GTK_CONTAINER (alignment18), clear_auth_info); + + alignment19 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment19); + gtk_container_add (GTK_CONTAINER (clear_auth_info), alignment19); + + hbox34 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox34); + gtk_container_add (GTK_CONTAINER (alignment19), hbox34); + + image27 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image27); + gtk_box_pack_start (GTK_BOX (hbox34), image27, FALSE, FALSE, 0); + + label102 = gtk_label_new_with_mnemonic (_("Clear all stored authentication information (username,password...)")); + gtk_widget_show (label102); + gtk_box_pack_start (GTK_BOX (hbox34), label102, FALSE, FALSE, 0); + + label101 = gtk_label_new (_("Authentication information")); + gtk_widget_show (label101); + gtk_frame_set_label_widget (GTK_FRAME (frame24), label101); + + sip_pref = gtk_label_new (_("SIP")); + gtk_widget_show (sip_pref); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), sip_pref); + gtk_label_set_justify (GTK_LABEL (sip_pref), GTK_JUSTIFY_CENTER); + + vbox13 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox13); + gtk_container_add (GTK_CONTAINER (notebook1), vbox13); + + frame16 = gtk_frame_new (NULL); + gtk_widget_show (frame16); + gtk_box_pack_start (GTK_BOX (vbox13), frame16, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame16), 10); + + hbox9 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox9); + gtk_container_add (GTK_CONTAINER (frame16), hbox9); + + vbox14 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox14); + gtk_box_pack_start (GTK_BOX (hbox9), vbox14, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox14), 9); + + label9 = gtk_label_new (_("List of audio codecs, in order of preference:")); + gtk_widget_show (label9); + gtk_box_pack_start (GTK_BOX (vbox14), label9, FALSE, FALSE, 4); + gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5); + + codec_notebook = gtk_notebook_new (); + gtk_widget_show (codec_notebook); + gtk_box_pack_start (GTK_BOX (vbox14), codec_notebook, TRUE, TRUE, 0); + + scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow2); + gtk_container_add (GTK_CONTAINER (codec_notebook), scrolledwindow2); + GTK_WIDGET_UNSET_FLAGS (scrolledwindow2, GTK_CAN_FOCUS); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_ETCHED_IN); + + au_codec_list = gtk_tree_view_new (); + gtk_widget_show (au_codec_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow2), au_codec_list); + gtk_tree_view_set_reorderable (GTK_TREE_VIEW (au_codec_list), TRUE); + + label116 = gtk_label_new (_("Audio codecs")); + gtk_widget_show (label116); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (codec_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (codec_notebook), 0), label116); + + scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow7); + gtk_container_add (GTK_CONTAINER (codec_notebook), scrolledwindow7); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_SHADOW_IN); + + vid_codec_list = gtk_tree_view_new (); + gtk_widget_show (vid_codec_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow7), vid_codec_list); + + label117 = gtk_label_new (_("Video Codecs")); + gtk_widget_show (label117); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (codec_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (codec_notebook), 1), label117); + + hbuttonbox4 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox4); + gtk_box_pack_start (GTK_BOX (vbox14), hbuttonbox4, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox4), 10); + + aucodec_up = gtk_button_new_from_stock ("gtk-go-up"); + gtk_widget_show (aucodec_up); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_up); + GTK_WIDGET_SET_FLAGS (aucodec_up, GTK_CAN_DEFAULT); + + aucodec_down = gtk_button_new_from_stock ("gtk-go-down"); + gtk_widget_show (aucodec_down); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_down); + GTK_WIDGET_SET_FLAGS (aucodec_down, GTK_CAN_DEFAULT); + + aucodec_enable = gtk_button_new (); + gtk_widget_show (aucodec_enable); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_enable); + GTK_WIDGET_SET_FLAGS (aucodec_enable, GTK_CAN_DEFAULT); + + alignment1 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (aucodec_enable), alignment1); + + hbox11 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox11); + gtk_container_add (GTK_CONTAINER (alignment1), hbox11); + + image4 = gtk_image_new_from_stock ("gtk-apply", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image4); + gtk_box_pack_start (GTK_BOX (hbox11), image4, FALSE, FALSE, 0); + + label50 = gtk_label_new_with_mnemonic (_("Enable")); + gtk_widget_show (label50); + gtk_box_pack_start (GTK_BOX (hbox11), label50, FALSE, FALSE, 0); + + aucodec_disable = gtk_button_new (); + gtk_widget_show (aucodec_disable); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_disable); + GTK_WIDGET_SET_FLAGS (aucodec_disable, GTK_CAN_DEFAULT); + + alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment2); + gtk_container_add (GTK_CONTAINER (aucodec_disable), alignment2); + + hbox12 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox12); + gtk_container_add (GTK_CONTAINER (alignment2), hbox12); + + image5 = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image5); + gtk_box_pack_start (GTK_BOX (hbox12), image5, FALSE, FALSE, 0); + + label51 = gtk_label_new_with_mnemonic (_("Disable")); + gtk_widget_show (label51); + gtk_box_pack_start (GTK_BOX (hbox12), label51, FALSE, FALSE, 0); + + table12 = gtk_table_new (2, 2, TRUE); + gtk_widget_show (table12); + gtk_box_pack_start (GTK_BOX (vbox14), table12, FALSE, TRUE, 0); + + label112 = gtk_label_new (_("Upload bandwidth (kbit/sec):")); + gtk_widget_show (label112); + gtk_table_attach (GTK_TABLE (table12), label112, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label112), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label112), 0, 0.5); + + label111 = gtk_label_new (_("Download bandwidth (kbit/sec):")); + gtk_widget_show (label111); + gtk_table_attach (GTK_TABLE (table12), label111, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label111), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label111), 0, 0.5); + + download_bw_adj = gtk_adjustment_new (0, 0, 100000, 10, 100, 10); + download_bw = gtk_spin_button_new (GTK_ADJUSTMENT (download_bw_adj), 1, 0); + gtk_widget_show (download_bw); + gtk_table_attach (GTK_TABLE (table12), download_bw, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (download_bw), GTK_UPDATE_IF_VALID); + + upload_bw_adj = gtk_adjustment_new (0, 0, 100000, 10, 100, 10); + upload_bw = gtk_spin_button_new (GTK_ADJUSTMENT (upload_bw_adj), 1, 0); + gtk_widget_show (upload_bw); + gtk_table_attach (GTK_TABLE (table12), upload_bw, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + vbox17 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox17); + gtk_box_pack_start (GTK_BOX (hbox9), vbox17, TRUE, FALSE, 0); + + label22 = gtk_label_new (_("Note: Codecs in red are not usable regarding to your connection type to the internet.")); + gtk_widget_show (label22); + gtk_box_pack_start (GTK_BOX (vbox17), label22, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label22), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label22), TRUE); + gtk_misc_set_padding (GTK_MISC (label22), 15, 0); + + frame18 = gtk_frame_new (NULL); + gtk_widget_show (frame18); + gtk_box_pack_start (GTK_BOX (vbox17), frame18, TRUE, TRUE, 5); + gtk_container_set_border_width (GTK_CONTAINER (frame18), 8); + + codec_info = gtk_label_new (_("No information availlable")); + gtk_widget_show (codec_info); + gtk_container_add (GTK_CONTAINER (frame18), codec_info); + gtk_label_set_justify (GTK_LABEL (codec_info), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (codec_info), TRUE); + gtk_misc_set_padding (GTK_MISC (codec_info), 10, 10); + + label47 = gtk_label_new (_("Codec information")); + gtk_widget_show (label47); + gtk_frame_set_label_widget (GTK_FRAME (frame18), label47); + + label46 = gtk_label_new (_("Audio and video codecs")); + gtk_widget_show (label46); + gtk_frame_set_label_widget (GTK_FRAME (frame16), label46); + gtk_misc_set_alignment (GTK_MISC (label46), 0.53, 0.5); + + codecs_pref = gtk_label_new (_("Codecs")); + gtk_widget_show (codecs_pref); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 3), codecs_pref); + gtk_label_set_justify (GTK_LABEL (codecs_pref), GTK_JUSTIFY_CENTER); + + g_signal_connect ((gpointer) prop1, "apply", + G_CALLBACK (on_propertybox1_apply), + NULL); + g_signal_connect ((gpointer) prop1, "close", + G_CALLBACK (on_prop1_close), + NULL); + g_signal_connect ((gpointer) prop1, "help", + G_CALLBACK (on_prop1_help), + NULL); + g_signal_connect ((gpointer) prop1, "close", + G_CALLBACK (on_property_box_closed), + NULL); + g_signal_connect ((gpointer) enable_ipv6, "toggled", + G_CALLBACK (on_enable_ipv6_toggled), + NULL); + g_signal_connect ((gpointer) no_nat, "toggled", + G_CALLBACK (on_no_nat_toggled), + NULL); + g_signal_connect ((gpointer) use_stun, "toggled", + G_CALLBACK (on_use_stun_toggled), + NULL); + g_signal_connect ((gpointer) static_nat, "toggled", + G_CALLBACK (on_static_nat_toggled), + NULL); + g_signal_connect ((gpointer) nat_address, "changed", + G_CALLBACK (on_nat_address_changed), + NULL); + g_signal_connect ((gpointer) stun_server, "changed", + G_CALLBACK (on_stun_server_changed), + NULL); + g_signal_connect ((gpointer) audio_jittcomp, "value_changed", + G_CALLBACK (on_audio_jittcomp_value_changed), + NULL); + g_signal_connect ((gpointer) audioport, "changed", + G_CALLBACK (on_audioport_changed), + NULL); + g_signal_connect ((gpointer) use_sipinfo, "toggled", + G_CALLBACK (on_use_sipinfo_toggled), + NULL); + g_signal_connect ((gpointer) rec_source, "changed", + G_CALLBACK (on_source_changed), + NULL); + g_signal_connect ((gpointer) play_card, "changed", + G_CALLBACK (on_play_card_changed), + NULL); + g_signal_connect ((gpointer) capt_card, "changed", + G_CALLBACK (on_capt_card_changed), + NULL); + g_signal_connect ((gpointer) ringfileentry, "changed", + G_CALLBACK (on_ringfileentry_changed), + NULL); + g_signal_connect ((gpointer) ringpreview, "clicked", + G_CALLBACK (on_ringpreview_clicked), + NULL); + g_signal_connect ((gpointer) ring_card, "changed", + G_CALLBACK (on_ring_card_changed), + NULL); + g_signal_connect ((gpointer) echocancelation, "toggled", + G_CALLBACK (on_echocancelation_toggled), + NULL); + g_signal_connect ((gpointer) sip_port, "changed", + G_CALLBACK (on_sipport_changed), + NULL); + g_signal_connect ((gpointer) user_name, "changed", + G_CALLBACK (on_user_name_changed), + NULL); + g_signal_connect ((gpointer) domain_name, "changed", + G_CALLBACK (on_domain_name_changed), + NULL); + g_signal_connect ((gpointer) guess_hostname, "toggled", + G_CALLBACK (on_guess_hostname_toggled), + NULL); + g_signal_connect ((gpointer) addproxy_button, "clicked", + G_CALLBACK (on_addproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) editproxy_button, "clicked", + G_CALLBACK (on_editproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) removeproxy_button, "clicked", + G_CALLBACK (on_removeproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) clear_auth_info, "clicked", + G_CALLBACK (on_clear_auth_info_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_up, "clicked", + G_CALLBACK (on_aucodec_up_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_down, "clicked", + G_CALLBACK (on_aucodec_down_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_enable, "clicked", + G_CALLBACK (on_aucodec_enable_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_disable, "clicked", + G_CALLBACK (on_aucodec_disable_clicked), + NULL); + g_signal_connect ((gpointer) download_bw, "value_changed", + G_CALLBACK (on_download_bw_value_changed), + NULL); + g_signal_connect ((gpointer) upload_bw, "value_changed", + G_CALLBACK (on_upload_bw_value_changed), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (prop1, prop1, "prop1"); + GLADE_HOOKUP_OBJECT_NO_REF (prop1, notebook1, "notebook1"); + GLADE_HOOKUP_OBJECT (prop1, vbox9, "vbox9"); + GLADE_HOOKUP_OBJECT (prop1, frame26, "frame26"); + GLADE_HOOKUP_OBJECT (prop1, alignment21, "alignment21"); + GLADE_HOOKUP_OBJECT (prop1, vbox29, "vbox29"); + GLADE_HOOKUP_OBJECT (prop1, enable_ipv6, "enable_ipv6"); + GLADE_HOOKUP_OBJECT (prop1, label105, "label105"); + GLADE_HOOKUP_OBJECT (prop1, frame21, "frame21"); + GLADE_HOOKUP_OBJECT (prop1, vbox21, "vbox21"); + GLADE_HOOKUP_OBJECT (prop1, label56, "label56"); + GLADE_HOOKUP_OBJECT (prop1, table13, "table13"); + GLADE_HOOKUP_OBJECT (prop1, no_nat, "no_nat"); + GLADE_HOOKUP_OBJECT (prop1, use_stun, "use_stun"); + GLADE_HOOKUP_OBJECT (prop1, static_nat, "static_nat"); + GLADE_HOOKUP_OBJECT (prop1, nat_address, "nat_address"); + GLADE_HOOKUP_OBJECT (prop1, stun_server, "stun_server"); + GLADE_HOOKUP_OBJECT (prop1, label55, "label55"); + GLADE_HOOKUP_OBJECT (prop1, frame20, "frame20"); + GLADE_HOOKUP_OBJECT (prop1, table6, "table6"); + GLADE_HOOKUP_OBJECT (prop1, audio_jittcomp, "audio_jittcomp"); + GLADE_HOOKUP_OBJECT (prop1, audioport, "audioport"); + GLADE_HOOKUP_OBJECT (prop1, label52, "label52"); + GLADE_HOOKUP_OBJECT (prop1, label53, "label53"); + GLADE_HOOKUP_OBJECT (prop1, label54, "label54"); + GLADE_HOOKUP_OBJECT (prop1, frame25, "frame25"); + GLADE_HOOKUP_OBJECT (prop1, alignment20, "alignment20"); + GLADE_HOOKUP_OBJECT (prop1, vbox28, "vbox28"); + GLADE_HOOKUP_OBJECT (prop1, use_sipinfo, "use_sipinfo"); + GLADE_HOOKUP_OBJECT (prop1, label103, "label103"); + GLADE_HOOKUP_OBJECT (prop1, network, "network"); + GLADE_HOOKUP_OBJECT (prop1, vbox12, "vbox12"); + GLADE_HOOKUP_OBJECT (prop1, vbox20, "vbox20"); + GLADE_HOOKUP_OBJECT (prop1, frame17, "frame17"); + GLADE_HOOKUP_OBJECT (prop1, vbox16, "vbox16"); + GLADE_HOOKUP_OBJECT (prop1, table4, "table4"); + GLADE_HOOKUP_OBJECT (prop1, label10, "label10"); + GLADE_HOOKUP_OBJECT (prop1, combo3, "combo3"); + GLADE_HOOKUP_OBJECT (prop1, rec_source, "rec_source"); + GLADE_HOOKUP_OBJECT (prop1, label106, "label106"); + GLADE_HOOKUP_OBJECT (prop1, play_card, "play_card"); + GLADE_HOOKUP_OBJECT (prop1, capt_card, "capt_card"); + GLADE_HOOKUP_OBJECT (prop1, hbox20, "hbox20"); + GLADE_HOOKUP_OBJECT (prop1, ringfileentry, "ringfileentry"); + GLADE_HOOKUP_OBJECT (prop1, combo_entry1, "combo_entry1"); + GLADE_HOOKUP_OBJECT (prop1, ringpreview, "ringpreview"); + GLADE_HOOKUP_OBJECT (prop1, alignment8, "alignment8"); + GLADE_HOOKUP_OBJECT (prop1, hbox21, "hbox21"); + GLADE_HOOKUP_OBJECT (prop1, image15, "image15"); + GLADE_HOOKUP_OBJECT (prop1, label64, "label64"); + GLADE_HOOKUP_OBJECT (prop1, label11, "label11"); + GLADE_HOOKUP_OBJECT (prop1, ringsnddev_label, "ringsnddev_label"); + GLADE_HOOKUP_OBJECT (prop1, label63, "label63"); + GLADE_HOOKUP_OBJECT (prop1, ring_card, "ring_card"); + GLADE_HOOKUP_OBJECT (prop1, echocancelation, "echocancelation"); + GLADE_HOOKUP_OBJECT (prop1, label115, "label115"); + GLADE_HOOKUP_OBJECT (prop1, label48, "label48"); + GLADE_HOOKUP_OBJECT (prop1, sound, "sound"); + GLADE_HOOKUP_OBJECT (prop1, vbox7, "vbox7"); + GLADE_HOOKUP_OBJECT (prop1, frame10, "frame10"); + GLADE_HOOKUP_OBJECT (prop1, hbox6, "hbox6"); + GLADE_HOOKUP_OBJECT (prop1, label13, "label13"); + GLADE_HOOKUP_OBJECT (prop1, sip_port, "sip_port"); + GLADE_HOOKUP_OBJECT (prop1, label43, "label43"); + GLADE_HOOKUP_OBJECT (prop1, frame11, "frame11"); + GLADE_HOOKUP_OBJECT (prop1, vbox27, "vbox27"); + GLADE_HOOKUP_OBJECT (prop1, hbox7, "hbox7"); + GLADE_HOOKUP_OBJECT (prop1, label26, "label26"); + GLADE_HOOKUP_OBJECT (prop1, label27, "label27"); + GLADE_HOOKUP_OBJECT (prop1, user_name, "user_name"); + GLADE_HOOKUP_OBJECT (prop1, label28, "label28"); + GLADE_HOOKUP_OBJECT (prop1, domain_name, "domain_name"); + GLADE_HOOKUP_OBJECT (prop1, guess_hostname, "guess_hostname"); + GLADE_HOOKUP_OBJECT (prop1, label44, "label44"); + GLADE_HOOKUP_OBJECT (prop1, frame1, "frame1"); + GLADE_HOOKUP_OBJECT (prop1, vbox23, "vbox23"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow4, "scrolledwindow4"); + GLADE_HOOKUP_OBJECT (prop1, proxy_list, "proxy_list"); + GLADE_HOOKUP_OBJECT (prop1, hbuttonbox6, "hbuttonbox6"); + GLADE_HOOKUP_OBJECT (prop1, addproxy_button, "addproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment12, "alignment12"); + GLADE_HOOKUP_OBJECT (prop1, hbox25, "hbox25"); + GLADE_HOOKUP_OBJECT (prop1, image19, "image19"); + GLADE_HOOKUP_OBJECT (prop1, label77, "label77"); + GLADE_HOOKUP_OBJECT (prop1, editproxy_button, "editproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment13, "alignment13"); + GLADE_HOOKUP_OBJECT (prop1, hbox26, "hbox26"); + GLADE_HOOKUP_OBJECT (prop1, image20, "image20"); + GLADE_HOOKUP_OBJECT (prop1, label78, "label78"); + GLADE_HOOKUP_OBJECT (prop1, removeproxy_button, "removeproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment14, "alignment14"); + GLADE_HOOKUP_OBJECT (prop1, hbox27, "hbox27"); + GLADE_HOOKUP_OBJECT (prop1, image21, "image21"); + GLADE_HOOKUP_OBJECT (prop1, label79, "label79"); + GLADE_HOOKUP_OBJECT (prop1, label45, "label45"); + GLADE_HOOKUP_OBJECT (prop1, frame24, "frame24"); + GLADE_HOOKUP_OBJECT (prop1, alignment18, "alignment18"); + GLADE_HOOKUP_OBJECT (prop1, clear_auth_info, "clear_auth_info"); + GLADE_HOOKUP_OBJECT (prop1, alignment19, "alignment19"); + GLADE_HOOKUP_OBJECT (prop1, hbox34, "hbox34"); + GLADE_HOOKUP_OBJECT (prop1, image27, "image27"); + GLADE_HOOKUP_OBJECT (prop1, label102, "label102"); + GLADE_HOOKUP_OBJECT (prop1, label101, "label101"); + GLADE_HOOKUP_OBJECT (prop1, sip_pref, "sip_pref"); + GLADE_HOOKUP_OBJECT (prop1, vbox13, "vbox13"); + GLADE_HOOKUP_OBJECT (prop1, frame16, "frame16"); + GLADE_HOOKUP_OBJECT (prop1, hbox9, "hbox9"); + GLADE_HOOKUP_OBJECT (prop1, vbox14, "vbox14"); + GLADE_HOOKUP_OBJECT (prop1, label9, "label9"); + GLADE_HOOKUP_OBJECT (prop1, codec_notebook, "codec_notebook"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow2, "scrolledwindow2"); + GLADE_HOOKUP_OBJECT (prop1, au_codec_list, "au_codec_list"); + GLADE_HOOKUP_OBJECT (prop1, label116, "label116"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow7, "scrolledwindow7"); + GLADE_HOOKUP_OBJECT (prop1, vid_codec_list, "vid_codec_list"); + GLADE_HOOKUP_OBJECT (prop1, label117, "label117"); + GLADE_HOOKUP_OBJECT (prop1, hbuttonbox4, "hbuttonbox4"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_up, "aucodec_up"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_down, "aucodec_down"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_enable, "aucodec_enable"); + GLADE_HOOKUP_OBJECT (prop1, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (prop1, hbox11, "hbox11"); + GLADE_HOOKUP_OBJECT (prop1, image4, "image4"); + GLADE_HOOKUP_OBJECT (prop1, label50, "label50"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_disable, "aucodec_disable"); + GLADE_HOOKUP_OBJECT (prop1, alignment2, "alignment2"); + GLADE_HOOKUP_OBJECT (prop1, hbox12, "hbox12"); + GLADE_HOOKUP_OBJECT (prop1, image5, "image5"); + GLADE_HOOKUP_OBJECT (prop1, label51, "label51"); + GLADE_HOOKUP_OBJECT (prop1, table12, "table12"); + GLADE_HOOKUP_OBJECT (prop1, label112, "label112"); + GLADE_HOOKUP_OBJECT (prop1, label111, "label111"); + GLADE_HOOKUP_OBJECT (prop1, download_bw, "download_bw"); + GLADE_HOOKUP_OBJECT (prop1, upload_bw, "upload_bw"); + GLADE_HOOKUP_OBJECT (prop1, vbox17, "vbox17"); + GLADE_HOOKUP_OBJECT (prop1, label22, "label22"); + GLADE_HOOKUP_OBJECT (prop1, frame18, "frame18"); + GLADE_HOOKUP_OBJECT (prop1, codec_info, "codec_info"); + GLADE_HOOKUP_OBJECT (prop1, label47, "label47"); + GLADE_HOOKUP_OBJECT (prop1, label46, "label46"); + GLADE_HOOKUP_OBJECT (prop1, codecs_pref, "codecs_pref"); + GLADE_HOOKUP_OBJECT_NO_REF (prop1, tooltips, "tooltips"); + + return prop1; +} + +GtkWidget* +create_address_book (void) +{ + GtkWidget *address_book; + GdkPixbuf *address_book_icon_pixbuf; + GtkWidget *dialog_vbox7; + GtkWidget *vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *viewport1; + GtkWidget *address_list; + GtkWidget *dialog_action_area7; + GtkWidget *hbuttonbox1; + GtkWidget *add_address; + GtkWidget *remove_address; + GtkWidget *modify_address; + GtkWidget *alignment15; + GtkWidget *hbox29; + GtkWidget *image22; + GtkWidget *label93; + GtkWidget *close_addbook; + GtkWidget *select_address; + GtkWidget *alignment7; + GtkWidget *hbox19; + GtkWidget *image14; + GtkWidget *label62; + + address_book = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (address_book), _("Address Book")); + gtk_window_set_default_size (GTK_WINDOW (address_book), -1, 305); + address_book_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (address_book_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (address_book), address_book_icon_pixbuf); + gdk_pixbuf_unref (address_book_icon_pixbuf); + } + + dialog_vbox7 = GTK_DIALOG (address_book)->vbox; + gtk_widget_show (dialog_vbox7); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_box_pack_start (GTK_BOX (dialog_vbox7), vbox1, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 12); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); + GTK_WIDGET_UNSET_FLAGS (scrolledwindow1, GTK_CAN_FOCUS); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN); + + viewport1 = gtk_viewport_new (NULL, NULL); + gtk_widget_show (viewport1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1); + + address_list = gtk_tree_view_new (); + gtk_widget_show (address_list); + gtk_container_add (GTK_CONTAINER (viewport1), address_list); + + dialog_action_area7 = GTK_DIALOG (address_book)->action_area; + gtk_widget_show (dialog_action_area7); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area7), GTK_BUTTONBOX_SPREAD); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox1); + gtk_container_add (GTK_CONTAINER (dialog_action_area7), hbuttonbox1); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 11); + + add_address = gtk_button_new_from_stock ("gtk-add"); + gtk_widget_show (add_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), add_address); + GTK_WIDGET_SET_FLAGS (add_address, GTK_CAN_DEFAULT); + gtk_button_set_relief (GTK_BUTTON (add_address), GTK_RELIEF_HALF); + + remove_address = gtk_button_new_from_stock ("gtk-delete"); + gtk_widget_show (remove_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), remove_address); + GTK_WIDGET_SET_FLAGS (remove_address, GTK_CAN_DEFAULT); + gtk_button_set_relief (GTK_BUTTON (remove_address), GTK_RELIEF_HALF); + + modify_address = gtk_button_new (); + gtk_widget_show (modify_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), modify_address); + GTK_WIDGET_SET_FLAGS (modify_address, GTK_CAN_DEFAULT); + + alignment15 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment15); + gtk_container_add (GTK_CONTAINER (modify_address), alignment15); + + hbox29 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox29); + gtk_container_add (GTK_CONTAINER (alignment15), hbox29); + + image22 = gtk_image_new_from_stock ("gtk-justify-center", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image22); + gtk_box_pack_start (GTK_BOX (hbox29), image22, FALSE, FALSE, 0); + + label93 = gtk_label_new_with_mnemonic (_("Edit")); + gtk_widget_show (label93); + gtk_box_pack_start (GTK_BOX (hbox29), label93, FALSE, FALSE, 0); + + close_addbook = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (close_addbook); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), close_addbook); + GTK_WIDGET_SET_FLAGS (close_addbook, GTK_CAN_DEFAULT); + + select_address = gtk_button_new (); + gtk_widget_show (select_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), select_address); + GTK_WIDGET_SET_FLAGS (select_address, GTK_CAN_DEFAULT); + + alignment7 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment7); + gtk_container_add (GTK_CONTAINER (select_address), alignment7); + + hbox19 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox19); + gtk_container_add (GTK_CONTAINER (alignment7), hbox19); + + image14 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image14); + gtk_box_pack_start (GTK_BOX (hbox19), image14, FALSE, FALSE, 0); + + label62 = gtk_label_new_with_mnemonic (_("Select")); + gtk_widget_show (label62); + gtk_box_pack_start (GTK_BOX (hbox19), label62, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) add_address, "clicked", + G_CALLBACK (on_add_address_clicked), + NULL); + g_signal_connect ((gpointer) remove_address, "clicked", + G_CALLBACK (on_remove_address_clicked), + NULL); + g_signal_connect ((gpointer) modify_address, "clicked", + G_CALLBACK (on_modify_address_clicked), + NULL); + g_signal_connect ((gpointer) close_addbook, "clicked", + G_CALLBACK (address_book_close), + NULL); + g_signal_connect ((gpointer) select_address, "clicked", + G_CALLBACK (on_select_address_clicked), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (address_book, address_book, "address_book"); + GLADE_HOOKUP_OBJECT_NO_REF (address_book, dialog_vbox7, "dialog_vbox7"); + GLADE_HOOKUP_OBJECT (address_book, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (address_book, scrolledwindow1, "scrolledwindow1"); + GLADE_HOOKUP_OBJECT (address_book, viewport1, "viewport1"); + GLADE_HOOKUP_OBJECT (address_book, address_list, "address_list"); + GLADE_HOOKUP_OBJECT_NO_REF (address_book, dialog_action_area7, "dialog_action_area7"); + GLADE_HOOKUP_OBJECT (address_book, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (address_book, add_address, "add_address"); + GLADE_HOOKUP_OBJECT (address_book, remove_address, "remove_address"); + GLADE_HOOKUP_OBJECT (address_book, modify_address, "modify_address"); + GLADE_HOOKUP_OBJECT (address_book, alignment15, "alignment15"); + GLADE_HOOKUP_OBJECT (address_book, hbox29, "hbox29"); + GLADE_HOOKUP_OBJECT (address_book, image22, "image22"); + GLADE_HOOKUP_OBJECT (address_book, label93, "label93"); + GLADE_HOOKUP_OBJECT (address_book, close_addbook, "close_addbook"); + GLADE_HOOKUP_OBJECT (address_book, select_address, "select_address"); + GLADE_HOOKUP_OBJECT (address_book, alignment7, "alignment7"); + GLADE_HOOKUP_OBJECT (address_book, hbox19, "hbox19"); + GLADE_HOOKUP_OBJECT (address_book, image14, "image14"); + GLADE_HOOKUP_OBJECT (address_book, label62, "label62"); + + return address_book; +} + +GtkWidget* +create_altressource (void) +{ + GtkWidget *altressource; + GdkPixbuf *altressource_icon_pixbuf; + GtkWidget *dialog_vbox10; + GtkWidget *vbox19; + GtkWidget *label49; + GtkWidget *alt_href; + GtkWidget *dialog_action_area10; + GtkWidget *closebutton1; + + altressource = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (altressource), _("Information")); + gtk_window_set_resizable (GTK_WINDOW (altressource), FALSE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (altressource), TRUE); + altressource_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (altressource_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (altressource), altressource_icon_pixbuf); + gdk_pixbuf_unref (altressource_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (altressource), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox10 = GTK_DIALOG (altressource)->vbox; + gtk_widget_show (dialog_vbox10); + + vbox19 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox19); + gtk_box_pack_start (GTK_BOX (dialog_vbox10), vbox19, TRUE, TRUE, 0); + + label49 = gtk_label_new (_("User is not reachable at the moment but he invites you to contact him using the following alternate ressource:")); + gtk_widget_show (label49); + gtk_box_pack_start (GTK_BOX (vbox19), label49, TRUE, TRUE, 10); + gtk_label_set_justify (GTK_LABEL (label49), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label49), TRUE); + gtk_misc_set_padding (GTK_MISC (label49), 25, 5); + + alt_href = gtk_button_new_with_mnemonic (_("None.")); + gtk_widget_show (alt_href); + gtk_box_pack_start (GTK_BOX (vbox19), alt_href, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (alt_href), 12); + gtk_button_set_relief (GTK_BUTTON (alt_href), GTK_RELIEF_NONE); + + dialog_action_area10 = GTK_DIALOG (altressource)->action_area; + gtk_widget_show (dialog_action_area10); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area10), GTK_BUTTONBOX_END); + + closebutton1 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (closebutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (altressource), closebutton1, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT); + + g_signal_connect_swapped ((gpointer) alt_href, "clicked", + G_CALLBACK (on_alt_href_clicked), + GTK_OBJECT (altressource)); + g_signal_connect ((gpointer) alt_href, "realize", + G_CALLBACK (on_alt_href_realize), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (altressource, altressource, "altressource"); + GLADE_HOOKUP_OBJECT_NO_REF (altressource, dialog_vbox10, "dialog_vbox10"); + GLADE_HOOKUP_OBJECT (altressource, vbox19, "vbox19"); + GLADE_HOOKUP_OBJECT (altressource, label49, "label49"); + GLADE_HOOKUP_OBJECT (altressource, alt_href, "alt_href"); + GLADE_HOOKUP_OBJECT_NO_REF (altressource, dialog_action_area10, "dialog_action_area10"); + GLADE_HOOKUP_OBJECT (altressource, closebutton1, "closebutton1"); + + return altressource; +} + +GtkWidget* +create_proxy_config_box (void) +{ + GtkWidget *proxy_config_box; + GdkPixbuf *proxy_config_box_icon_pixbuf; + GtkWidget *dialog_vbox12; + GtkWidget *frame22; + GtkWidget *table8; + GtkWidget *reg_sendregister; + GtkWidget *label82; + GtkWidget *reg_route; + GtkWidget *reg_proxy; + GtkWidget *label83; + GtkWidget *label84; + GtkWidget *reg_identity; + GtkWidget *label85; + GtkObject *reg_expires_adj; + GtkWidget *reg_expires; + GtkWidget *label81; + GtkWidget *label104; + GtkWidget *publish; + GtkWidget *label86; + GtkWidget *dialog_action_area12; + GtkWidget *helpbutton1; + GtkWidget *okbutton2; + + proxy_config_box = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (proxy_config_box), _("Proxy/Registrar configuration box")); + gtk_window_set_modal (GTK_WINDOW (proxy_config_box), TRUE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (proxy_config_box), TRUE); + proxy_config_box_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (proxy_config_box_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (proxy_config_box), proxy_config_box_icon_pixbuf); + gdk_pixbuf_unref (proxy_config_box_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (proxy_config_box), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox12 = GTK_DIALOG (proxy_config_box)->vbox; + gtk_widget_show (dialog_vbox12); + + frame22 = gtk_frame_new (NULL); + gtk_widget_show (frame22); + gtk_box_pack_start (GTK_BOX (dialog_vbox12), frame22, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame22), 8); + + table8 = gtk_table_new (7, 2, FALSE); + gtk_widget_show (table8); + gtk_container_add (GTK_CONTAINER (frame22), table8); + + reg_sendregister = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (reg_sendregister); + gtk_table_attach (GTK_TABLE (table8), reg_sendregister, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (reg_sendregister), TRUE); + + label82 = gtk_label_new (_("Route (optional):")); + gtk_widget_show (label82); + gtk_table_attach (GTK_TABLE (table8), label82, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label82), 0, 0.5); + + reg_route = gtk_entry_new (); + gtk_widget_show (reg_route); + gtk_table_attach (GTK_TABLE (table8), reg_route, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_route), 256); + + reg_proxy = gtk_entry_new (); + gtk_widget_show (reg_proxy); + gtk_table_attach (GTK_TABLE (table8), reg_proxy, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_proxy), 250); + gtk_entry_set_text (GTK_ENTRY (reg_proxy), _("sip:")); + + label83 = gtk_label_new (_("SIP Proxy:")); + gtk_widget_show (label83); + gtk_table_attach (GTK_TABLE (table8), label83, 0, 1, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label83), 0, 0.5); + + label84 = gtk_label_new (_("SIP Identity:")); + gtk_widget_show (label84); + gtk_table_attach (GTK_TABLE (table8), label84, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label84), 0, 0.5); + + reg_identity = gtk_entry_new (); + gtk_widget_show (reg_identity); + gtk_table_attach (GTK_TABLE (table8), reg_identity, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_identity), 256); + gtk_entry_set_text (GTK_ENTRY (reg_identity), _("sip:")); + + label85 = gtk_label_new (_("Registration Period:")); + gtk_widget_show (label85); + gtk_table_attach (GTK_TABLE (table8), label85, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label85), 0, 0.5); + + reg_expires_adj = gtk_adjustment_new (900, 120, 72000, 1, 10, 10); + reg_expires = gtk_spin_button_new (GTK_ADJUSTMENT (reg_expires_adj), 1, 0); + gtk_widget_show (reg_expires); + gtk_table_attach (GTK_TABLE (table8), reg_expires, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (reg_expires), TRUE); + + label81 = gtk_label_new (_("Send registration:")); + gtk_widget_show (label81); + gtk_table_attach (GTK_TABLE (table8), label81, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label81), 0, 0.5); + + label104 = gtk_label_new (_("Publish presence information:")); + gtk_widget_show (label104); + gtk_table_attach (GTK_TABLE (table8), label104, 0, 1, 6, 7, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label104), 0, 0.5); + + publish = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (publish); + gtk_table_attach (GTK_TABLE (table8), publish, 1, 2, 6, 7, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label86 = gtk_label_new (_("Proxy/Registrar configuration box")); + gtk_widget_show (label86); + gtk_frame_set_label_widget (GTK_FRAME (frame22), label86); + + dialog_action_area12 = GTK_DIALOG (proxy_config_box)->action_area; + gtk_widget_show (dialog_action_area12); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area12), GTK_BUTTONBOX_END); + + helpbutton1 = gtk_button_new_from_stock ("gtk-help"); + gtk_widget_show (helpbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (proxy_config_box), helpbutton1, GTK_RESPONSE_HELP); + GTK_WIDGET_SET_FLAGS (helpbutton1, GTK_CAN_DEFAULT); + + okbutton2 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (proxy_config_box), okbutton2, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) proxy_config_box, "response", + G_CALLBACK (on_proxy_config_box_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, proxy_config_box, "proxy_config_box"); + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, dialog_vbox12, "dialog_vbox12"); + GLADE_HOOKUP_OBJECT (proxy_config_box, frame22, "frame22"); + GLADE_HOOKUP_OBJECT (proxy_config_box, table8, "table8"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_sendregister, "reg_sendregister"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label82, "label82"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_route, "reg_route"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_proxy, "reg_proxy"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label83, "label83"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label84, "label84"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_identity, "reg_identity"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label85, "label85"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_expires, "reg_expires"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label81, "label81"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label104, "label104"); + GLADE_HOOKUP_OBJECT (proxy_config_box, publish, "publish"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label86, "label86"); + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, dialog_action_area12, "dialog_action_area12"); + GLADE_HOOKUP_OBJECT (proxy_config_box, helpbutton1, "helpbutton1"); + GLADE_HOOKUP_OBJECT (proxy_config_box, okbutton2, "okbutton2"); + + gtk_widget_grab_focus (proxy_config_box); + return proxy_config_box; +} + +GtkWidget* +create_contact_box (void) +{ + GtkWidget *contact_box; + GdkPixbuf *contact_box_icon_pixbuf; + GtkWidget *dialog_vbox13; + GtkWidget *frame23; + GtkWidget *vbox25; + GtkWidget *table10; + GtkWidget *sipaddr; + GtkWidget *name; + GtkWidget *label89; + GtkWidget *label90; + GtkWidget *label91; + GtkWidget *label92; + GtkWidget *send_subscribe; + GtkWidget *label88; + GtkWidget *dialog_action_area13; + GtkWidget *helpbutton2; + GtkWidget *cancelbutton2; + GtkWidget *okbutton3; + + contact_box = gtk_dialog_new (); + GTK_WIDGET_SET_FLAGS (contact_box, GTK_CAN_FOCUS); + gtk_window_set_title (GTK_WINDOW (contact_box), _("Edit contact information")); + gtk_window_set_destroy_with_parent (GTK_WINDOW (contact_box), TRUE); + contact_box_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (contact_box_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (contact_box), contact_box_icon_pixbuf); + gdk_pixbuf_unref (contact_box_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (contact_box), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox13 = GTK_DIALOG (contact_box)->vbox; + gtk_widget_show (dialog_vbox13); + + frame23 = gtk_frame_new (NULL); + gtk_widget_show (frame23); + gtk_box_pack_start (GTK_BOX (dialog_vbox13), frame23, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame23), 6); + + vbox25 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox25); + gtk_container_add (GTK_CONTAINER (frame23), vbox25); + + table10 = gtk_table_new (4, 2, TRUE); + gtk_widget_show (table10); + gtk_box_pack_start (GTK_BOX (vbox25), table10, TRUE, TRUE, 0); + + sipaddr = gtk_entry_new (); + gtk_widget_show (sipaddr); + gtk_table_attach (GTK_TABLE (table10), sipaddr, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_text (GTK_ENTRY (sipaddr), _("sip:")); + + name = gtk_entry_new (); + gtk_widget_show (name); + gtk_table_attach (GTK_TABLE (table10), name, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label89 = gtk_label_new (_("Name:")); + gtk_widget_show (label89); + gtk_table_attach (GTK_TABLE (table10), label89, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label89), 0, 0.5); + + label90 = gtk_label_new (_("Sip address:")); + gtk_widget_show (label90); + gtk_table_attach (GTK_TABLE (table10), label90, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label90), 0, 0.5); + + label91 = gtk_label_new (_("Proxy to use:")); + gtk_widget_show (label91); + gtk_table_attach (GTK_TABLE (table10), label91, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label91), 0, 0.5); + + label92 = gtk_label_new (_("Subscribe policy:")); + gtk_widget_show (label92); + gtk_table_attach (GTK_TABLE (table10), label92, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label92), 0, 0.5); + + send_subscribe = gtk_check_button_new_with_mnemonic (_("Send subscription (see person's online status)")); + gtk_widget_show (send_subscribe); + gtk_box_pack_start (GTK_BOX (vbox25), send_subscribe, TRUE, TRUE, 0); + + label88 = gtk_label_new (_("Contact information")); + gtk_widget_show (label88); + gtk_frame_set_label_widget (GTK_FRAME (frame23), label88); + + dialog_action_area13 = GTK_DIALOG (contact_box)->action_area; + gtk_widget_show (dialog_action_area13); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area13), GTK_BUTTONBOX_END); + + helpbutton2 = gtk_button_new_from_stock ("gtk-help"); + gtk_widget_show (helpbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), helpbutton2, GTK_RESPONSE_HELP); + GTK_WIDGET_SET_FLAGS (helpbutton2, GTK_CAN_DEFAULT); + + cancelbutton2 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), cancelbutton2, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT); + + okbutton3 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton3); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), okbutton3, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) contact_box, "response", + G_CALLBACK (on_contact_box_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, contact_box, "contact_box"); + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, dialog_vbox13, "dialog_vbox13"); + GLADE_HOOKUP_OBJECT (contact_box, frame23, "frame23"); + GLADE_HOOKUP_OBJECT (contact_box, vbox25, "vbox25"); + GLADE_HOOKUP_OBJECT (contact_box, table10, "table10"); + GLADE_HOOKUP_OBJECT (contact_box, sipaddr, "sipaddr"); + GLADE_HOOKUP_OBJECT (contact_box, name, "name"); + GLADE_HOOKUP_OBJECT (contact_box, label89, "label89"); + GLADE_HOOKUP_OBJECT (contact_box, label90, "label90"); + GLADE_HOOKUP_OBJECT (contact_box, label91, "label91"); + GLADE_HOOKUP_OBJECT (contact_box, label92, "label92"); + GLADE_HOOKUP_OBJECT (contact_box, send_subscribe, "send_subscribe"); + GLADE_HOOKUP_OBJECT (contact_box, label88, "label88"); + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, dialog_action_area13, "dialog_action_area13"); + GLADE_HOOKUP_OBJECT (contact_box, helpbutton2, "helpbutton2"); + GLADE_HOOKUP_OBJECT (contact_box, cancelbutton2, "cancelbutton2"); + GLADE_HOOKUP_OBJECT (contact_box, okbutton3, "okbutton3"); + + return contact_box; +} + +GtkWidget* +create_inc_subscr_dialog (void) +{ + GtkWidget *inc_subscr_dialog; + GdkPixbuf *inc_subscr_dialog_icon_pixbuf; + GtkWidget *dialog_vbox14; + GtkWidget *hbox32; + GtkWidget *image25; + GtkWidget *subscr_label; + GtkWidget *dialog_action_area14; + GtkWidget *button15; + GtkWidget *alignment17; + GtkWidget *hbox31; + GtkWidget *image24; + GtkWidget *label95; + GtkWidget *button16; + GtkWidget *alignment16; + GtkWidget *hbox30; + GtkWidget *image23; + GtkWidget *label94; + + inc_subscr_dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (inc_subscr_dialog), _("New incoming subscription")); + inc_subscr_dialog_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (inc_subscr_dialog_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (inc_subscr_dialog), inc_subscr_dialog_icon_pixbuf); + gdk_pixbuf_unref (inc_subscr_dialog_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (inc_subscr_dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox14 = GTK_DIALOG (inc_subscr_dialog)->vbox; + gtk_widget_show (dialog_vbox14); + + hbox32 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox32); + gtk_box_pack_start (GTK_BOX (dialog_vbox14), hbox32, TRUE, TRUE, 0); + + image25 = gtk_image_new_from_stock ("gtk-dialog-warning", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image25); + gtk_box_pack_start (GTK_BOX (hbox32), image25, FALSE, TRUE, 0); + + subscr_label = gtk_label_new (_("You have received a new subscription...")); + gtk_widget_show (subscr_label); + gtk_box_pack_start (GTK_BOX (hbox32), subscr_label, TRUE, TRUE, 0); + gtk_label_set_line_wrap (GTK_LABEL (subscr_label), TRUE); + gtk_misc_set_padding (GTK_MISC (subscr_label), 14, 9); + + dialog_action_area14 = GTK_DIALOG (inc_subscr_dialog)->action_area; + gtk_widget_show (dialog_action_area14); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area14), GTK_BUTTONBOX_SPREAD); + + button15 = gtk_button_new (); + gtk_widget_show (button15); + gtk_dialog_add_action_widget (GTK_DIALOG (inc_subscr_dialog), button15, GTK_RESPONSE_REJECT); + GTK_WIDGET_SET_FLAGS (button15, GTK_CAN_DEFAULT); + + alignment17 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment17); + gtk_container_add (GTK_CONTAINER (button15), alignment17); + + hbox31 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox31); + gtk_container_add (GTK_CONTAINER (alignment17), hbox31); + + image24 = gtk_image_new_from_stock ("gtk-stop", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image24); + gtk_box_pack_start (GTK_BOX (hbox31), image24, FALSE, FALSE, 0); + + label95 = gtk_label_new_with_mnemonic (_("Refuse")); + gtk_widget_show (label95); + gtk_box_pack_start (GTK_BOX (hbox31), label95, FALSE, FALSE, 0); + + button16 = gtk_button_new (); + gtk_widget_show (button16); + gtk_dialog_add_action_widget (GTK_DIALOG (inc_subscr_dialog), button16, GTK_RESPONSE_ACCEPT); + GTK_WIDGET_SET_FLAGS (button16, GTK_CAN_DEFAULT); + + alignment16 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment16); + gtk_container_add (GTK_CONTAINER (button16), alignment16); + + hbox30 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox30); + gtk_container_add (GTK_CONTAINER (alignment16), hbox30); + + image23 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image23); + gtk_box_pack_start (GTK_BOX (hbox30), image23, FALSE, FALSE, 0); + + label94 = gtk_label_new_with_mnemonic (_("Accept")); + gtk_widget_show (label94); + gtk_box_pack_start (GTK_BOX (hbox30), label94, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) inc_subscr_dialog, "response", + G_CALLBACK (on_inc_subscr_dialog_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, inc_subscr_dialog, "inc_subscr_dialog"); + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, dialog_vbox14, "dialog_vbox14"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox32, "hbox32"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image25, "image25"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, subscr_label, "subscr_label"); + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, dialog_action_area14, "dialog_action_area14"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, button15, "button15"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, alignment17, "alignment17"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox31, "hbox31"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image24, "image24"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, label95, "label95"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, button16, "button16"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, alignment16, "alignment16"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox30, "hbox30"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image23, "image23"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, label94, "label94"); + + return inc_subscr_dialog; +} + +GtkWidget* +create_authentication_dialog (void) +{ + GtkWidget *authentication_dialog; + GdkPixbuf *authentication_dialog_icon_pixbuf; + GtkWidget *dialog_vbox15; + GtkWidget *vbox26; + GtkWidget *hbox33; + GtkWidget *image26; + GtkWidget *question; + GtkWidget *table11; + GtkWidget *realm; + GtkWidget *username; + GtkWidget *passwd; + GtkWidget *userid; + GtkWidget *label100; + GtkWidget *label99; + GtkWidget *label98; + GtkWidget *label97; + GtkWidget *dialog_action_area15; + GtkWidget *cancelbutton3; + GtkWidget *okbutton4; + + authentication_dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (authentication_dialog), _("Authentication requested")); + gtk_window_set_destroy_with_parent (GTK_WINDOW (authentication_dialog), TRUE); + authentication_dialog_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (authentication_dialog_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (authentication_dialog), authentication_dialog_icon_pixbuf); + gdk_pixbuf_unref (authentication_dialog_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (authentication_dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox15 = GTK_DIALOG (authentication_dialog)->vbox; + gtk_widget_show (dialog_vbox15); + + vbox26 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox26); + gtk_box_pack_start (GTK_BOX (dialog_vbox15), vbox26, TRUE, TRUE, 0); + + hbox33 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox33); + gtk_box_pack_start (GTK_BOX (vbox26), hbox33, FALSE, FALSE, 0); + + image26 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image26); + gtk_box_pack_start (GTK_BOX (hbox33), image26, TRUE, TRUE, 0); + gtk_misc_set_padding (GTK_MISC (image26), 16, 0); + + question = gtk_label_new (_("Authentication required for realm")); + gtk_widget_show (question); + gtk_box_pack_start (GTK_BOX (hbox33), question, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (question), GTK_JUSTIFY_CENTER); + gtk_misc_set_padding (GTK_MISC (question), 29, 14); + + table11 = gtk_table_new (5, 2, FALSE); + gtk_widget_show (table11); + gtk_box_pack_start (GTK_BOX (vbox26), table11, TRUE, TRUE, 0); + + realm = gtk_entry_new (); + gtk_widget_show (realm); + gtk_table_attach (GTK_TABLE (table11), realm, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable (GTK_EDITABLE (realm), FALSE); + + username = gtk_entry_new (); + gtk_widget_show (username); + gtk_table_attach (GTK_TABLE (table11), username, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + passwd = gtk_entry_new (); + gtk_widget_show (passwd); + gtk_table_attach (GTK_TABLE (table11), passwd, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_visibility (GTK_ENTRY (passwd), FALSE); + + userid = gtk_entry_new (); + gtk_widget_show (userid); + gtk_table_attach (GTK_TABLE (table11), userid, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label100 = gtk_label_new (_("userid:")); + gtk_widget_show (label100); + gtk_table_attach (GTK_TABLE (table11), label100, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label100), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label100), 0, 0.5); + + label99 = gtk_label_new (_("password:")); + gtk_widget_show (label99); + gtk_table_attach (GTK_TABLE (table11), label99, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label99), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label99), 0, 0.5); + + label98 = gtk_label_new (_("username:")); + gtk_widget_show (label98); + gtk_table_attach (GTK_TABLE (table11), label98, 0, 1, 1, 2, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label98), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label98), 0, 0.5); + + label97 = gtk_label_new (_("realm:")); + gtk_widget_show (label97); + gtk_table_attach (GTK_TABLE (table11), label97, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label97), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label97), 0, 0.5); + + dialog_action_area15 = GTK_DIALOG (authentication_dialog)->action_area; + gtk_widget_show (dialog_action_area15); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area15), GTK_BUTTONBOX_END); + + cancelbutton3 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton3); + gtk_dialog_add_action_widget (GTK_DIALOG (authentication_dialog), cancelbutton3, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton3, GTK_CAN_DEFAULT); + + okbutton4 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton4); + gtk_dialog_add_action_widget (GTK_DIALOG (authentication_dialog), okbutton4, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton4, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) authentication_dialog, "response", + G_CALLBACK (on_authentication_dialog_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, authentication_dialog, "authentication_dialog"); + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, dialog_vbox15, "dialog_vbox15"); + GLADE_HOOKUP_OBJECT (authentication_dialog, vbox26, "vbox26"); + GLADE_HOOKUP_OBJECT (authentication_dialog, hbox33, "hbox33"); + GLADE_HOOKUP_OBJECT (authentication_dialog, image26, "image26"); + GLADE_HOOKUP_OBJECT (authentication_dialog, question, "question"); + GLADE_HOOKUP_OBJECT (authentication_dialog, table11, "table11"); + GLADE_HOOKUP_OBJECT (authentication_dialog, realm, "realm"); + GLADE_HOOKUP_OBJECT (authentication_dialog, username, "username"); + GLADE_HOOKUP_OBJECT (authentication_dialog, passwd, "passwd"); + GLADE_HOOKUP_OBJECT (authentication_dialog, userid, "userid"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label100, "label100"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label99, "label99"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label98, "label98"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label97, "label97"); + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, dialog_action_area15, "dialog_action_area15"); + GLADE_HOOKUP_OBJECT (authentication_dialog, cancelbutton3, "cancelbutton3"); + GLADE_HOOKUP_OBJECT (authentication_dialog, okbutton4, "okbutton4"); + + return authentication_dialog; +} + +GtkWidget* +create_call_logs (void) +{ + GtkWidget *call_logs; + GdkPixbuf *call_logs_icon_pixbuf; + GtkWidget *dialog_vbox16; + GtkWidget *scrolledwindow5; + GtkWidget *logview; + GtkWidget *dialog_action_area16; + GtkWidget *closebutton2; + + call_logs = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (call_logs), _("Linphone - Call history")); + gtk_window_set_default_size (GTK_WINDOW (call_logs), 240, 240); + gtk_window_set_destroy_with_parent (GTK_WINDOW (call_logs), TRUE); + call_logs_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (call_logs_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (call_logs), call_logs_icon_pixbuf); + gdk_pixbuf_unref (call_logs_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (call_logs), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox16 = GTK_DIALOG (call_logs)->vbox; + gtk_widget_show (dialog_vbox16); + + scrolledwindow5 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow5); + gtk_box_pack_start (GTK_BOX (dialog_vbox16), scrolledwindow5, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_SHADOW_IN); + + logview = gtk_text_view_new (); + gtk_widget_show (logview); + gtk_container_add (GTK_CONTAINER (scrolledwindow5), logview); + gtk_text_view_set_editable (GTK_TEXT_VIEW (logview), FALSE); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (logview), FALSE); + + dialog_action_area16 = GTK_DIALOG (call_logs)->action_area; + gtk_widget_show (dialog_action_area16); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area16), GTK_BUTTONBOX_END); + + closebutton2 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (closebutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (call_logs), closebutton2, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (closebutton2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) call_logs, "response", + G_CALLBACK (on_call_logs_response), + NULL); + g_signal_connect ((gpointer) call_logs, "destroy", + G_CALLBACK (on_call_logs_destroy), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, call_logs, "call_logs"); + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, dialog_vbox16, "dialog_vbox16"); + GLADE_HOOKUP_OBJECT (call_logs, scrolledwindow5, "scrolledwindow5"); + GLADE_HOOKUP_OBJECT (call_logs, logview, "logview"); + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, dialog_action_area16, "dialog_action_area16"); + GLADE_HOOKUP_OBJECT (call_logs, closebutton2, "closebutton2"); + + return call_logs; +} + +GtkWidget* +create_chatroom (void) +{ + GtkWidget *chatroom; + GdkPixbuf *chatroom_icon_pixbuf; + GtkWidget *vbox30; + GtkWidget *scrolledwindow6; + GtkWidget *chattext; + GtkWidget *hbox35; + GtkWidget *label107; + GtkWidget *chatentry; + GtkWidget *button17; + + chatroom = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (chatroom), _("Chat Room")); + gtk_window_set_default_size (GTK_WINDOW (chatroom), 400, 400); + gtk_window_set_destroy_with_parent (GTK_WINDOW (chatroom), TRUE); + chatroom_icon_pixbuf = create_pixbuf ("linphone/linphone2.xpm"); + if (chatroom_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (chatroom), chatroom_icon_pixbuf); + gdk_pixbuf_unref (chatroom_icon_pixbuf); + } + + vbox30 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox30); + gtk_container_add (GTK_CONTAINER (chatroom), vbox30); + + scrolledwindow6 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow6); + gtk_box_pack_start (GTK_BOX (vbox30), scrolledwindow6, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow6), GTK_SHADOW_IN); + + chattext = gtk_text_view_new (); + gtk_widget_show (chattext); + gtk_container_add (GTK_CONTAINER (scrolledwindow6), chattext); + gtk_text_view_set_editable (GTK_TEXT_VIEW (chattext), FALSE); + + hbox35 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox35); + gtk_box_pack_start (GTK_BOX (vbox30), hbox35, FALSE, TRUE, 0); + + label107 = gtk_label_new (_("Text:")); + gtk_widget_show (label107); + gtk_box_pack_start (GTK_BOX (hbox35), label107, FALSE, FALSE, 0); + + chatentry = gtk_entry_new (); + gtk_widget_show (chatentry); + gtk_box_pack_start (GTK_BOX (hbox35), chatentry, TRUE, TRUE, 0); + + button17 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (button17); + gtk_box_pack_start (GTK_BOX (vbox30), button17, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) chatroom, "destroy", + G_CALLBACK (on_chatroom_destroy), + NULL); + g_signal_connect ((gpointer) chatentry, "activate", + G_CALLBACK (on_chatentry_activate), + NULL); + g_signal_connect ((gpointer) button17, "clicked", + G_CALLBACK (on_chatbox_clicked), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (chatroom, chatroom, "chatroom"); + GLADE_HOOKUP_OBJECT (chatroom, vbox30, "vbox30"); + GLADE_HOOKUP_OBJECT (chatroom, scrolledwindow6, "scrolledwindow6"); + GLADE_HOOKUP_OBJECT (chatroom, chattext, "chattext"); + GLADE_HOOKUP_OBJECT (chatroom, hbox35, "hbox35"); + GLADE_HOOKUP_OBJECT (chatroom, label107, "label107"); + GLADE_HOOKUP_OBJECT (chatroom, chatentry, "chatentry"); + GLADE_HOOKUP_OBJECT (chatroom, button17, "button17"); + + gtk_widget_grab_focus (chatentry); + return chatroom; +} + diff --git a/linphone/gnome/interface.h b/linphone/gnome/interface.h new file mode 100644 index 000000000..1e94fd3f7 --- /dev/null +++ b/linphone/gnome/interface.h @@ -0,0 +1,15 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_app1 (void); +GtkWidget* create_about2 (void); +GtkWidget* create_prop1 (void); +GtkWidget* create_address_book (void); +GtkWidget* create_altressource (void); +GtkWidget* create_proxy_config_box (void); +GtkWidget* create_contact_box (void); +GtkWidget* create_inc_subscr_dialog (void); +GtkWidget* create_authentication_dialog (void); +GtkWidget* create_call_logs (void); +GtkWidget* create_chatroom (void); diff --git a/linphone/gnome/linphone.c b/linphone/gnome/linphone.c new file mode 100644 index 000000000..535cef11d --- /dev/null +++ b/linphone/gnome/linphone.c @@ -0,0 +1,449 @@ +/*************************************************************************** + linphone.c - Main code for linphone's gnome + interface + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "linphone.h" +#include "support.h" +#include "interface.h" +#include "callbacks.h" +#include "gui_utils.h" +#include "lpconfig.h" + + +LinphoneGnomeUI *uiobj=NULL; +#define get_uiobj() (uiobj) +#define get_core() (uiobj->core) +#define get_friend_list() (&uiobj->main_window.friendlist) + +void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core) +{ + gdk_threads_init(); + memset(ui,0,sizeof(LinphoneGnomeUI)); + ui->core=core; + uiobj=ui; + ui->main_window.shown_once=FALSE; +} + +static void restore_uri_history(GtkEntry *uribar, LpConfig *cfg){ + char key[20]; + int i; + GtkEntryCompletion *gep=gtk_entry_completion_new(); + GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING); + for (i=0;;i++){ + const char *uri; + snprintf(key,sizeof(key),"uri%i",i); + uri=lp_config_get_string(cfg,"GtkUi",key,NULL); + if (uri!=NULL) { + GtkTreeIter iter; + gtk_list_store_append(model,&iter); + gtk_list_store_set(model,&iter,0,uri,-1); + if (i==0) gtk_entry_set_text(uribar,uri); + } + else break; + } + gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model)); + gtk_entry_completion_set_text_column(gep,0); + gtk_entry_set_completion(uribar,gep); +} + +void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui){ + char key[20]; + int i=0; + char *uri=NULL; + GtkTreeIter iter; + GtkEntry *uribar=GTK_ENTRY(ui->main_window.addressentry); + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar)); + LpConfig *cfg=linphone_core_get_config(ui->core); + if (!gtk_tree_model_get_iter_first(model,&iter)) return; + do { + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri) { + snprintf(key,sizeof(key),"uri%i",i); + lp_config_set_string(cfg,"GtkUi",key,uri); + g_free(uri); + }else break; + i++; + if (i>5) break; + }while(gtk_tree_model_iter_next(model,&iter)); +} + +void main_window_create(LinphoneGnomeUI *obj) +{ + GtkWidget *child; + GtkWidget *window; + window=create_app1 (); + gnome_window_icon_set_from_default(GTK_WINDOW(window)); + obj->main_window.status_bar=lookup_widget(window,"appbar1"); + obj->main_window.addressentry=lookup_widget(window,"addressentry"); + obj->main_window.optioncontrols=lookup_widget(window,"optioncontrols"); + obj->main_window.dtmfentry=lookup_widget(window,"dtmf_entry"); + obj->main_window.callbutton=lookup_widget(window,"callbutton"); + child=lookup_widget(window,"showmore"); + /* hide the optionnal controls at startup */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child),0); +#ifndef VIDEO_ENABLED + gtk_widget_hide(lookup_widget(child,"video_enabled")); +#endif + presence_box_init(&obj->main_window.presencebox,window,obj->core); + friend_list_init(&obj->main_window.friendlist,obj->core,window); + g_object_set_data(G_OBJECT(window),"ui",(gpointer)obj); + obj->main_window.window=window; +} + +void linphone_gnome_ui_show(LinphoneGnomeUI *ui) +{ + if (ui->main_window.window==NULL){ + main_window_create(ui); + } + gtk_widget_show(ui->main_window.window); + gtk_window_present(GTK_WINDOW(ui->main_window.window)); + ui->main_window.shown_once=TRUE; +} + +void linphone_gnome_ui_hide(LinphoneGnomeUI *ui) +{ + if (ui->main_window.window==NULL) return; + gtk_widget_hide(ui->main_window.window); +} + + +void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui) +{ + ui->main_window.window=NULL; +} + +void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message) +{ + GtkWidget *dialog; + + if (!linphone_core_is_in_main_thread(ui->core)) gdk_threads_enter(); + linphone_gnome_ui_show(ui); + if (type==GTK_MESSAGE_QUESTION) + { +#ifdef VINCENT_MAURY_RSVP + /* draw a question box. link to dialog_click callback */ + dialog = gtk_message_dialog_new ( + GTK_WINDOW(ui->main_window.window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + (const gchar*)message); + /* connect the click event to the callback */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (dialog_click), + G_OBJECT (dialog)); + /* actually show the box */ + gtk_widget_show(dialog); +#endif + } + else + { + dialog = gtk_message_dialog_new (GTK_WINDOW(ui->main_window.window), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + GTK_BUTTONS_CLOSE, + (const gchar*)message); + /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); + gtk_widget_show(dialog); + } + if (!linphone_core_is_in_main_thread(ui->core)) gdk_threads_leave(); +} + +/* these are the LinphoneCore virtual functions */ +void linphone_gnome_display_message(LinphoneCore *lc, const char *message) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_INFO,message); +} + +#ifdef VINCENT_MAURY_RSVP +/* Question box with yes/no answer. */ +void linphone_gnome_display_yes_no(LinphoneCore *lc,const char *message) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + if (strcmp(message,"With QoS")==0) + /* the caller asks for QoS, this function is called because, by default, + * you don't use QoS ! */ + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION, + _("The caller asks for resource reservation. Do you agree ?")); + else + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION, + _("The caller doesn't use resource reservation. \ + Do you wish to continue anyway ?")); +} +#endif + +void linphone_gnome_display_warning(LinphoneCore *lc, const char *warning) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_WARNING,warning); +} + +void linphone_gnome_display_status(LinphoneCore *lc, const char *status) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + if (ui->main_window.window==NULL) return; + if (!ui->main_window.shown_once) return; /* avoid a gnome bug*/ + gnome_appbar_push(GNOME_APPBAR(ui->main_window.status_bar),status); + +} + +void linphone_gnome_inv_recv(LinphoneCore *lc,const char *from) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + gchar *title; + if (ui->main_window.window==NULL) return; + gtk_entry_set_text(GTK_ENTRY(ui->main_window.addressentry),from); + title=g_strdup_printf(_("linphone - receiving call from %s"),from); + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),title); + g_free(title); +} + +void linphone_gnome_show(LinphoneCore *lc) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_show(ui); +} + +void linphone_gnome_display_url(LinphoneCore *lc, const char *message, const char *url) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + alt_ressource_display(ui,url); +} + + + +void linphone_gnome_notify_received(LinphoneCore *lc,LinphoneFriend *fid, const char *from, const char *status, const char *img){ + FriendList *fl=get_friend_list(); + friend_list_set_friend_status(fl,fid,from,status, img); +} + +void linphone_gnome_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ + GtkWidget *d=create_inc_subscr_dialog(); + gchar *text=g_strdup_printf(_("You have received a subscription from %s." + "This means that this person wishes to be notified of your presence information (online, busy, away...).\n" + "Do you agree ?"),url); + gtk_label_set_text(GTK_LABEL(lookup_widget(d,"subscr_label")),text); + g_object_set_data(G_OBJECT(d),"friend_ref",(gpointer)lf); + gtk_widget_show(d); +} + +void linphone_gnome_prompt_authentication(LinphoneCore *lc, const gchar *realm, const gchar *username){ + GtkWidget *w=create_authentication_dialog(); + gchar *question=g_strdup_printf(_("Authentication required for realm %s"),realm); + gtk_label_set_text(GTK_LABEL(lookup_widget(w,"question")),question); + g_free(question); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"realm")),realm); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"username")),username); + gtk_widget_show(w); +} + +void linphone_gnome_bye_recv(LinphoneCore *lc, const char *from){ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone"); +} + +void stub(){ +} + +void linphone_gnome_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){ + LinphoneGnomeUI *ui=(LinphoneGnomeUI *)linphone_core_get_user_data(lc); + linphone_gnome_update_call_logs(ui); +} + +void linphone_gnome_text_received(LinphoneCore *lc,LinphoneChatRoom *cr, const char *from, const char *msg){ + GtkWidget *gcr=(GtkWidget*)linphone_chat_room_get_user_data(cr); + if (gcr==NULL){ + gcr=chatroom_new(from,cr); + } + gtk_widget_show(gcr); + chatroom_append(gcr,from,msg); +} + +LinphoneCoreVTable linphone_gnome_vtable= +{ + show: linphone_gnome_show, + inv_recv: linphone_gnome_inv_recv, + bye_recv : linphone_gnome_bye_recv, + notify_recv: linphone_gnome_notify_received, + new_unknown_subscriber: linphone_gnome_new_unknown_subscriber, + auth_info_requested: linphone_gnome_prompt_authentication, + display_status : linphone_gnome_display_status, + display_message : linphone_gnome_display_message, + display_warning : linphone_gnome_display_warning, +#ifdef VINCENT_MAURY_RSVP + display_yes_no : linphone_gnome_display_yes_no, +#endif + display_url : linphone_gnome_display_url, + display_question : stub, + call_log_updated : linphone_gnome_call_log_updated, + text_received: linphone_gnome_text_received +}; + +gboolean linphone_gnome_iterate(LinphoneCore *lc) +{ + linphone_core_iterate(lc); + return TRUE; +} + +void proxy_changed(GtkWidget *combo){ + LinphoneProxyConfig *pcfg=proxy_combo_box_get_selected(combo); + linphone_core_set_default_proxy(get_core(),pcfg); +} + +void linphone_refresh_proxy_combo_box(GtkWidget *window){ + LinphoneCore *lc=get_core(); + GtkWidget *combo; + const MSList *elem=linphone_core_get_proxy_config_list(lc); + LinphoneProxyConfig *cfg=NULL; + GtkWidget *hbox=lookup_widget(window,"proxy_hbox"); + + linphone_core_get_default_proxy(lc,&cfg); + + if (elem==NULL){ + gtk_widget_hide(hbox); + return; + } + combo=(GtkWidget*)g_object_get_data(G_OBJECT(hbox),"proxy"); + if (combo!=NULL){ + gtk_widget_destroy(combo); + } + combo=proxy_combo_box_new(cfg); + g_object_set_data(G_OBJECT(hbox),"proxy",(gpointer)combo); + g_signal_connect(G_OBJECT(combo),"changed",G_CALLBACK(proxy_changed),NULL); + gtk_box_pack_start_defaults(GTK_BOX(hbox),combo); + gtk_widget_show(combo); + gtk_widget_show(hbox); + +} + +void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc) +{ + gchar *configfile_name = + g_strdup_printf ("%s/.gnome2/linphone", getenv ("HOME")); + linphone_gnome_ui_init(ui,lc); + linphone_gnome_ui_show(ui); + linphone_core_init(lc,&linphone_gnome_vtable,configfile_name,(gpointer)ui); + g_free(configfile_name); + set_levels(ui,linphone_core_get_rec_level(lc),linphone_core_get_play_level(lc),linphone_core_get_ring_level(lc)); + /* get history of uri bar */ + restore_uri_history(GTK_ENTRY(ui->main_window.addressentry), linphone_core_get_config(lc)); + linphone_refresh_proxy_combo_box(ui->main_window.window); + ui->timeout_id=gtk_timeout_add(500,(GtkFunction)linphone_gnome_iterate,(gpointer)lc); +} + +void linphone_gnome_uninit(LinphoneGnomeUI *ui) +{ + LinphoneCore *lc=ui->core; + linphone_gnome_ui_uninit(ui); + linphone_core_uninit(lc); + gtk_timeout_remove (ui->timeout_id); +} + +GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected){ + GtkWidget *combo; + const MSList *elem; + GtkListStore *store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_POINTER); + GtkTreeIter iter; + GtkTreeIter prxiter; + GtkCellRenderer *renderer; + gboolean proxy_found=FALSE; + /* fill the store */ + elem=linphone_core_get_proxy_config_list(get_core()); + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,0,_("None"),1,(gpointer)NULL,-1); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)elem->data; + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,0,proxy->reg_proxy,1,(gpointer)proxy,-1); + if (selected==proxy) { + prxiter=iter; + proxy_found=TRUE; + } + } + combo=gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, + "text", 0, + NULL); + if (proxy_found){ + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),&prxiter); + }else{ + /*else select "None" */ + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0); + } + return combo; +} + +LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo){ + LinphoneProxyConfig *pcfg=NULL; + GtkTreeIter iter; + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo),&iter)){ + GtkTreeModel *model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_tree_model_get(model,&iter,1,(gpointer)&pcfg,-1); + } + return pcfg; +} + +void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui){ + LinphoneCore *lc=ui->core; + GtkTextView *tv; + GtkTextBuffer *tb; + GtkTextIter begin,end; + GtkTextTag *tag; + MSList *elem; + if (ui->logs==NULL) return; + tv=GTK_TEXT_VIEW(lookup_widget(ui->logs,"logview")); + tb=gtk_text_view_get_buffer(tv); + + gtk_text_buffer_get_bounds(tb,&begin,&end); + gtk_text_buffer_delete(tb,&begin,&end); + gtk_text_buffer_get_end_iter(tb,&end); + for (elem=linphone_core_get_call_logs(lc);elem!=NULL;elem=ms_list_next(elem)){ + LinphoneCallLog *cl=(LinphoneCallLog*)elem->data; + gchar *str=linphone_call_log_to_str(cl); + tag=NULL; + if (cl->status==LinphoneCallMissed){ + tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(tb),"redforeground"); + if (tag==NULL) tag = gtk_text_buffer_create_tag (tb, "redforeground", + "foreground", "red", NULL); + } + gtk_text_buffer_insert_with_tags(tb,&end,str,-1,tag,NULL); + gtk_text_buffer_insert(tb,&end,"\n",-1); + + ms_free(str); + } +} + +void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui){ + if (ui->logs==NULL) { + ui->logs=create_call_logs(); + } + linphone_gnome_update_call_logs(ui); + gtk_widget_show(ui->logs); +} diff --git a/linphone/gnome/linphone.h b/linphone/gnome/linphone.h new file mode 100644 index 000000000..fd3fa3872 --- /dev/null +++ b/linphone/gnome/linphone.h @@ -0,0 +1,66 @@ + + +#ifndef LINPHONE_H +#define LINPHONE_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "lpconfig.h" + +#include "support.h" +#include "propertybox.h" +#include "presence.h" +#include "addressbook.h" +#include "friends.h" + +typedef struct _LinphoneMainWindow +{ + GtkWidget *window; + GtkWidget *status_bar; + GtkWidget *addressentry; + GtkWidget *optioncontrols; + GtkWidget *dtmfentry; + GtkWidget *callbutton; + PresenceBox presencebox; + FriendList friendlist; + gboolean shown_once; +}LinphoneMainWindow; + +typedef struct _LinphoneGnomeUI +{ + LinphoneMainWindow main_window; + LinphonePropertyBox propbox; + GtkWidget *ab; /*the address book */ + GtkWidget *logs; /* the call logs window */ + LinphoneCore *core; + guint timeout_id; +}LinphoneGnomeUI; + + +void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core); +void linphone_gnome_ui_show(LinphoneGnomeUI *ui); +void linphone_gnome_ui_hide(LinphoneGnomeUI *ui); +void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui); + +void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc); +void linphone_gnome_uninit(LinphoneGnomeUI *ui); + +extern LinphoneGnomeUI *uiobj; + +GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected); +void linphone_refresh_proxy_combo_box(GtkWidget *window); +LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo); +void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui); +void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui); +void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message); +void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui); + +GtkWidget *chatroom_new(const gchar *url, LinphoneChatRoom *cr); +void chatroom_append(GtkWidget *gcr, const gchar *from, const gchar *message); +void chatroom_close(GtkWidget *gcr); + +#endif diff --git a/linphone/gnome/main.c b/linphone/gnome/main.c new file mode 100644 index 000000000..e62d199f0 --- /dev/null +++ b/linphone/gnome/main.c @@ -0,0 +1,70 @@ +/* + * Initial main.c file generated by Glade. Edit as required. + * Glade will not overwrite this file. + */ + + +#include "linphone.h" + + +/* +#include "../osipua/src/dbgalloc.h" + +GMemVTable dbgtable={ + smalloc, + srealloc, + sfree, + scalloc, + smalloc, + srealloc +}; +*/ +LinphoneCore core; +LinphoneGnomeUI ui; +static int verbose=0; +struct poptOption linphone_options[2]={ + { + longName: "verbose", + shortName: '\0', + argInfo: POPT_ARG_NONE, + arg : (void*)&verbose, + val : 0, + descrip: "log to stdout some debug information while running.", + NULL + }, + POPT_TABLEEND +}; + +int +main (int argc, char *argv[]) +{ + void *p; + + //g_log_set_fatal_mask("GLib",G_LOG_LEVEL_WARNING); + //g_mem_set_vtable(glib_mem_profiler_table); + //g_mem_set_vtable(&dbgtable); +#ifdef ENABLE_NLS + p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + if (p==NULL) perror("bindtextdomain failed"); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); +#else + printf("NLS disabled.\n"); +#endif + + gnome_program_init ("linphone", LINPHONE_VERSION, LIBGNOMEUI_MODULE, + argc, argv, + GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR, + GNOME_PARAM_POPT_TABLE,&linphone_options,NULL); + + if (verbose) linphone_core_enable_logs(stdout); + else linphone_core_disable_logs(); + linphone_gnome_init(&ui,&core); + linphone_gnome_ui_show(&ui); + gtk_main (); + gdk_threads_leave(); /* it appears that the gdk lock is hold while exiting from gtk_main() */ + linphone_gnome_uninit(&ui); + //g_mem_profile(); + exit(0); + return 0; +} diff --git a/linphone/gnome/presence.c b/linphone/gnome/presence.c new file mode 100644 index 000000000..18042b2c8 --- /dev/null +++ b/linphone/gnome/presence.c @@ -0,0 +1,150 @@ +/*************************************************************************** + presence.c - code for the presence box + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "linphone.h" +#include "callbacks.h" +#include "support.h" + + +void presence_box_init(PresenceBox *p, GtkWidget *main_window,LinphoneCore *lc) +{ + GtkWidget *r; + p->lc=lc; + p->contact_field=lookup_widget(main_window,"contact_field"); + p->minutesaway=lookup_widget(main_window,"minutesaway"); + r=lookup_widget(main_window,"presence_reachable"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(r),TRUE); + r=lookup_widget(main_window,"presence_frame"); +} + +void presence_box_changed(PresenceBox *p) +{ + presence_box_apply(p); +} + +#define get_presence_box() (&(uiobj)->main_window.presencebox) + + +void +on_reachable (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + p->toggled_button=PRESENCE_MODE_REACHABLE; + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + //gtk_widget_set_sensitive(p->contact_field,FALSE); + presence_box_changed(p); +} + + +void +on_busy (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + p->toggled_button=PRESENCE_MODE_BUSY; + //gtk_widget_set_sensitive(p->minutesaway,TRUE); + presence_box_changed(p); +} + + +void +on_minutesaway_changed (GtkEditable *editable,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + presence_box_changed(p); +} + + +void +on_away (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + //gtk_widget_set_sensitive(p->minutesaway,TRUE); + p->toggled_button=PRESENCE_MODE_AWAY; + presence_box_changed(p); +} + + +void +on_do_not_disturb (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_NOT_DISTURB; + presence_box_changed(p); +} + + +void +on_moved_tmply (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,TRUE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_MOVED; + presence_box_changed(p); +} + + +void +on_alt_serv (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,TRUE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_ALT_SERVICE; + presence_box_changed(p); +} + + +void +on_contact_field_changed (GtkEditable *entry,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + presence_box_changed(p); +} + +void presence_box_apply(PresenceBox *p) +{ + gchar *tmp,*contact=NULL; + int minutes_away=-1; + g_message("presence_box_apply"); + /* retrieve the minutes away */ + tmp = gtk_editable_get_chars (GTK_EDITABLE(p->minutesaway),0,-1); + if (tmp!=NULL && strlen(tmp)>0) + { + minutes_away = atoi(tmp); + g_free(tmp); + } + /* retrieve the alternate contact url */ + tmp = gtk_editable_get_chars (GTK_EDITABLE(p->contact_field),0,-1); + if (tmp!=NULL && strlen(tmp)>0) + { + contact=tmp; + } + /* set presence mode */ + linphone_core_set_presence_info(p->lc,minutes_away,contact,p->toggled_button); + if (tmp!=NULL) g_free(tmp); +} diff --git a/linphone/gnome/presence.h b/linphone/gnome/presence.h new file mode 100644 index 000000000..cbe8701c7 --- /dev/null +++ b/linphone/gnome/presence.h @@ -0,0 +1,43 @@ +/*************************************************************************** + presence.h - code for the presence box + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PRESENCE_H +#define PRESENCE_H + +enum { PRESENCE_MODE_REACHABLE=LINPHONE_STATUS_ONLINE, + PRESENCE_MODE_BUSY=LINPHONE_STATUS_BUSY, + PRESENCE_MODE_AWAY=LINPHONE_STATUS_AWAY, + PRESENCE_MODE_NOT_DISTURB=LINPHONE_STATUS_NOT_DISTURB, + PRESENCE_MODE_MOVED=LINPHONE_STATUS_MOVED, + PRESENCE_MODE_ALT_SERVICE=LINPHONE_STATUS_ALT_SERVICE + }; + + +typedef struct _PresenceBox +{ + LinphoneCore *lc; + GtkWidget *minutesaway; + GtkWidget *contact_field; + gint toggled_button; /* indicate which button is toggled*/ +} PresenceBox; + + +void presence_box_init(PresenceBox *p, GtkWidget *main_window,LinphoneCore *lc); +void presence_box_changed(PresenceBox *p); +void presence_box_apply(PresenceBox *p); + +#endif diff --git a/linphone/gnome/propertybox.c b/linphone/gnome/propertybox.c new file mode 100644 index 000000000..50f818176 --- /dev/null +++ b/linphone/gnome/propertybox.c @@ -0,0 +1,1065 @@ +/*************************************************************************** + propertybox.c - description + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "linphone.h" + +enum{ +#ifdef INET6 + IFACE_INDEX, +#endif + IFACE_NAME, + IFACE_ADDR, + IFACE_NCOLUMNS +}; + +enum { + CODEC_NAME, + CODEC_RATE, + CODEC_BITRATE, + CODEC_STATUS, + CODEC_PRIVDATA, + CODEC_COLOR, + CODEC_NCOLUMNS +}; + +#define get_core() (uiobj->core) +#define get_property_box() (&uiobj->propbox) +#define property_box_changed() gnome_property_box_changed(GNOME_PROPERTY_BOX ( (&uiobj->propbox)->prop)) +#define get_main_window() (&uiobj->main_window) + +#if !GTK_CHECK_VERSION(2,6,0) +static gchar * _lp_combo_box_get_active_text (GtkComboBox *combobox) +{ + GtkTreeIter iter; + GtkTreeModel *model; + gchar *text = NULL; + model = gtk_combo_box_get_model (combobox); + if (gtk_combo_box_get_active_iter (combobox, &iter) && model) + gtk_tree_model_get (model, &iter, 0, &text, -1); + return text; +} +#endif /* GTK+ < 2.6.0 */ + +void net_section_init(NetSection *sec, GtkWidget *prop) +{ + sec->au_port=lookup_widget(prop,"audioport"); + sec->audio_jittcomp=lookup_widget(prop,"audio_jittcomp"); +#ifdef LINPHONE_DEPRECATED + sec->interfaces=lookup_widget(prop, "interfaces"); +#endif + sec->nat_address=lookup_widget(prop,"nat_address"); + sec->use_sipinfo=lookup_widget(prop,"use_sipinfo"); + sec->enable_ipv6=lookup_widget(prop,"enable_ipv6"); +} + +void codec_list_update(GtkTreeView *listview); + + +void net_selection_changed_cb(GtkTreeSelection *select, gpointer userdata) +{ + property_box_changed(); +} + +void net_section_fill(NetSection *sec,LinphoneCore *lc) +{ + gfloat value; + const gchar *nat_address,*stun_server; + + value=(gfloat)linphone_core_get_audio_jittcomp(lc); + /* put the current value of jitt_comp*/ + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(sec->audio_jittcomp)),value); + /* display current rtp port */ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(sec->au_port), + (gfloat)linphone_core_get_audio_port(lc)); + + + /* nat setup */ + nat_address=linphone_core_get_nat_address(lc); + + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_NAT_ADDRESS) + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"static_nat")) + ,TRUE); + + if (nat_address!=NULL) { + gtk_entry_set_text(GTK_ENTRY(sec->nat_address),nat_address); + } + stun_server=linphone_core_get_stun_server(lc); + if (stun_server!=NULL) + gtk_entry_set_text( + GTK_ENTRY(lookup_widget(get_property_box()->prop,"stun_server")), + stun_server); + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_STUN) + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"use_stun")),TRUE); + + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->use_sipinfo), + linphone_core_get_use_info_for_dtmf(lc)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->enable_ipv6), + linphone_core_ipv6_enabled(lc)); +} + +void +on_enable_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); + +} + + + +void +on_nat_address_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_enable_ipv6_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void net_section_apply(NetSection *sec,LinphoneCore *lc) +{ + gboolean use_nat,use_stun; + gchar *name; + + use_nat=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + lookup_widget(get_property_box()->prop,"static_nat"))); + name=gtk_editable_get_chars(GTK_EDITABLE(sec->nat_address),0,-1); + linphone_core_set_nat_address(lc,name); + g_free(name); + + use_stun=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + lookup_widget(get_property_box()->prop,"use_stun") )); + name=gtk_editable_get_chars(GTK_EDITABLE( + lookup_widget(get_property_box()->prop,"stun_server") ),0,-1); + linphone_core_set_stun_server(lc,name); + g_free(name); + if (use_stun) linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_USE_STUN); + else if (use_nat) linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_USE_NAT_ADDRESS); + else linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_NO_FIREWALL); + + { + /* get the value of jitt_comp*/ + GtkAdjustment *adj= gtk_range_get_adjustment(GTK_RANGE(sec->audio_jittcomp)); + linphone_core_set_audio_jittcomp(lc,(gint)adj->value); + /* get rtp port */ + adj=gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(sec->au_port)); + linphone_core_set_audio_port(lc,(gint)adj->value); + } + linphone_core_enable_ipv6(lc,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sec->enable_ipv6))); +} + + +enum{ + PROXY_CONFIG_IDENTITY, + PROXY_CONFIG_REF, + PROXY_CONFIG_NCOL +}; + +void sip_section_init(SipSection *sec,GtkWidget *prop) +{ + + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + sec->port=lookup_widget(prop,"sip_port"); + sec->username=lookup_widget(prop, "user_name"); + sec->hostname=lookup_widget(prop,"domain_name"); + sec->proxy_list=lookup_widget(prop,"proxy_list"); + sec->guess_hostname=lookup_widget(prop,"guess_hostname"); + /* create the proxy list */ + store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model(GTK_TREE_VIEW(sec->proxy_list),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Account"), + renderer, + "text", PROXY_CONFIG_IDENTITY, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sec->proxy_list), column); + + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (sec->proxy_list)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); +} + + +void proxy_list_fill(GtkTreeModel *model, LinphoneCore *lc){ + const MSList *elem; + GtkTreeIter iter; + /* fill the proxy list */ + gtk_list_store_clear(GTK_LIST_STORE(model)); + elem=linphone_core_get_proxy_config_list(lc); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *pcfg=(LinphoneProxyConfig*)elem->data; + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,PROXY_CONFIG_IDENTITY,pcfg->reg_identity, + PROXY_CONFIG_REF,pcfg,-1); + } +} + +void sip_section_fill(SipSection *sec, LinphoneCore *lc) +{ + osip_from_t *contact; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->proxy_list)); + + /* set sip port */ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(sec->port), + (gfloat)linphone_core_get_sip_port(lc)); + contact=linphone_core_get_primary_contact_parsed(lc); + g_return_if_fail(contact!=NULL); + /* set sip username */ + gtk_entry_set_text(GTK_ENTRY(sec->username),contact->url->username); + /* set domain name */ + gtk_entry_set_text(GTK_ENTRY(sec->hostname),contact->url->host); + osip_from_free(contact); + proxy_list_fill(model,lc); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->guess_hostname), + linphone_core_get_guess_hostname(lc)); +} + +void sip_section_apply(SipSection *sec, LinphoneCore *lc) +{ + GtkAdjustment *adj; + gchar *tmp; + gchar *username,*hostname; + /* get sip port*/ + adj=gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(sec->port)); + + username=gtk_editable_get_chars(GTK_EDITABLE(sec->username),0,-1); + if (username!=NULL && strlen(username)!=0) + { + hostname=gtk_editable_get_chars(GTK_EDITABLE(sec->hostname),0,-1); + if (hostname!=NULL && strlen(hostname)!=0) + { + tmp=g_strdup_printf("sip:%s@%s",username,hostname); + linphone_core_set_primary_contact(lc,tmp); + linphone_core_set_sip_port(lc,(int)gtk_adjustment_get_value(adj)); + g_free(hostname); + g_free(tmp); + } + g_free(username); + } +} + + +void +on_addproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *w=create_proxy_config_box(); + gtk_widget_show(w); +} + + +void +on_editproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *w; + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneProxyConfig * cfg; + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_property_box()->sip.proxy_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,PROXY_CONFIG_REF , &cfg, -1); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + linphone_proxy_config_edit(cfg); + }else return; + w=create_proxy_config_box(); + gtk_widget_show(w); + if (cfg->reg_proxy!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_proxy")),cfg->reg_proxy); + if (cfg->reg_route!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_route")),cfg->reg_route); + if (cfg->reg_identity!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_identity")),cfg->reg_identity); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"reg_sendregister")),cfg->reg_sendregister); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"publish")),cfg->publish); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(w,"reg_expires")),cfg->expires); + g_object_set_data(G_OBJECT(w),"edited_config",(gpointer)cfg); +} + + +void +on_removeproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneProxyConfig * cfg; + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_property_box()->sip.proxy_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,PROXY_CONFIG_REF , &cfg, -1); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + linphone_core_remove_proxy_config(get_core(),cfg); + linphone_refresh_proxy_combo_box(get_main_window()->window); + } +} + +void get_proxy_config_box_data(GtkWidget *dialog) +{ + gchar *tmp; + gboolean editing=FALSE; + LinphoneProxyConfig *cfg; + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_proxy")),0,-1); + cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(dialog),"edited_config"); + if (cfg==NULL){ + cfg=linphone_proxy_config_new(tmp); + g_free(tmp); + if (cfg==NULL) { + /* set an error message here */ + return; + } + }else{ + linphone_proxy_config_set_server_addr(cfg,tmp); + g_free(tmp); + editing=TRUE; + } + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_route")),0,-1); + linphone_proxy_config_set_route(cfg,tmp); + g_free(tmp); + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_identity")),0,-1); + linphone_proxy_config_set_identity(cfg,tmp); + g_free(tmp); + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_expires")),0,-1); + { + int exp; + if (tmp!=NULL) + { + exp = atoi(tmp); + if (exp<=0) + exp = 200; /* minimum */ + if (exp>7200) + exp = 7200; /* maximum */ + linphone_proxy_config_expires(cfg,exp); + } + } + g_free(tmp); + linphone_proxy_config_enableregister(cfg,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"reg_sendregister")))); + linphone_proxy_config_enable_publish(cfg,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"publish")))); + if (editing) linphone_proxy_config_done(cfg); + else linphone_core_add_proxy_config(get_core(),cfg); + /* set the last entered/changed proxy as the default one */ + linphone_core_set_default_proxy(get_core(),cfg); + proxy_list_fill(gtk_tree_view_get_model(GTK_TREE_VIEW(get_property_box()->sip.proxy_list)),get_core()); + linphone_refresh_proxy_combo_box(get_main_window()->window); +} + +void +on_proxy_config_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch(response_id){ + case GTK_RESPONSE_OK: + get_proxy_config_box_data(GTK_WIDGET(dialog)); + gtk_widget_destroy(GTK_WIDGET(dialog)); + + break; + } +} + + +void codec_section_init(CodecSection *sec, GtkWidget *prop) +{ + sec->au_codec_list=lookup_widget(prop,"au_codec_list"); + sec->vi_codec_list=lookup_widget(prop,"vid_codec_list"); + sec->codec_info=lookup_widget(prop,"codec_info"); +} + +void codec_selection_changed_cb(GtkTreeSelection *selection, gpointer data) +{ + GtkTreeIter iter; + GtkTreeModel *model; + struct _PayloadType *pt=NULL; + LinphonePropertyBox *prop=get_property_box(); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, CODEC_PRIVDATA, &pt, -1); + g_return_if_fail(pt!=NULL); + /* display the codec information */ + gtk_label_set_text(GTK_LABEL(prop->codec.codec_info),payload_type_get_description(pt)); + } +} + +void codec_list_build(GtkTreeView *listview,const MSList *codeclist) +{ + const MSList *elem; + GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_FLOAT, + G_TYPE_STRING, + G_TYPE_POINTER, + G_TYPE_STRING); + GtkTreeIter iter; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select=gtk_tree_view_get_selection (listview); + for(elem=codeclist; elem!=NULL; elem=elem->next){ + gchar *status; + gint rate; + gfloat bitrate; + gchar *color; + struct _PayloadType *pt=(struct _PayloadType *)elem->data; + if (payload_type_enabled(pt)) status=_("Enabled"); + else status=_("Disabled"); + if (linphone_core_check_payload_type_usability(get_core(),pt)) color="blue"; + else color="red"; + /* get an iterator */ + gtk_list_store_append(store,&iter); + bitrate=payload_type_get_bitrate(pt)/1000.0; + rate=payload_type_get_rate(pt); + gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt), + CODEC_RATE,rate, + CODEC_BITRATE,bitrate, + CODEC_STATUS,status, + CODEC_PRIVDATA,(gpointer)pt, + CODEC_COLOR,(gpointer)color, + -1); + } + gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", CODEC_NAME, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"), + renderer, + "text", CODEC_RATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Status"), + renderer, + "text", CODEC_STATUS, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"), + renderer, + "text", CODEC_BITRATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + + /* Setup the selection handler */ + select = gtk_tree_view_get_selection (listview); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces)); + g_signal_connect (G_OBJECT (select), "changed", + G_CALLBACK (codec_selection_changed_cb), + NULL); +} + +void codec_section_fill(CodecSection *sec, LinphoneCore *lc, GtkWidget *propbox) +{ + /* display prefered codecs*/ + int value; + const MSList *audio_codecs=linphone_core_get_audio_codecs(lc); + const MSList *video_codecs=linphone_core_get_video_codecs(lc); + codec_list_build(GTK_TREE_VIEW(sec->au_codec_list),audio_codecs); + codec_list_build(GTK_TREE_VIEW(lookup_widget(propbox,"vid_codec_list")),video_codecs); + value=linphone_core_get_download_bandwidth(lc); + if (value!=0) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(propbox,"download_bw")),value); + else + gtk_entry_set_text(GTK_ENTRY(lookup_widget(propbox,"download_bw")),_("Unlimited")); + value=linphone_core_get_upload_bandwidth(lc); + if (value!=0) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(propbox,"upload_bw")),value); + else + gtk_entry_set_text(GTK_ENTRY(lookup_widget(propbox,"upload_bw")),_("Unlimited")); +} + +void codec_section_apply(CodecSection *sec, LinphoneCore *lc) +{ + GtkTreeIter iter; + struct _PayloadType *pt; + MSList *codeclist=NULL; + gchar *status; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->au_codec_list)); + /* retrieve the codec list */ + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_STATUS,&status,CODEC_PRIVDATA, &pt,-1); + g_return_if_fail(pt!=NULL); + if (strcmp(status,_("Enabled"))==0) payload_type_set_enable(pt,1); + else payload_type_set_enable(pt,0); + codeclist=ms_list_append(codeclist,pt); + }while (gtk_tree_model_iter_next(model,&iter)); + linphone_core_set_audio_codecs(lc,codeclist); + model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->vi_codec_list)); + /* retrieve the codec list */ + codeclist=NULL; + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_STATUS,&status,CODEC_PRIVDATA, &pt,-1); + g_return_if_fail(pt!=NULL); + if (strcmp(status,_("Enabled"))==0) payload_type_set_enable(pt,1); + else payload_type_set_enable(pt,0); + codeclist=ms_list_append(codeclist,pt); + }while (gtk_tree_model_iter_next(model,&iter)); + linphone_core_set_video_codecs(lc,codeclist); +} + +void sound_section_init(SoundSection *sec, GtkWidget *prop) +{ + sec->source_entry=lookup_widget(prop,"rec_source"); + sec->ringfileentry=lookup_widget(prop,"ringfileentry"); +} + + +void +on_play_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char *dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char *dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + linphone_core_set_playback_device(get_core(),dev); + property_box_changed(); + g_free(dev); +} + + +void +on_capt_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char * dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char * dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + linphone_core_set_capture_device(get_core(),dev); + property_box_changed(); + g_free(dev); +} + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char * dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char * dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + linphone_core_set_ringer_device(get_core(),dev); + property_box_changed(); + g_free(dev); +} + +static int get_dev_index(const char **devnames, const char *dev){ + int i; + for (i=0;devnames[i]!=NULL;i++){ + if (strcmp(devnames[i],dev)==0) + return i; + } + g_warning("could not find %s in device list.",dev); + return 0; +} + +void sound_section_fill(SoundSection *sec, LinphoneCore *lc) +{ + GtkComboBox *play_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"play_card")); + GtkComboBox *capt_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"capt_card")); + GtkComboBox *ring_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"ring_card")); + int i; + const char **devnames=linphone_core_get_sound_devices(lc); + /* select used sound drivers*/ + + for (i=0;devnames[i]!=NULL;i++){ + const char *carddesc=devnames[i]; + gtk_combo_box_append_text(play_card,carddesc); + gtk_combo_box_append_text(capt_card,carddesc); + gtk_combo_box_append_text(ring_card,carddesc); + } + /*select used cards */ + gtk_combo_box_set_active(play_card,get_dev_index(devnames,linphone_core_get_playback_device(lc))); + gtk_combo_box_set_active(capt_card,get_dev_index(devnames,linphone_core_get_capture_device(lc))); + gtk_combo_box_set_active(ring_card,get_dev_index(devnames,linphone_core_get_ringer_device(lc))); + /* select audio source*/ + switch(linphone_core_get_sound_source(lc)) + { + case 'm': + gtk_entry_set_text (GTK_ENTRY (sec->source_entry), _("micro")); + break; + case 'l': + gtk_entry_set_text (GTK_ENTRY (sec->source_entry), _("line")); + break; + default: + g_warning("Invalid source !"); + } + { + gchar *ringfile=linphone_core_get_ring(lc); + gnome_file_entry_set_filename(GNOME_FILE_ENTRY(sec->ringfileentry),ringfile); + + } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"echocancelation")),linphone_core_echo_cancelation_enabled(lc)); +} + + + + +void sound_section_apply(SoundSection *sec, LinphoneCore *lc) +{ + gchar *tmp; + + /* get audio source*/ + tmp=gtk_editable_get_chars(GTK_EDITABLE(sec->source_entry),0,-1); + if (strcmp(tmp,_("micro"))==0) linphone_core_set_sound_source(lc,'m'); + else if (strcmp(tmp,_("line"))==0) linphone_core_set_sound_source(lc,'l'); + g_free(tmp); + + /* get ring path */ + tmp=gtk_editable_get_chars(GTK_EDITABLE(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(sec->ringfileentry))),0,-1); + linphone_core_set_ring(lc,tmp); + g_free(tmp); + +} + +void ring_finished(LinphoneCore *lc,gpointer user_data) +{ + GtkWidget *button=(GtkWidget*)user_data; + LinphonePropertyBox *prop=get_property_box(); + if (prop->prop==NULL) return; /* the box has been closed before the end of the preview */ + gtk_widget_set_sensitive(button,1); +} + +void +on_ringpreview_clicked (GtkButton *button, + gpointer user_data) +{ + int err; + gchar *tmp; + LinphonePropertyBox *prop=get_property_box(); + LinphoneCore *lc=get_core(); + /* get ring path */ + tmp=gtk_editable_get_chars(GTK_EDITABLE(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(prop->sound.ringfileentry))),0,-1); + err=linphone_core_preview_ring(lc,tmp,ring_finished,(gpointer)button); + if (err==0) gtk_widget_set_sensitive(GTK_WIDGET(button),0); + g_free(tmp); +} + + +void linphone_property_box_fill(LinphonePropertyBox * box, LinphoneCore *lp) +{ + net_section_fill(&box->net,lp); + sip_section_fill(&box->sip,lp); + codec_section_fill(&box->codec,lp,box->prop); + sound_section_fill(&box->sound,lp); + /* set uchanged state to the prop1 box, because gtk_entry_set_text() causes signal "changed" + to be sent */ + gnome_property_box_set_state(GNOME_PROPERTY_BOX(box->prop),0); +} + +void linphone_property_box_init(LinphonePropertyBox *box) +{ + if (box->prop==NULL){ + GtkWidget *prop=create_prop1(); + box->prop=prop; + net_section_init(&box->net,prop); + sip_section_init(&box->sip,prop); + codec_section_init(&box->codec,prop); + sound_section_init(&box->sound,prop); + gtk_widget_show(prop); + linphone_property_box_fill(box,get_core()); + }else{ + gtk_widget_show(box->prop); + gtk_window_present(GTK_WINDOW(box->prop)); + } +} + + + + +void on_propertybox1_apply (GtkButton *button, + gint pagenum) +{ + LinphonePropertyBox *prop=get_property_box(); + LinphoneCore *lc=get_core(); + switch(pagenum) + { + case 0: + net_section_apply(&prop->net,lc); + break; + case 1: + sound_section_apply(&prop->sound,lc); + break; + case 2: + sip_section_apply(&prop->sip,lc); + break; + case 3: + codec_section_apply(&prop->codec,lc); + break; + } +} + + +void +on_audioport_changed (GtkEditable *editable, + gpointer user_data) +{ + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); + return; +} + + +void +on_sipport_changed (GtkEditable *editable, + gpointer user_data) +{ + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); + return; +} + + +void +on_source_changed (GtkEditable *editable, + gpointer user_data) +{ + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); +} + +enum { + CODEC_ACTION_UP, + CODEC_ACTION_DOWN +}; + + +void codec_row_move(GtkTreeView *listview, int action) +{ + GtkTreeIter iter; + GtkTreeIter previter,nextiter,newiter; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreePath *treepath; + struct _PayloadType *codec=NULL; + gchar *name=NULL; + gint rate; + gfloat bitrate; + gchar *status=NULL; + gchar *color=NULL; + + selection=gtk_tree_view_get_selection(listview); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, CODEC_NAME,&name, + CODEC_RATE,&rate, + CODEC_BITRATE,&bitrate, + CODEC_STATUS,&status, + CODEC_PRIVDATA, &codec, + CODEC_COLOR,&color, + -1); + g_return_if_fail(codec!=NULL); + switch(action){ + case CODEC_ACTION_UP: + /* get an iterator on the prev codec */ + treepath=gtk_tree_model_get_path(model,&iter); + if (!gtk_tree_path_prev(treepath)){ + /* codec is the first, no match. */ + return; + } + gtk_tree_model_get_iter(model,&previter,treepath); + gtk_list_store_insert_before(GTK_LIST_STORE(model),&newiter,&previter); + break; + case CODEC_ACTION_DOWN: + /* get an iterator on the next codec */ + nextiter=iter; + if (!gtk_tree_model_iter_next(model,&nextiter)){ + /* codec is the last, no match. */ + return; + } + gtk_list_store_insert_after(GTK_LIST_STORE(model),&newiter,&nextiter); + + break; + } + gtk_list_store_set(GTK_LIST_STORE(model),&newiter, + CODEC_NAME,name, + CODEC_RATE,rate, + CODEC_BITRATE,bitrate, + CODEC_STATUS,status, + CODEC_PRIVDATA, codec, + CODEC_COLOR,color, + -1); + /* remove the selected line */ + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + gtk_tree_selection_select_iter(selection,&newiter); + g_free(name); + g_free(status); + g_free(color); + } +} + +static void codec_move(int action){ + GtkTreeView *listview; + int page=gtk_notebook_get_current_page(GTK_NOTEBOOK( + lookup_widget(get_property_box()->prop,"codec_notebook"))); + if (page==0) + listview=GTK_TREE_VIEW(get_property_box()->codec.au_codec_list); + else + listview=GTK_TREE_VIEW(lookup_widget(get_property_box()->prop,"vid_codec_list")); + codec_row_move(listview,action); + property_box_changed(); +} + +void +on_aucodec_up_clicked (GtkButton *button, + gpointer user_data) +{ + codec_move(CODEC_ACTION_UP); +} + + +void +on_aucodec_down_clicked (GtkButton *button, + gpointer user_data) +{ + codec_move(CODEC_ACTION_DOWN); +} + +void codec_set_status(GtkTreeView *listview,gboolean status) +{ + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + gchar *statusstring; + selection=gtk_tree_view_get_selection(listview); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + if (status) statusstring=_("Enabled"); + else statusstring=_("Disabled"); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_STATUS,statusstring,-1); + } +} + +void codec_list_update(GtkTreeView *listview) +{ + GtkTreeModel *model; + GtkTreeIter iter; + PayloadType *pt; + gchar *color; + gfloat bitrate; + model=gtk_tree_view_get_model(listview); + + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_PRIVDATA, &pt,-1); + if (linphone_core_check_payload_type_usability(get_core(),pt)){ + color="blue"; + }else color="red"; + bitrate=payload_type_get_bitrate(pt)/1000.0; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR,color,CODEC_BITRATE,bitrate,-1); + }while (gtk_tree_model_iter_next(model,&iter)); +} + +static void codec_enable(gboolean val){ + GtkTreeView *listview; + int page=gtk_notebook_get_current_page(GTK_NOTEBOOK( + lookup_widget(get_property_box()->prop,"codec_notebook"))); + if (page==0) + listview=GTK_TREE_VIEW(get_property_box()->codec.au_codec_list); + else + listview=GTK_TREE_VIEW(lookup_widget(get_property_box()->prop,"vid_codec_list")); + codec_set_status(listview,val); + property_box_changed(); +} + +void +on_aucodec_enable_clicked (GtkButton *button, + gpointer user_data) +{ + codec_enable(TRUE); +} + + +void +on_aucodec_disable_clicked (GtkButton *button, + gpointer user_data) +{ + codec_enable(FALSE); +} + + +void +on_user_name_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_domain_name_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + + +void +on_reg_passwd_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_obproxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_address_of_record_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_audio_jittcomp_value_changed (GtkRange *range, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_ringfileentry_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + +void linphone_property_box_uninit(LinphonePropertyBox *box) +{ + memset(box,0, sizeof(LinphonePropertyBox)); +} + + +gboolean +on_property_box_closed (GnomeDialog *gnomedialog, + gpointer user_data) +{ + linphone_property_box_uninit(get_property_box()); + return FALSE; +} + +void +on_use_sipinfo_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + linphone_core_set_use_info_for_dtmf(get_core(),gtk_toggle_button_get_active(togglebutton)); +} + + +void +on_guess_hostname_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + GtkWidget *hostname; + osip_from_t *from; + gboolean val=gtk_toggle_button_get_active(togglebutton); + linphone_core_set_guess_hostname(get_core(),val); + hostname=get_property_box()->sip.hostname; + from=linphone_core_get_primary_contact_parsed(get_core()); + gtk_entry_set_text(GTK_ENTRY(hostname),from->url->host); + gtk_widget_set_sensitive(hostname,!val); + osip_from_free(from); +} + +void +on_download_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + gdouble val=gtk_spin_button_get_value(spinbutton); + if (val==0) gtk_entry_set_text(GTK_ENTRY(spinbutton),_("Unlimited")); + linphone_core_set_download_bandwidth(get_core(),(int)val); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"au_codec_list"))); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"vid_codec_list"))); +} + +void +on_upload_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + gdouble val=gtk_spin_button_get_value(spinbutton); + if (val==0) gtk_entry_set_text(GTK_ENTRY(spinbutton),_("Unlimited")); + linphone_core_set_upload_bandwidth(get_core(),(int)val); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"au_codec_list"))); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"vid_codec_list"))); +} + +void +on_no_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_use_stun_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_static_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_stun_server_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + diff --git a/linphone/gnome/propertybox.h b/linphone/gnome/propertybox.h new file mode 100644 index 000000000..911c72ef7 --- /dev/null +++ b/linphone/gnome/propertybox.h @@ -0,0 +1,96 @@ +/*************************************************************************** + propertybox.h - description + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "interface.h" +#include + +struct _NetSection +{ + GtkWidget *interfaces; + gint if_sel; + GtkWidget *au_port; + GtkWidget *audio_jittcomp; + GtkWidget *enable_nat; + GtkWidget *nat_label; + GtkWidget *nat_address; + GtkWidget *use_sipinfo; + GtkWidget *enable_ipv6; +}; +typedef struct _NetSection NetSection; + +void net_section_init(NetSection *sec, GtkWidget *prop); +void net_section_apply(NetSection *sec, LinphoneCore *lp); + +struct _SipSection +{ + GtkWidget *port; + GtkWidget *username; + GtkWidget *hostname; + GtkWidget *proxy_list; + GtkWidget *guess_hostname; +}; + +typedef struct _SipSection SipSection; + +void sip_section_enable_registrar(SipSection *sec, LinphoneCore *lp, gboolean state); +void sip_section_fill(SipSection *sec, LinphoneCore *lp); + +void sip_section_init(SipSection *sec, GtkWidget *prop); +void sip_section_apply(SipSection *sec, LinphoneCore *lp); + +struct _CodecSection +{ + GtkWidget *au_codec_list; + GtkWidget *vi_codec_list; + GtkWidget *codec_info; +}; + +typedef struct _CodecSection CodecSection; + +void codec_section_init(CodecSection *sec, GtkWidget *prop); +void codec_section_apply(CodecSection *sec, LinphoneCore *lc); + +struct _SoundSection +{ + GtkWidget *source_entry; + GtkWidget *autokill_button; + GtkWidget *ringfileentry; + GtkWidget *ringpreview; +}; +typedef struct _SoundSection SoundSection; + +void sound_section_init(SoundSection *sec,GtkWidget *prop); +void sound_section_apply(SoundSection *sec, LinphoneCore *lc); + +struct _LinphonePropertyBox +{ + GtkWidget *prop; + NetSection net; + SipSection sip; + CodecSection codec; + SoundSection sound; +}; + +typedef struct _LinphonePropertyBox LinphonePropertyBox; + +void linphone_property_box_init(LinphonePropertyBox *box); +void linphone_property_box_apply(LinphonePropertyBox * box, LinphoneCore *lc, int page); +void linphone_property_box_uninit(LinphonePropertyBox *box); diff --git a/linphone/gnome/support.c b/linphone/gnome/support.c new file mode 100644 index 000000000..06a04b7dd --- /dev/null +++ b/linphone/gnome/support.c @@ -0,0 +1,115 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + GtkWidget *pixmap; + gchar *pathname; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP, + filename, TRUE, NULL); + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP, + filename, TRUE, NULL); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/linphone/gnome/support.h b/linphone/gnome/support.h new file mode 100644 index 000000000..2bec209a5 --- /dev/null +++ b/linphone/gnome/support.h @@ -0,0 +1,49 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#undef Q_ +#ifdef ENABLE_NLS +# define Q_(String) g_strip_context ((String), gettext (String)) +#else +# define Q_(String) g_strip_context ((String), (String)) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/linphone/gsmlib/.cvsignore b/linphone/gsmlib/.cvsignore new file mode 100644 index 000000000..05623353b --- /dev/null +++ b/linphone/gsmlib/.cvsignore @@ -0,0 +1,6 @@ +*.lo +.deps +.libs +Makefile +Makefile.in +libgsm.la diff --git a/linphone/gsmlib/COPYRIGHT b/linphone/gsmlib/COPYRIGHT new file mode 100644 index 000000000..eba0e523b --- /dev/null +++ b/linphone/gsmlib/COPYRIGHT @@ -0,0 +1,16 @@ +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universitaet Berlin +are deemed to have made any representations as to the suitability of this +software for any purpose nor are held responsible for any defects of +this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann diff --git a/linphone/gsmlib/ChangeLog b/linphone/gsmlib/ChangeLog new file mode 100644 index 000000000..4cf467d09 --- /dev/null +++ b/linphone/gsmlib/ChangeLog @@ -0,0 +1,80 @@ + +Fri Jul 5 19:26:37 1996 Jutta Degener (jutta@cs.tu-berlin.de) + + * Release 1.0 Patchlevel 10 + src/toast_alaw.c: exchanged A-law tables for something + slightly more A-law. + +Tue Jul 2 12:18:20 1996 Jutta Degener (jutta@cs.tu-berlin.de) + + * Release 1.0 Patchlevel 9 + src/long_term.c: in FLOAT_MUL mode, an array was accessed past its end + src/gsm_option.c: three options related to WAV #49 packing + src/gsm_encode.c: support WAV #49-style encoding. + src/gsm_decode.c: support WAV #49-style decoding. + tls/sour.c: generate the WAV bit shifting code, encode + tls/ginger.c: generate the WAV bit shifting code, decode + The WAV code goes back to an inofficial patch #8 that + Jeff Chilton sent us (hence the jump from 7 to 9). + src/toast.c: add _fsetmode() calls to set stdin/stdout to + binary (from an OS/2 port by Arnd Gronenberg.) + +Tue Mar 7 01:55:10 1995 Jutta Degener (jutta@cs.tu-berlin.de) + + * Release 1.0 Patchlevel 7 + src/long_term.c: Yet another 16-bit overflow + src/toast.c: -C option to toast, cuts LPC time + src/gsm_option.c: corresponding LPC_CUT option to GSM library + +Fri Dec 30 23:33:50 1994 Jutta Degener (jutta@cs.tu-berlin.de) + + * Release 1.0 Patchlevel 6 + src/lpc.c: fixed 16-bit addition overflow in Autocorrelation code + src/add.c: gsm_L_asl should fall back on gsm_L_asr, not gsm_asr + +Mon Nov 28 20:49:57 1994 Jutta Degener (jutta@cs.tu-berlin.de) + + * Release 1.0 Patchlevel 5 + src/toast_audio.c: initialization should return -1 on error + src/gsm_destroy.c: #include configuration header file + src/add.c: gsm_sub should cast its parameters to longword + man/*: bug reports to {jutta,cabo}@cs.tu-berlin.de, not to toast@tub + inc/private.h: longword long by default, not int + inc/toast.h: read/write fopen modes "rb" and "wb", not just "r" + src/toast.c: better (or different, anyway) error handling in process() + +Tue May 10 19:41:34 1994 Jutta Degener (jutta at kugelbus) + + * Release 1.0 Patchlevel 4 + inc/private.h: GSM_ADD should cast to ulongword, not to unsigned. + src/long_term.c: missing cast to longword. + add-test/add_test.c: Test macros too, not only functions, + thanks to Simao Ferraz de Campos Neto, simao@dragon.cpqd.ansp.br + General cleanup: remove unused variables, add function prototypes. + +Tue Jan 25 22:53:40 1994 Jutta Degener (jutta at kugelbus) + + * Release 1.0 Patchlevel 3 + changed rpe.c's STEP macro to work with 16-bit integers, + thanks to Dr Alex Lee (alexlee@solomon.technet.sg); + removed non-fatal bugs from add-test.dta, private.h + and toast_audio.c, thanks to P. Emanuelsson. + +Fri Jan 29 19:02:12 1993 Jutta Degener (jutta at kraftbus) + + * Release 1.0 Patchlevel 2 + fixed L_add(0,-1) in src/add.c and inc/private.h, + thanks to Raphael Trommer at AT&T Bell Laboratories; + various other ANSI C compatibility details + +Fri Oct 30 17:58:54 1992 Jutta Degener (jutta at kraftbus) + + * Release 1.0 Patchlevel 1 + Switched uid/gid in toast's [f]chown calls. + +Wed Oct 28 14:12:35 1992 Carsten Bormann (cabo at kubus) + + * Release 1.0: released + Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + Universitaet Berlin. See the accompanying file "COPYRIGHT" for + details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. diff --git a/linphone/gsmlib/ChangeLog.orig b/linphone/gsmlib/ChangeLog.orig new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/gsmlib/INSTALL b/linphone/gsmlib/INSTALL new file mode 100644 index 000000000..5850304f8 --- /dev/null +++ b/linphone/gsmlib/INSTALL @@ -0,0 +1,99 @@ +How to get started: + + Edit the Makefile. + + You should configure a few machine-dependencies and what + compiler you want to use. + + The code works both with ANSI and K&R-C. Use + -DNeedFunctionPrototypes to compile with, or + -UNeedFunctionPrototypes to compile without, function + prototypes in the header files. + + Make addtst + + The "add" program that will be compiled and run checks whether + the basic math functions of the gsm library work with your + compiler. If it prints anything to stderr, complain (to us). + + Edit inc/config.h. + + Make + + Local versions of the gsm library and the "compress"-like filters + toast, untoast and tcat will be generated. + + If the compilation aborts because of a missing function, + declaration, or header file, see if there's something in + inc/config.h to work around it. If not, complain. + + Try it + + Grab an audio file from somewhere (raw u-law or Sun .au is fine, + linear 16-bit in host byte order will do), copy it, toast it, + untoast it, and listen to the result. + + The GSM-encoded and -decoded audio should have the quality + of a good phone line. If the resulting audio is noisier than + your original, or if you hear compression artifacts, complain; + that's a bug in our software, not a bug in the GSM encoding + standard itself. + +Installation + + You can install the gsm library interface, or the toast binaries, + or both. + + Edit the Makefile + + Fill in the directories where you want to install the + library, header files, manual pages, and binaries. + + Turn off the installation of one half of the distribution + (i.e., gsm library or toast binaries) by not setting the + corresponding directory root Makefile macro. + + make install + + will install the programs "toast" with two links named + "tcat" and "untoast", and the gsm library "libgsm.a" with + a "gsm.h" header file, and their respective manual pages. + + +Optimizing + + This code was developed on a machine without an integer + multiplication instruction, where we obtained the fastest result by + replacing some of the integer multiplications with floating point + multiplications. + + If your machine does multiply integers fast enough, + leave USE_FLOAT_MUL undefined. The results should be the + same in both cases. + + On machines with fast floating point arithmetic, defining + both USE_FLOAT_MUL and FAST makes a run-time library + option available that will (in a few crucial places) use + ``native'' floating point operations rather than the bit-by-bit + defined ones of the GSM standard. If you use this fast + option, the outcome will not be bitwise identical to the + results prescribed by the standard, but it is compatible with + the standard encoding, and a user is unlikely to notice a + difference. + + +Bug Reports + + Please direct bug reports, questions, and comments to + jutta@cs.tu-berlin.de and cabo@informatik.uni-bremen.de. + + +Good luck, + + Jutta Degener, + Carsten Bormann + +-- +Copyright 1992, 1993, 1994, by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" +for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. diff --git a/linphone/gsmlib/MACHINES b/linphone/gsmlib/MACHINES new file mode 100644 index 000000000..4adafd24f --- /dev/null +++ b/linphone/gsmlib/MACHINES @@ -0,0 +1,11 @@ +The gsm library has been tested successfully on the following platforms: + +- Various Sun4's running SunOS 4.1.2 +- SPARC1 (SunOS 4.1.1) +- Integrated Solutions 68k Optimum running 4.3BSD UNIX with a Green Hills cc +- NeXTstation running NeXT-OS/Mach 3.0 +- No-name AT/386 with Xenix 2.3.2 (using -DSTUPID_COMPILER) +- RS/6000-350 running AIX 3.2.0 +- RS/6000-320 running AIX 3.1.5 +- Alliant FX80 (Concentrix 5.7) +- SGI Indigo XS4000 (IRIX 4.0.5F) diff --git a/linphone/gsmlib/MANIFEST b/linphone/gsmlib/MANIFEST new file mode 100644 index 000000000..6db3b2a3e --- /dev/null +++ b/linphone/gsmlib/MANIFEST @@ -0,0 +1,59 @@ +gsm-1.0/COPYRIGHT +gsm-1.0/ChangeLog +gsm-1.0/INSTALL +gsm-1.0/MACHINES +gsm-1.0/MANIFEST +gsm-1.0/Makefile +gsm-1.0/README +gsm-1.0/add-test/add_test.c +gsm-1.0/add-test/add_test.dta +gsm-1.0/inc/gsm.h +gsm-1.0/inc/proto.h +gsm-1.0/inc/unproto.h +gsm-1.0/inc/config.h +gsm-1.0/inc/private.h +gsm-1.0/inc/toast.h +gsm-1.0/man/bitter.1 +gsm-1.0/man/gsm.3 +gsm-1.0/man/gsm_explode.3 +gsm-1.0/man/gsm_print.3 +gsm-1.0/man/gsm_option.3 +gsm-1.0/man/toast.1 +gsm-1.0/src/add.c +gsm-1.0/src/code.c +gsm-1.0/src/debug.c +gsm-1.0/src/decode.c +gsm-1.0/src/gsm_destroy.c +gsm-1.0/src/gsm_decode.c +gsm-1.0/src/gsm_encode.c +gsm-1.0/src/gsm_explode.c +gsm-1.0/src/gsm_implode.c +gsm-1.0/src/gsm_create.c +gsm-1.0/src/gsm_print.c +gsm-1.0/src/gsm_option.c +gsm-1.0/src/long_term.c +gsm-1.0/src/lpc.c +gsm-1.0/src/preprocess.c +gsm-1.0/src/rpe.c +gsm-1.0/src/short_term.c +gsm-1.0/src/table.c +gsm-1.0/src/toast.c +gsm-1.0/src/toast_alaw.c +gsm-1.0/src/toast_audio.c +gsm-1.0/src/toast_lin.c +gsm-1.0/src/toast_ulaw.c +gsm-1.0/tls/bitter.c +gsm-1.0/tls/bitter.dta +gsm-1.0/tls/taste.c +gsm-1.0/tls/taste.h +gsm-1.0/tls/sweet.c +gsm-1.0/tls/sour.c +gsm-1.0/tls/sour1.dta +gsm-1.0/tls/sour2.dta +gsm-1.0/tls/ginger.c +gsm-1.0/tst/cod2lin.c +gsm-1.0/tst/cod2txt.c +gsm-1.0/tst/gsm2cod.c +gsm-1.0/tst/lin2cod.c +gsm-1.0/tst/lin2txt.c +gsm-1.0/tst/run diff --git a/linphone/gsmlib/Makefile.am b/linphone/gsmlib/Makefile.am new file mode 100644 index 000000000..01b5cfd73 --- /dev/null +++ b/linphone/gsmlib/Makefile.am @@ -0,0 +1,26 @@ + +EXTRA_DIST= ChangeLog INSTALL MACHINES MANIFEST README COPYRIGHT + +noinst_LTLIBRARIES= libgsm.la + +libgsm_la_SOURCES= gsmadd.c proto.h unproto.h config.h private.h gsm.h toast.h \ + code.c proto.h unproto.h config.h private.h gsm.h toast.h \ + debug.c proto.h unproto.h config.h private.h gsm.h toast.h \ + decode.c proto.h unproto.h config.h private.h gsm.h toast.h \ + long_term.c proto.h unproto.h config.h private.h gsm.h toast.h \ + lpc.c proto.h unproto.h config.h private.h gsm.h toast.h \ + preprocess.c proto.h unproto.h config.h private.h gsm.h toast.h \ + rpe.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_destroy.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_decode.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_encode.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_explode.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_implode.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_create.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_print.c proto.h unproto.h config.h private.h gsm.h toast.h \ + gsm_option.c proto.h unproto.h config.h private.h gsm.h toast.h \ + short_term.c proto.h unproto.h config.h private.h gsm.h toast.h \ + table.c proto.h unproto.h config.h private.h gsm.h toast.h + + +AM_CFLAGS=-w diff --git a/linphone/gsmlib/README b/linphone/gsmlib/README new file mode 100644 index 000000000..cb6af85cf --- /dev/null +++ b/linphone/gsmlib/README @@ -0,0 +1,37 @@ + +GSM 06.10 13 kbit/s RPE/LTP speech compression available +-------------------------------------------------------- + +The Communications and Operating Systems Research Group (KBS) at the +Technische Universitaet Berlin is currently working on a set of +UNIX-based tools for computer-mediated telecooperation that will be +made freely available. + +As part of this effort we are publishing an implementation of the +European GSM 06.10 provisional standard for full-rate speech +transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse +excitation/long term prediction) coding at 13 kbit/s. + +GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling +rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility +with typical UNIX applications, our implementation turns frames of 160 +16-bit linear samples into 33-byte frames (1650 Bytes/s). +The quality of the algorithm is good enough for reliable speaker +recognition; even music often survives transcoding in recognizable +form (given the bandwidth limitations of 8 kHz sampling rate). + +The interfaces offered are a front end modelled after compress(1), and +a library API. Compression and decompression run faster than realtime +on most SPARCstations. The implementation has been verified against the +ETSI standard test patterns. + +Jutta Degener (jutta@cs.tu-berlin.de) +Carsten Bormann (cabo@cs.tu-berlin.de) + +Communications and Operating Systems Research Group, TU Berlin +Fax: +49.30.31425156, Phone: +49.30.31424315 + +-- +Copyright 1992 by Jutta Degener and Carsten Bormann, Technische +Universitaet Berlin. See the accompanying file "COPYRIGHT" for +details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. diff --git a/linphone/gsmlib/code.c b/linphone/gsmlib/code.c new file mode 100644 index 000000000..a6003da04 --- /dev/null +++ b/linphone/gsmlib/code.c @@ -0,0 +1,99 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/code.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include "config.h" + + +#ifdef HAS_STDLIB_H +#include +#else +# include "proto.h" + extern char * memcpy P((char *, char *, int)); +#endif + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +/* + * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER + */ + +void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc), + + struct gsm_state * S, + + word * s, /* [0..159] samples IN */ + +/* + * The RPE-LTD coder works on a frame by frame basis. The length of + * the frame is equal to 160 samples. Some computations are done + * once per frame to produce at the output of the coder the + * LARc[1..8] parameters which are the coded LAR coefficients and + * also to realize the inverse filtering operation for the entire + * frame (160 samples of signal d[0..159]). These parts produce at + * the output of the coder: + */ + + word * LARc, /* [0..7] LAR coefficients OUT */ + +/* + * Procedure 4.2.11 to 4.2.18 are to be executed four times per + * frame. That means once for each sub-segment RPE-LTP analysis of + * 40 samples. These parts produce at the output of the coder: + */ + + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */ +) +{ + int k; + word * dp = S->dp0 + 120; /* [ -120...-1 ] */ + word * dpp = dp; /* [ 0...39 ] */ + + static word e[50]; + + word so[160]; + + Gsm_Preprocess (S, s, so); + Gsm_LPC_Analysis (S, so, LARc); + Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + for (k = 0; k <= 3; k++, xMc += 13) { + + Gsm_Long_Term_Predictor ( S, + so+k*40, /* d [0..39] IN */ + dp, /* dp [-120..-1] IN */ + e + 5, /* e [0..39] OUT */ + dpp, /* dpp [0..39] OUT */ + Nc++, + bc++); + + Gsm_RPE_Encoding ( S, + e + 5, /* e ][0..39][ IN/OUT */ + xmaxc++, Mc++, xMc ); + /* + * Gsm_Update_of_reconstructed_short_time_residual_signal + * ( dpp, e + 5, dp ); + */ + + { register int i; + register longword ltmp; + for (i = 0; i <= 39; i++) + dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); + } + dp += 40; + dpp += 40; + + } + (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), + 120 * sizeof(*S->dp0) ); +} diff --git a/linphone/gsmlib/config.h b/linphone/gsmlib/config.h new file mode 100644 index 000000000..d5f9a13ac --- /dev/null +++ b/linphone/gsmlib/config.h @@ -0,0 +1,37 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /sources/linphone/linphone/gsmlib/config.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $*/ + +#ifndef CONFIG_H +#define CONFIG_H + +/*efine SIGHANDLER_T int /* signal handlers are void */ +/*efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */ + +#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ +/*efine HAS_LIMITS_H 1 /* /usr/include/limits.h */ +#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ +/*efine HAS_ERRNO_DECL 1 /* errno.h declares errno */ + +#define HAS_FSTAT 1 /* fstat syscall */ +#define HAS_FCHMOD 1 /* fchmod syscall */ +#define HAS_CHMOD 1 /* chmod syscall */ +#define HAS_FCHOWN 1 /* fchown syscall */ +#define HAS_CHOWN 1 /* chown syscall */ +/*efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */ + +#define HAS_STRING_H 1 /* /usr/include/string.h */ +/*efine HAS_STRINGS_H 1 /* /usr/include/strings.h */ + +#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ +#define HAS_UTIME 1 /* POSIX utime(path, times) */ +/*efine HAS_UTIMES 1 /* use utimes() syscall instead */ +#define HAS_UTIME_H 1 /* UTIME header file */ +/*efine HAS_UTIMBUF 1 /* struct utimbuf */ +/*efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */ + +#endif /* CONFIG_H */ diff --git a/linphone/gsmlib/debug.c b/linphone/gsmlib/debug.c new file mode 100644 index 000000000..d4b820d23 --- /dev/null +++ b/linphone/gsmlib/debug.c @@ -0,0 +1,76 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/debug.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include "private.h" + +#ifndef NDEBUG + +/* If NDEBUG _is_ defined and no debugging should be performed, + * calls to functions in this module are #defined to nothing + * in private.h. + */ + +#include +#include "proto.h" + +void gsm_debug_words P4( (name, from, to, ptr), + char * name, + int from, + int to, + word * ptr) +{ + int nprinted = 0; + + fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); + while (from <= to) { + fprintf(stderr, "%d ", ptr[ from ] ); + from++; + if (nprinted++ >= 7) { + nprinted = 0; + if (from < to) putc('\n', stderr); + } + } + putc('\n', stderr); +} + +void gsm_debug_longwords P4( (name, from, to, ptr), + char * name, + int from, + int to, + longword * ptr) +{ + int nprinted = 0; + + fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); + while (from <= to) { + + fprintf(stderr, "%d ", ptr[ from ] ); + from++; + if (nprinted++ >= 7) { + nprinted = 0; + if (from < to) putc('\n', stderr); + } + } + putc('\n', stderr); +} + +void gsm_debug_longword P2( (name, value), + char * name, + longword value ) +{ + fprintf(stderr, "%s: %d\n", name, (long)value ); +} + +void gsm_debug_word P2( (name, value), + char * name, + word value ) +{ + fprintf(stderr, "%s: %d\n", name, (long)value); +} + +#endif diff --git a/linphone/gsmlib/decode.c b/linphone/gsmlib/decode.c new file mode 100644 index 000000000..fa4a3068f --- /dev/null +++ b/linphone/gsmlib/decode.c @@ -0,0 +1,63 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/decode.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +/* + * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER + */ + +static void Postprocessing P2((S,s), + struct gsm_state * S, + register word * s) +{ + register int k; + register word msr = S->msr; + register longword ltmp; /* for GSM_ADD */ + register word tmp; + + for (k = 160; k--; s++) { + tmp = GSM_MULT_R( msr, 28180 ); + msr = GSM_ADD(*s, tmp); /* Deemphasis */ + *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ + } + S->msr = msr; +} + +void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), + struct gsm_state * S, + + word * LARcr, /* [0..7] IN */ + + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + + word * s) /* [0..159] OUT */ +{ + int j, k; + word erp[40], wt[160]; + word * drp = S->dp0 + 120; + + for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { + + Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); + Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; + } + + Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); + Postprocessing(S, s); +} diff --git a/linphone/gsmlib/gsm.h b/linphone/gsmlib/gsm.h new file mode 100644 index 000000000..78e7f82c1 --- /dev/null +++ b/linphone/gsmlib/gsm.h @@ -0,0 +1,96 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /sources/linphone/linphone/gsmlib/gsm.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $*/ + +#ifndef GSM_H +#define GSM_H + +#ifdef __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#ifdef NeedFunctionPrototypes +# include /* for FILE * */ +#endif + +#undef GSM_P +#if NeedFunctionPrototypes +# define GSM_P( protos ) protos +#else +# define GSM_P( protos ) ( /* protos */ ) +#endif + +/* + * Interface +vocoders.h" */ + + +typedef struct gsm_state * gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#define GSM_PATCHLEVEL 10 +#define GSM_MINOR 0 +#define GSM_MAJOR 1 + +#define GSM_OPT_VERBOSE 1 +#define GSM_OPT_FAST 2 +#define GSM_OPT_LTP_CUT 3 +#define GSM_OPT_WAV49 4 +#define GSM_OPT_FRAME_INDEX 5 +#define GSM_OPT_FRAME_CHAIN 6 + +#ifndef __cplusplus + +extern gsm gsm_create GSM_P((void)); +extern void gsm_destroy GSM_P((gsm)); + +extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); +extern int gsm_option GSM_P((gsm, int, int *)); + +extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); +extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); + +extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); +extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); +#else +extern "C" +{ +gsm gsm_create GSM_P((void)); +void gsm_destroy GSM_P((gsm)); + +int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); +int gsm_option GSM_P((gsm, int, int *)); + +void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); +int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); + +int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); +void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); +} + + + + +#endif + + + +#undef GSM_P + +#endif /* GSM_H */ diff --git a/linphone/gsmlib/gsm_create.c b/linphone/gsmlib/gsm_create.c new file mode 100644 index 000000000..b3e6bb13e --- /dev/null +++ b/linphone/gsmlib/gsm_create.c @@ -0,0 +1,45 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +static char const ident[] = "$Header: /sources/linphone/linphone/gsmlib/gsm_create.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $"; + +#include "config.h" + +#ifdef HAS_STRING_H +#include +#else +# include "proto.h" + extern char * memset P((char *, int, int)); +#endif + +#ifdef HAS_STDLIB_H +# include +#else +# ifdef HAS_MALLOC_H +# include +# else + extern char * malloc(); +# endif +#endif + +#include + +#include "gsm.h" +#include "private.h" +#include "proto.h" + +gsm gsm_create P0() +{ + gsm r; + + r = (gsm)malloc(sizeof(struct gsm_state)); + if (!r) return r; + + memset((char *)r, 0, sizeof(*r)); + r->nrp = 40; + + return r; +} diff --git a/linphone/gsmlib/gsm_decode.c b/linphone/gsmlib/gsm_decode.c new file mode 100644 index 000000000..928de7d56 --- /dev/null +++ b/linphone/gsmlib/gsm_decode.c @@ -0,0 +1,361 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_decode.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + + s->frame_index = !s->frame_index; + if (s->frame_index) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + Nc[0] = (*c >> 1) & 0x7F; + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + Mc[0] = (*c >> 5) & 0x3; + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + Nc[1] = (*c >> 1) & 0x7F; + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + Mc[1] = (*c >> 5) & 0x3; + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + Nc[2] = (*c >> 1) & 0x7F; + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + Mc[2] = (*c >> 5) & 0x3; + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + Nc[3] = (*c >> 1) & 0x7F; + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + Mc[3] = (*c >> 5) & 0x3; + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + } + + Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); + + return 0; +} diff --git a/linphone/gsmlib/gsm_destroy.c b/linphone/gsmlib/gsm_destroy.c new file mode 100644 index 000000000..e8bc33e63 --- /dev/null +++ b/linphone/gsmlib/gsm_destroy.c @@ -0,0 +1,26 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_destroy.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "gsm.h" +#include "config.h" +#include "proto.h" + +#ifdef HAS_STDLIB_H +# include +#else +# ifdef HAS_MALLOC_H +# include +# else + extern void free(); +# endif +#endif + +void gsm_destroy P1((S), gsm S) +{ + if (S) free((char *)S); +} diff --git a/linphone/gsmlib/gsm_encode.c b/linphone/gsmlib/gsm_encode.c new file mode 100644 index 000000000..0c55ee0aa --- /dev/null +++ b/linphone/gsmlib/gsm_encode.c @@ -0,0 +1,451 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_encode.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + + /* variable size + + GSM_MAGIC 4 + + LARc[0] 6 + LARc[1] 6 + LARc[2] 5 + LARc[3] 5 + LARc[4] 4 + LARc[5] 4 + LARc[6] 3 + LARc[7] 3 + + Nc[0] 7 + bc[0] 2 + Mc[0] 2 + xmaxc[0] 6 + xmc[0] 3 + xmc[1] 3 + xmc[2] 3 + xmc[3] 3 + xmc[4] 3 + xmc[5] 3 + xmc[6] 3 + xmc[7] 3 + xmc[8] 3 + xmc[9] 3 + xmc[10] 3 + xmc[11] 3 + xmc[12] 3 + + Nc[1] 7 + bc[1] 2 + Mc[1] 2 + xmaxc[1] 6 + xmc[13] 3 + xmc[14] 3 + xmc[15] 3 + xmc[16] 3 + xmc[17] 3 + xmc[18] 3 + xmc[19] 3 + xmc[20] 3 + xmc[21] 3 + xmc[22] 3 + xmc[23] 3 + xmc[24] 3 + xmc[25] 3 + + Nc[2] 7 + bc[2] 2 + Mc[2] 2 + xmaxc[2] 6 + xmc[26] 3 + xmc[27] 3 + xmc[28] 3 + xmc[29] 3 + xmc[30] 3 + xmc[31] 3 + xmc[32] 3 + xmc[33] 3 + xmc[34] 3 + xmc[35] 3 + xmc[36] 3 + xmc[37] 3 + xmc[38] 3 + + Nc[3] 7 + bc[3] 2 + Mc[3] 2 + xmaxc[3] 6 + xmc[39] 3 + xmc[40] 3 + xmc[41] 3 + xmc[42] 3 + xmc[43] 3 + xmc[44] 3 + xmc[45] 3 + xmc[46] 3 + xmc[47] 3 + xmc[48] 3 + xmc[49] 3 + xmc[50] 3 + xmc[51] 3 + */ + +#ifdef WAV49 + + if (s->wav_fmt) { + s->frame_index = !s->frame_index; + if (s->frame_index) { + + uword sr; + + sr = 0; + sr = sr >> 6 | LARc[0] << 10; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 4; + sr = sr >> 5 | LARc[2] << 11; + *c++ = sr >> 7; + sr = sr >> 5 | LARc[3] << 11; + sr = sr >> 4 | LARc[4] << 12; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[5] << 12; + sr = sr >> 3 | LARc[6] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | LARc[7] << 13; + sr = sr >> 7 | Nc[0] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[0] << 14; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[0] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + sr = sr >> 3 | xmc[3] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[4] << 13; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[7] << 13; + sr = sr >> 3 | xmc[8] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + sr = sr >> 3 | xmc[11] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[12] << 13; + sr = sr >> 7 | Nc[1] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[1] << 14; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[13] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + sr = sr >> 3 | xmc[16] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[17] << 13; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[20] << 13; + sr = sr >> 3 | xmc[21] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + sr = sr >> 3 | xmc[24] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[25] << 13; + sr = sr >> 7 | Nc[2] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[2] << 14; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[26] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + sr = sr >> 3 | xmc[29] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[30] << 13; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[33] << 13; + sr = sr >> 3 | xmc[34] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + sr = sr >> 3 | xmc[37] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[38] << 13; + sr = sr >> 7 | Nc[3] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[3] << 14; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[39] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + sr = sr >> 3 | xmc[42] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[43] << 13; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[46] << 13; + sr = sr >> 3 | xmc[47] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + sr = sr >> 3 | xmc[50] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[51] << 13; + sr = sr >> 4; + *c = sr >> 8; + s->frame_chain = *c; + } + else { + uword sr; + + sr = 0; + sr = sr >> 4 | s->frame_chain << 12; + sr = sr >> 6 | LARc[0] << 10; + *c++ = sr >> 6; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 8; + sr = sr >> 5 | LARc[2] << 11; + sr = sr >> 5 | LARc[3] << 11; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[4] << 12; + sr = sr >> 4 | LARc[5] << 12; + *c++ = sr >> 6; + sr = sr >> 3 | LARc[6] << 13; + sr = sr >> 3 | LARc[7] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[0] << 9; + sr = sr >> 2 | bc[0] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[0] << 13; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[3] << 13; + sr = sr >> 3 | xmc[4] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + sr = sr >> 3 | xmc[7] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[8] << 13; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[11] << 13; + sr = sr >> 3 | xmc[12] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[1] << 9; + sr = sr >> 2 | bc[1] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[13] << 13; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[16] << 13; + sr = sr >> 3 | xmc[17] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + sr = sr >> 3 | xmc[20] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[21] << 13; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[24] << 13; + sr = sr >> 3 | xmc[25] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[2] << 9; + sr = sr >> 2 | bc[2] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[26] << 13; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[29] << 13; + sr = sr >> 3 | xmc[30] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + sr = sr >> 3 | xmc[33] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[34] << 13; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[37] << 13; + sr = sr >> 3 | xmc[38] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[3] << 9; + sr = sr >> 2 | bc[3] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[39] << 13; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[42] << 13; + sr = sr >> 3 | xmc[43] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + sr = sr >> 3 | xmc[46] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[47] << 13; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[50] << 13; + sr = sr >> 3 | xmc[51] << 13; + *c++ = sr >> 8; + } + } + + else + +#endif /* WAV49 */ + { + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + *c++ = ((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + *c++ = ((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + *c++ = ((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + + } +} diff --git a/linphone/gsmlib/gsm_explode.c b/linphone/gsmlib/gsm_explode.c new file mode 100644 index 000000000..b7c98ed5a --- /dev/null +++ b/linphone/gsmlib/gsm_explode.c @@ -0,0 +1,417 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_explode.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) +{ +# define LARc target +# define Nc *((gsm_signal (*) [17])(target + 8)) +# define bc *((gsm_signal (*) [17])(target + 9)) +# define Mc *((gsm_signal (*) [17])(target + 10)) +# define xmaxc *((gsm_signal (*) [17])(target + 11)) + + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + + if (s->frame_index == 1) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 12) + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; + +#undef xmc +#define xmc (target + 46 - 26) + + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 12) + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; + +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + + Nc[0] = (*c >> 1) & 0x7F; + + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + + Mc[0] = (*c >> 5) & 0x3; + + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 12) + + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + + Nc[1] = (*c >> 1) & 0x7F; + + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + + Mc[1] = (*c >> 5) & 0x3; + + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + + Nc[2] = (*c >> 1) & 0x7F; + + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + + Mc[2] = (*c >> 5) & 0x3; + + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 46 - 26) + + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + + Nc[3] = (*c >> 1) & 0x7F; + + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + + Mc[3] = (*c >> 5) & 0x3; + + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + } + + return 0; +} diff --git a/linphone/gsmlib/gsm_implode.c b/linphone/gsmlib/gsm_implode.c new file mode 100644 index 000000000..e2c9d1c72 --- /dev/null +++ b/linphone/gsmlib/gsm_implode.c @@ -0,0 +1,515 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_implode.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) +{ + /* variable size index + + GSM_MAGIC 4 - + + LARc[0] 6 0 + LARc[1] 6 1 + LARc[2] 5 2 + LARc[3] 5 3 + LARc[4] 4 4 + LARc[5] 4 5 + LARc[6] 3 6 + LARc[7] 3 7 + + Nc[0] 7 8 + bc[0] 2 9 + Mc[0] 2 10 + xmaxc[0] 6 11 + xmc[0] 3 12 + xmc[1] 3 13 + xmc[2] 3 14 + xmc[3] 3 15 + xmc[4] 3 16 + xmc[5] 3 17 + xmc[6] 3 18 + xmc[7] 3 19 + xmc[8] 3 20 + xmc[9] 3 21 + xmc[10] 3 22 + xmc[11] 3 23 + xmc[12] 3 24 + + Nc[1] 7 25 + bc[1] 2 26 + Mc[1] 2 27 + xmaxc[1] 6 28 + xmc[13] 3 29 + xmc[14] 3 30 + xmc[15] 3 31 + xmc[16] 3 32 + xmc[17] 3 33 + xmc[18] 3 34 + xmc[19] 3 35 + xmc[20] 3 36 + xmc[21] 3 37 + xmc[22] 3 38 + xmc[23] 3 39 + xmc[24] 3 40 + xmc[25] 3 41 + + Nc[2] 7 42 + bc[2] 2 43 + Mc[2] 2 44 + xmaxc[2] 6 45 + xmc[26] 3 46 + xmc[27] 3 47 + xmc[28] 3 48 + xmc[29] 3 49 + xmc[30] 3 50 + xmc[31] 3 51 + xmc[32] 3 52 + xmc[33] 3 53 + xmc[34] 3 54 + xmc[35] 3 55 + xmc[36] 3 56 + xmc[37] 3 57 + xmc[38] 3 58 + + Nc[3] 7 59 + bc[3] 2 60 + Mc[3] 2 61 + xmaxc[3] 6 62 + xmc[39] 3 63 + xmc[40] 3 64 + xmc[41] 3 65 + xmc[42] 3 66 + xmc[43] 3 67 + xmc[44] 3 68 + xmc[45] 3 69 + xmc[46] 3 70 + xmc[47] 3 71 + xmc[48] 3 72 + xmc[49] 3 73 + xmc[50] 3 74 + xmc[51] 3 75 + */ + + /* There are 76 parameters per frame. The first eight are + * unique. The remaining 68 are four identical subframes of + * 17 parameters each. gsm_implode converts from a representation + * of these parameters as values in one array of signed words + * to the "packed" version of a GSM frame. + */ + +# define LARc source +# define Nc *((gsm_signal (*) [17])(source + 8)) +# define bc *((gsm_signal (*) [17])(source + 9)) +# define Mc *((gsm_signal (*) [17])(source + 10)) +# define xmaxc *((gsm_signal (*) [17])(source + 11)) + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + if (s->frame_index == 0) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 12) + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 29 - 13) + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 12) + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 29 - 13) + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + + + *c++ = ((Nc[0] & 0x7F) << 1) + + + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + + + | ((Mc[0] & 0x3) << 5) + + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + +#undef xmc +#define xmc (source + 12) + + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + + + *c++ = ((Nc[1] & 0x7F) << 1) + + + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + + + | ((Mc[1] & 0x3) << 5) + + + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + +#undef xmc +#define xmc (source + 29 - 13) + + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + + + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + + + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + + + | ((Mc[2] & 0x3) << 5) + + + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + +#undef xmc +#define xmc (source + 46 - 26) + + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + + + *c++ = ((Nc[3] & 0x7F) << 1) + + + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + + + | ((Mc[3] & 0x3) << 5) + + + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + +#undef xmc +#define xmc (source + 63 - 39) + + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + } +} diff --git a/linphone/gsmlib/gsm_option.c b/linphone/gsmlib/gsm_option.c new file mode 100644 index 000000000..17a174a32 --- /dev/null +++ b/linphone/gsmlib/gsm_option.c @@ -0,0 +1,69 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_option.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_option P3((r, opt, val), gsm r, int opt, int * val) +{ + int result = -1; + + switch (opt) { + case GSM_OPT_LTP_CUT: +#ifdef LTP_CUT + result = r->ltp_cut; + if (val) r->ltp_cut = *val; +#endif + break; + + case GSM_OPT_VERBOSE: +#ifndef NDEBUG + result = r->verbose; + if (val) r->verbose = *val; +#endif + break; + + case GSM_OPT_FAST: + +#if defined(FAST) && defined(USE_FLOAT_MUL) + result = r->fast; + if (val) r->fast = !!*val; +#endif + break; + + case GSM_OPT_FRAME_CHAIN: + +#ifdef WAV49 + result = r->frame_chain; + if (val) r->frame_chain = *val; +#endif + break; + + case GSM_OPT_FRAME_INDEX: + +#ifdef WAV49 + result = r->frame_index; + if (val) r->frame_index = *val; +#endif + break; + + case GSM_OPT_WAV49: + +#ifdef WAV49 + result = r->wav_fmt; + if (val) r->wav_fmt = !!*val; +#endif + break; + + default: + break; + } + return result; +} diff --git a/linphone/gsmlib/gsm_print.c b/linphone/gsmlib/gsm_print.c new file mode 100644 index 000000000..bdd467911 --- /dev/null +++ b/linphone/gsmlib/gsm_print.c @@ -0,0 +1,167 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsm_print.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + + + Nc[0] = (*c >> 1) & 0x7F; + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + Mc[0] = (*c >> 5) & 0x3; + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + + Nc[1] = (*c >> 1) & 0x7F; + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + Mc[1] = (*c >> 5) & 0x3; + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + + + Nc[2] = (*c >> 1) & 0x7F; + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + Mc[2] = (*c >> 5) & 0x3; + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + + Nc[3] = (*c >> 1) & 0x7F; + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + Mc[3] = (*c >> 5) & 0x3; + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + + fprintf(f, + "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n", + LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]); + + fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[0], bc[0], Mc[0], xmaxc[0]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6], + xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] ); + + fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[1], bc[1], Mc[1], xmaxc[1]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5], + xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11], + xmc[13+12] ); + + fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[2], bc[2], Mc[2], xmaxc[2]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5], + xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11], + xmc[26+12] ); + + fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[3], bc[3], Mc[3], xmaxc[3]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5], + xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11], + xmc[39+12] ); + + return 0; +} diff --git a/linphone/gsmlib/gsm_wrapper.c b/linphone/gsmlib/gsm_wrapper.c new file mode 100644 index 000000000..1179080e3 --- /dev/null +++ b/linphone/gsmlib/gsm_wrapper.c @@ -0,0 +1,67 @@ +#include "gsm_wrapper.h" +#include + +/* the following code has been added by Simon MORLAT to make GSM interface compatible with linphone*/ + +/* the public codec_info structure*/ + +struct codec_info gsm_codec_info= +{ + "GSM", + 160*2, /* size of the uncompressed frame*/ + 33, /* size of compressed frame*/ + 13000, /* bit rate*/ + {{ + 8000 + }}, /* audio sampling freq*/ + GSMcodec_new, /* codec constructor*/ + 3, /* payload type*/ + "gsm/8000/1", + CODEC_AUDIO, /* type*/ + 0, /*usable, set later*/ + 1 /*usable for user, default value*/ +}; + + +Codec *GSMcodec_new() +{ + GSMCodec *obj; + + obj=(GSMCodec*)malloc(sizeof(GSMCodec));/* we should make a few check to see if this codec is a GSM...*/ + + obj->baseclass._getinfo=&wgsm_getinfo; + obj->baseclass._encode=&wgsm_encode; + obj->baseclass._decode=&wgsm_decode; + obj->baseclass._destroy=&wgsm_destroy; + obj->gsm_enc=gsm_create(); + obj->gsm_dec=gsm_create(); + return((Codec*)obj); +} + + +void wgsm_getinfo(Codec *codec,struct codec_info *info) +{ + if (info==NULL) return; + memcpy(info,&gsm_codec_info,sizeof(codec_info_t)); +} + +void wgsm_encode(Codec *codec,char *frame, char *data) +{ + GSMCodec *obj=(GSMCodec*)codec; /* we should make a few check to see if this codec is a GSM...*/ + gsm_encode(obj->gsm_enc,(gsm_signal*)frame,data); +} + +void wgsm_decode(Codec *codec,char *data, char *frame) +{ + GSMCodec *obj=(GSMCodec*)codec; /* we should make a few check to see if this codec is a GSM...*/ + gsm_decode(obj->gsm_dec,data,(gsm_signal*)frame); +} + +void wgsm_destroy(Codec *codec) +{ + GSMCodec *obj=(GSMCodec*)codec; /* we should make a few check to see if this codec is a GSM...*/ + gsm_destroy(obj->gsm_enc); + gsm_destroy(obj->gsm_dec); + free(obj); +} + diff --git a/linphone/gsmlib/gsm_wrapper.h b/linphone/gsmlib/gsm_wrapper.h new file mode 100644 index 000000000..8fc9d4f09 --- /dev/null +++ b/linphone/gsmlib/gsm_wrapper.h @@ -0,0 +1,28 @@ +#ifndef GSM_WRAPPER +#define GSM_WRAPPER + +#include "../console/codec.h" +#include "gsm.h" + +/* the following code has been added by Simon MORLAT to make lpc10 interface compatible with linphone*/ + +/*Class definition*/ +typedef struct _GSMCodec +{ + Codec baseclass; /* Codec must be the first element of the structure in order to have the object mechanism to work*/ + gsm gsm_enc,gsm_dec; +} GSMCodec; + +/* this the constructor for derivate class GSMCodec*/ +Codec * GSMcodec_new(); + +extern struct codec_info gsm_codec_info; + +/* these are the overrides for the base class 's functions*/ +void wgsm_getinfo(Codec *codec, struct codec_info *info); +void wgsm_encode(Codec *codec, char *frame, char *data); +void wgsm_decode(Codec *codec, char *data, char *frame); +void wgsm_destroy(Codec *codec); + + +#endif diff --git a/linphone/gsmlib/gsmadd.c b/linphone/gsmlib/gsmadd.c new file mode 100644 index 000000000..ddf1516f0 --- /dev/null +++ b/linphone/gsmlib/gsmadd.c @@ -0,0 +1,235 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/gsmadd.c,v 1.1 2005/03/09 17:26:29 smorlat Exp $ */ + +/* + * See private.h for the more commonly used macro versions. + */ + +#include +#include + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +word gsm_add P2((a,b), word a, word b) +{ + longword sum = (longword)a + (longword)b; + return saturate(sum); +} + +word gsm_sub P2((a,b), word a, word b) +{ + longword diff = (longword)a - (longword)b; + return saturate(diff); +} + +word gsm_mult P2((a,b), word a, word b) +{ + if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; + else return SASR( (longword)a * (longword)b, 15 ); +} + +word gsm_mult_r P2((a,b), word a, word b) +{ + if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; + else { + longword prod = (longword)a * (longword)b + 16384; + prod >>= 15; + return prod & 0xFFFF; + } +} + +word gsm_abs P1((a), word a) +{ + return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; +} + +longword gsm_L_mult P2((a,b),word a, word b) +{ + assert( a != MIN_WORD || b != MIN_WORD ); + return ((longword)a * (longword)b) << 1; +} + +longword gsm_L_add P2((a,b), longword a, longword b) +{ + if (a < 0) { + if (b >= 0) return a + b; + else { + ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); + return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; + } + } + else if (b <= 0) return a + b; + else { + ulongword A = (ulongword)a + (ulongword)b; + return A > MAX_LONGWORD ? MAX_LONGWORD : A; + } +} + +longword gsm_L_sub P2((a,b), longword a, longword b) +{ + if (a >= 0) { + if (b >= 0) return a - b; + else { + /* a>=0, b<0 */ + + ulongword A = (ulongword)a + -(b + 1); + return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); + } + } + else if (b <= 0) return a - b; + else { + /* a<0, b>0 */ + + ulongword A = (ulongword)-(a + 1) + b; + return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; + } +} + +static unsigned char const bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +word gsm_norm P1((a), longword a ) +/* + * the number of left shifts needed to normalize the 32 bit + * variable L_var1 for positive values on the interval + * + * with minimum of + * minimum of 1073741824 (01000000000000000000000000000000) and + * maximum of 2147483647 (01111111111111111111111111111111) + * + * + * and for negative values on the interval with + * minimum of -2147483648 (-10000000000000000000000000000000) and + * maximum of -1073741824 ( -1000000000000000000000000000000). + * + * in order to normalize the result, the following + * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); + * + * (That's 'ffs', only from the left, not the right..) + */ +{ + assert(a != 0); + + if (a < 0) { + if (a <= -1073741824) return 0; + a = ~a; + } + + return a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + bitoff[ 0xFF & (a >> 24) ] + : 7 + bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + bitoff[ 0xFF & (a >> 8) ] + : 23 + bitoff[ 0xFF & a ] ); +} + +longword gsm_L_asl P2((a,n), longword a, int n) +{ + if (n >= 32) return 0; + if (n <= -32) return -(a < 0); + if (n < 0) return gsm_L_asr(a, -n); + return a << n; +} + +word gsm_asl P2((a,n), word a, int n) +{ + if (n >= 16) return 0; + if (n <= -16) return -(a < 0); + if (n < 0) return gsm_asr(a, -n); + return a << n; +} + +longword gsm_L_asr P2((a,n), longword a, int n) +{ + if (n >= 32) return -(a < 0); + if (n <= -32) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(longword)( -(ulongword)a >> n ); +# endif +} + +word gsm_asr P2((a,n), word a, int n) +{ + if (n >= 16) return -(a < 0); + if (n <= -16) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(word)( -(uword)a >> n ); +# endif +} + +/* + * (From p. 46, end of section 4.2.5) + * + * NOTE: The following lines gives [sic] one correct implementation + * of the div(num, denum) arithmetic operation. Compute div + * which is the integer division of num by denum: with denum + * >= num > 0 + */ + +word gsm_div P2((num,denum), word num, word denum) +{ + longword L_num = num; + longword L_denum = denum; + word div = 0; + int k = 15; + + /* The parameter num sometimes becomes zero. + * Although this is explicitly guarded against in 4.2.5, + * we assume that the result should then be zero as well. + */ + + /* assert(num != 0); */ + + assert(num >= 0 && denum >= num); + if (num == 0) + return 0; + + while (k--) { + div <<= 1; + L_num <<= 1; + + if (L_num >= L_denum) { + L_num -= L_denum; + div++; + } + } + + return div; +} diff --git a/linphone/gsmlib/long_term.c b/linphone/gsmlib/long_term.c new file mode 100644 index 000000000..c5365920c --- /dev/null +++ b/linphone/gsmlib/long_term.c @@ -0,0 +1,949 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/long_term.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* + * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION + */ + + +/* + * This module computes the LTP gain (bc) and the LTP lag (Nc) + * for the long term analysis filter. This is done by calculating a + * maximum of the cross-correlation function between the current + * sub-segment short term residual signal d[0..39] (output of + * the short term analysis filter; for simplification the index + * of this array begins at 0 and ends at 39 for each sub-segment of the + * RPE-LTP analysis) and the previous reconstructed short term + * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + * performed to avoid overflow. + */ + + /* The next procedure exists in six versions. First two integer + * version (if USE_FLOAT_MUL is not defined); then four floating + * point versions, twice with proper scaling (USE_FLOAT_MUL defined), + * once without (USE_FLOAT_MUL and FAST defined, and fast run-time + * option used). Every pair has first a Cut version (see the -C + * option to toast or the LTP_CUT option to gsm_option()), then the + * uncut one. (For a detailed explanation of why this is altogether + * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered + * Harmful''.) + */ + +#ifndef USE_FLOAT_MUL + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + + struct gsm_state * st, + + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_result; + longword L_max, L_power; + word R, S, dmax, scal, best_k; + word ltp_cut; + + register word temp, wt_k; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) { + dmax = temp; + best_k = k; + } + } + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + if (temp > 6) scal = 0; + else scal = 6 - temp; + assert(scal >= 0); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + wt_k = SASR(d[best_k], scal); + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = (longword)wt_k * dp[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + *Nc_out = Nc; + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + +# undef STEP +# define STEP(k) (longword)wt[k] * dp[k - lambda] + + register longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) { + + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#else /* USE_FLOAT_MUL */ + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word ltp_cut; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; + + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) { + register word w = SASR( d[k], scal ); + if (w < 0 ? w > -ltp_cut : w < ltp_cut) { + wt_float[k] = 0.0; + } + else { + wt_float[k] = w; + } + } + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + if ((W = wt_float[K]) != 0.0) { \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E; } else (a = lp[K]) + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#ifdef FAST +#ifdef LTP_CUT + +static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, + d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + register float wt_float; + word Nc, bc; + word wt_max, best_k, ltp_cut; + + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_result, L_max, L_power; + + wt_max = 0; + + for (k = 0; k < 40; ++k) { + if ( d[k] > wt_max) wt_max = d[best_k = k]; + else if (-d[k] > wt_max) wt_max = -d[best_k = k]; + } + + assert(wt_max >= 0); + wt_float = (float)wt_max; + + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = wt_float * dp_float[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_max, L_power; + + for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* FAST */ +#endif /* USE_FLOAT_MUL */ + + +/* 4.2.12 */ + +static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), + word bc, /* IN */ + word Nc, /* IN */ + register word * dp, /* previous d [-120..-1] IN */ + register word * d, /* d [0..39] IN */ + register word * dpp, /* estimate [0..39] OUT */ + register word * e /* long term res. signal [0..39] OUT */ +) +/* + * In this part, we have to decode the bc parameter to compute + * the samples of the estimate dpp[0..39]. The decoding of bc needs the + * use of table 4.3b. The long term residual signal e[0..39] + * is then calculated to be fed to the RPE encoding section. + */ +{ + register int k; + register longword ltmp; + +# undef STEP +# define STEP(BP) \ + for (k = 0; k <= 39; k++) { \ + dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ + e[k] = GSM_SUB( d[k], dpp[k] ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ + + struct gsm_state * S, + + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + + word * e, /* [0..39] OUT */ + word * dpp, /* [0..39] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */ +) +{ + assert( d ); assert( dp ); assert( e ); + assert( dpp); assert( Nc ); assert( bc ); + +#if defined(FAST) && defined(USE_FLOAT_MUL) + if (S->fast) +#if defined (LTP_CUT) + if (S->ltp_cut) + Cut_Fast_Calculation_of_the_LTP_parameters(S, + d, dp, bc, Nc); + else +#endif /* LTP_CUT */ + Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); + else +#endif /* FAST & USE_FLOAT_MUL */ +#ifdef LTP_CUT + if (S->ltp_cut) + Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); + else +#endif + Calculation_of_the_LTP_parameters(d, dp, bc, Nc); + + Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +/* 4.3.2 */ +void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), + struct gsm_state * S, + + word Ncr, + word bcr, + register word * erp, /* [0..39] IN */ + register word * drp /* [-120..-1] IN, [-120..40] OUT */ +) +/* + * This procedure uses the bcr and Ncr parameter to realize the + * long term synthesis filtering. The decoding of bcr needs + * table 4.3b. + */ +{ + register longword ltmp; /* for ADD */ + register int k; + word brp, drpp, Nr; + + /* Check the limits of Nr. + */ + Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; + S->nrp = Nr; + assert(Nr >= 40 && Nr <= 120); + + /* Decoding of the LTP gain bcr + */ + brp = gsm_QLB[ bcr ]; + + /* Computation of the reconstructed short term residual + * signal drp[0..39] + */ + assert(brp != MIN_WORD); + + for (k = 0; k <= 39; k++) { + drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); + drp[k] = GSM_ADD( erp[k], drpp ); + } + + /* + * Update of the reconstructed short term residual signal + * drp[ -1..-120 ] + */ + + for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; +} diff --git a/linphone/gsmlib/lpc.c b/linphone/gsmlib/lpc.c new file mode 100644 index 000000000..5fa53ac12 --- /dev/null +++ b/linphone/gsmlib/lpc.c @@ -0,0 +1,341 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/lpc.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +#undef P + +/* + * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION + */ + +/* 4.2.4 */ + + +static void Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +/* + * The goal is to compute the array L_ACF[k]. The signal s[i] must + * be scaled in order to avoid an overflow situation. + */ +{ + register int k, i; + + word temp, smax, scalauto; + +#ifdef USE_FLOAT_MUL + float float_s[160]; +#endif + + /* Dynamic scaling of the array s[0..159] + */ + + /* Search for the maximum. + */ + smax = 0; + for (k = 0; k <= 159; k++) { + temp = GSM_ABS( s[k] ); + if (temp > smax) smax = temp; + } + + /* Computation of the scaling factor. + */ + if (smax == 0) scalauto = 0; + else { + assert(smax > 0); + scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ + } + + /* Scaling of the array s[0...159] + */ + + if (scalauto > 0) { + +# ifdef USE_FLOAT_MUL +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + float_s[k] = (float) \ + (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ + break; +# else +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ + break; +# endif /* USE_FLOAT_MUL */ + + switch (scalauto) { + SCALE(1) + SCALE(2) + SCALE(3) + SCALE(4) + } +# undef SCALE + } +# ifdef USE_FLOAT_MUL + else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; +# endif + + /* Compute the L_ACF[..]. + */ + { +# ifdef USE_FLOAT_MUL + register float * sp = float_s; + register float sl = *sp; + +# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); +# else + word * sp = s; + word sl = *sp; + +# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); +# endif + +# define NEXTI sl = *++sp + + + for (k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + for (i = 8; i <= 159; i++) { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + for (k = 9; k--; L_ACF[k] <<= 1) ; + + } + /* Rescaling of the array s[0..159] + */ + if (scalauto > 0) { + assert(scalauto <= 4); + for (k = 160; k--; *s++ <<= scalauto) ; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +{ + register int k, i; + float f_L_ACF[9]; + float scale; + + float s_f[160]; + register float *sf = s_f; + + for (i = 0; i < 160; ++i) sf[i] = s[i]; + for (k = 0; k <= 8; k++) { + register float L_temp2 = 0; + register float *sfl = sf - k; + for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; + f_L_ACF[k] = L_temp2; + } + scale = MAX_LONGWORD / f_L_ACF[0]; + + for (k = 0; k <= 8; k++) { + L_ACF[k] = f_L_ACF[k] * scale; + } +} +#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ + +/* 4.2.5 */ + +static void Reflection_coefficients P2( (L_ACF, r), + longword * L_ACF, /* 0...8 IN */ + register word * r /* 0...7 OUT */ +) +{ + register int i, m, n; + register word temp; + register longword ltmp; + word ACF[9]; /* 0..8 */ + word P[ 9]; /* 0..8 */ + word K[ 9]; /* 2..8 */ + + /* Schur recursion with 16 bits arithmetic. + */ + + if (L_ACF[0] == 0) { + for (i = 8; i--; *r++ = 0) ; + return; + } + + assert( L_ACF[0] != 0 ); + temp = gsm_norm( L_ACF[0] ); + + assert(temp >= 0 && temp < 32); + + /* ? overflow ? */ + for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); + + /* Initialize array P[..] and K[..] for the recursion. + */ + + for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; + for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; + + /* Compute reflection coefficients + */ + for (n = 1; n <= 8; n++, r++) { + + temp = P[1]; + temp = GSM_ABS(temp); + if (P[0] < temp) { + for (i = n; i <= 8; i++) *r++ = 0; + return; + } + + *r = gsm_div( temp, P[0] ); + + assert(*r >= 0); + if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ + assert (*r != MIN_WORD); + if (n == 8) return; + + /* Schur recursion + */ + temp = GSM_MULT_R( P[1], *r ); + P[0] = GSM_ADD( P[0], temp ); + + for (m = 1; m <= 8 - n; m++) { + temp = GSM_MULT_R( K[ m ], *r ); + P[m] = GSM_ADD( P[ m+1 ], temp ); + + temp = GSM_MULT_R( P[ m+1 ], *r ); + K[m] = GSM_ADD( K[ m ], temp ); + } + } +} + +/* 4.2.6 */ + +static void Transformation_to_Log_Area_Ratios P1((r), + register word * r /* 0..7 IN/OUT */ +) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + register word temp; + register int i; + + + /* Computation of the LAR[0..7] from the r[0..7] + */ + for (i = 1; i <= 8; i++, r++) { + + temp = *r; + temp = GSM_ABS(temp); + assert(temp >= 0); + + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + assert( temp >= 11059 ); + temp -= 11059; + } else { + assert( temp >= 26112 ); + temp -= 26112; + temp <<= 2; + } + + *r = *r < 0 ? -temp : temp; + assert( *r != MIN_WORD ); + } +} + +/* 4.2.7 */ + +static void Quantization_and_coding P1((LAR), + register word * LAR /* [0..7] IN/OUT */ +) +{ + register word temp; + longword ltmp; + + + /* This procedure needs four tables; the following equations + * give the optimum scaling for the constants: + * + * A[0..7] = integer( real_A[0..7] * 1024 ) + * B[0..7] = integer( real_B[0..7] * 512 ) + * MAC[0..7] = maximum of the LARc[0..7] + * MIC[0..7] = minimum of the LARc[0..7] + */ + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = GSM_MULT( A, *LAR ); \ + temp = GSM_ADD( temp, B ); \ + temp = GSM_ADD( temp, 256 ); \ + temp = SASR( temp, 9 ); \ + *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); + else +#endif + Autocorrelation (s, L_ACF ); + Reflection_coefficients (L_ACF, LARc ); + Transformation_to_Log_Area_Ratios (LARc); + Quantization_and_coding (LARc); +} diff --git a/linphone/gsmlib/preprocess.c b/linphone/gsmlib/preprocess.c new file mode 100644 index 000000000..82ee9099e --- /dev/null +++ b/linphone/gsmlib/preprocess.c @@ -0,0 +1,113 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/preprocess.c,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION + * + * After A-law to linear conversion (or directly from the + * Ato D converter) the following scaling is assumed for + * input to the RPE-LTP algorithm: + * + * in: 0.1.....................12 + * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + * + * Where S is the sign bit, v a valid bit, and * a "don't care" bit. + * The original signal is called sop[..] + * + * out: 0.1................... 12 + * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 + */ + + +void Gsm_Preprocess P3((S, s, so), + struct gsm_state * S, + word * s, + word * so ) /* [0..159] IN/OUT */ +{ + + word z1 = S->z1; + longword L_z2 = S->L_z2; + word mp = S->mp; + + word s1; + longword L_s2; + + longword L_temp; + + word msp, lsp; + word SO; + + longword ltmp; /* for ADD */ + ulongword utmp; /* for L_ADD */ + + register int k = 160; + + while (k--) { + + /* 4.2.1 Downscaling of the input signal + */ + SO = SASR( *s, 3 ) << 2; + s++; + + assert (SO >= -0x4000); /* downscaled by */ + assert (SO <= 0x3FFC); /* previous routine. */ + + + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + + s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ + z1 = SO; + + assert(s1 != MIN_WORD); + + /* Compute the recursive part + */ + L_s2 = s1; + L_s2 <<= 15; + + /* Execution of a 31 bv 16 bits multiplication + */ + + msp = SASR( L_z2, 15 ); + lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */ + + L_s2 += GSM_MULT_R( lsp, 32735 ); + L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ + L_z2 = GSM_L_ADD( L_temp, L_s2 ); + + /* Compute sof[k] with rounding + */ + L_temp = GSM_L_ADD( L_z2, 16384 ); + + /* 4.2.3 Preemphasis + */ + + msp = GSM_MULT_R( mp, -28180 ); + mp = SASR( L_temp, 15 ); + *so++ = GSM_ADD( mp, msp ); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} diff --git a/linphone/gsmlib/private.h b/linphone/gsmlib/private.h new file mode 100644 index 000000000..d78fd6b97 --- /dev/null +++ b/linphone/gsmlib/private.h @@ -0,0 +1,268 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /sources/linphone/linphone/gsmlib/private.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $*/ + +#ifndef PRIVATE_H +#define PRIVATE_H + +typedef short word; /* 16 bit signed int */ +typedef long longword; /* 32 bit signed int */ + +typedef unsigned short uword; /* unsigned word */ +typedef unsigned long ulongword; /* unsigned longword */ + +struct gsm_state { + + word dp0[ 280 ]; + + word z1; /* preprocessing.c, Offset_com. */ + longword L_z2; /* Offset_com. */ + int mp; /* Preemphasis */ + + word u[8]; /* short_term_aly_filter.c */ + word LARpp[2][8]; /* */ + word j; /* */ + + word ltp_cut; /* long_term.c, LTP crosscorr. */ + word nrp; /* 40 */ /* long_term.c, synthesis */ + word v[9]; /* short_term.c, synthesis */ + word msr; /* decoder.c, Postprocessing */ + + char verbose; /* only used if !NDEBUG */ + char fast; /* only used if FAST */ + + char wav_fmt; /* only used if WAV49 defined */ + unsigned char frame_index; /* odd/even chaining */ + unsigned char frame_chain; /* half-byte to carry forward */ +}; + + +#define MIN_WORD (-32767 - 1) +#define MAX_WORD 32767 + +#define MIN_LONGWORD (-2147483647 - 1) +#define MAX_LONGWORD 2147483647 + +#ifdef SASR /* flag: >> is a signed arithmetic shift right */ +#undef SASR +#define SASR(x, by) ((x) >> (by)) +#else +#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) +#endif /* SASR */ + +#include "proto.h" + +/* + * Prototypes from add.c + */ +extern word gsm_mult P((word a, word b)); +extern longword gsm_L_mult P((word a, word b)); +extern word gsm_mult_r P((word a, word b)); + +extern word gsm_div P((word num, word denum)); + +extern word gsm_add P(( word a, word b )); +extern longword gsm_L_add P(( longword a, longword b )); + +extern word gsm_sub P((word a, word b)); +extern longword gsm_L_sub P((longword a, longword b)); + +extern word gsm_abs P((word a)); + +extern word gsm_norm P(( longword a )); + +extern longword gsm_L_asl P((longword a, int n)); +extern word gsm_asl P((word a, int n)); + +extern longword gsm_L_asr P((longword a, int n)); +extern word gsm_asr P((word a, int n)); + +/* + * Inlined functions from add.h + */ + +/* + * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ + * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) + */ +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_MULT(a, b) /* word a, word b */ \ + (((longword)(a) * (longword)(b)) << 1) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + * # define GSM_ADD(a, b) \ + * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + */ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_mult_r(a, b) +# define GSM_MULT(a, b) gsm_mult(a, b) +# define GSM_L_MULT(a, b) gsm_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_L_add(a, b) +# define GSM_ADD(a, b) gsm_add(a, b) +# define GSM_SUB(a, b) gsm_sub(a, b) + +# define GSM_ABS(a) gsm_abs(a) + +*/ + +/* + * More prototypes from implementations.. + */ +extern void Gsm_Coder P(( + struct gsm_state * S, + word * s, /* [0..159] samples IN */ + word * LARc, /* [0..7] LAR coefficients OUT */ + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */)); + +extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ + struct gsm_state * S, + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + word * e, /* [0..40] OUT */ + word * dpp, /* [0..40] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */)); + +extern void Gsm_LPC_Analysis P(( + struct gsm_state * S, + word * s, /* 0..159 signals IN/OUT */ + word * LARc)); /* 0..7 LARc's OUT */ + +extern void Gsm_Preprocess P(( + struct gsm_state * S, + word * s, word * so)); + +extern void Gsm_Encoding P(( + struct gsm_state * S, + word * e, + word * ep, + word * xmaxc, + word * Mc, + word * xMc)); + +extern void Gsm_Short_Term_Analysis_Filter P(( + struct gsm_state * S, + word * LARc, /* coded log area ratio [0..7] IN */ + word * d /* st res. signal [0..159] IN/OUT */)); + +extern void Gsm_Decoder P(( + struct gsm_state * S, + word * LARcr, /* [0..7] IN */ + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + word * s)); /* [0..159] OUT */ + +extern void Gsm_Decoding P(( + struct gsm_state * S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12] IN */ + word * erp)); /* [0..39] OUT */ + +extern void Gsm_Long_Term_Synthesis_Filtering P(( + struct gsm_state* S, + word Ncr, + word bcr, + word * erp, /* [0..39] IN */ + word * drp)); /* [-120..-1] IN, [0..40] OUT */ + +void Gsm_RPE_Decoding P(( + struct gsm_state *S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp)); /* [0..39] OUT */ + +void Gsm_RPE_Encoding P(( + struct gsm_state * S, + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc)); /* [0..12] OUT */ + +extern void Gsm_Short_Term_Synthesis_Filter P(( + struct gsm_state * S, + word * LARcr, /* log area ratios [0..7] IN */ + word * drp, /* received d [0...39] IN */ + word * s)); /* signal s [0..159] OUT */ + +extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp)); /* [-120...-1] IN/OUT */ + +/* + * Tables from table.c + */ +#ifndef GSM_TABLE_C + +extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; +extern word gsm_INVA[8]; +extern word gsm_DLB[4], gsm_QLB[4]; +extern word gsm_H[11]; +extern word gsm_NRFAC[8]; +extern word gsm_FAC[8]; + +#endif /* GSM_TABLE_C */ + +/* + * Debugging + */ +#ifdef NDEBUG + +# define gsm_debug_words(a, b, c, d) /* nil */ +# define gsm_debug_longwords(a, b, c, d) /* nil */ +# define gsm_debug_word(a, b) /* nil */ +# define gsm_debug_longword(a, b) /* nil */ + +#else /* !NDEBUG => DEBUG */ + + extern void gsm_debug_words P((char * name, int, int, word *)); + extern void gsm_debug_longwords P((char * name, int, int, longword *)); + extern void gsm_debug_longword P((char * name, longword)); + extern void gsm_debug_word P((char * name, word)); + +#endif /* !NDEBUG */ + +#include "unproto.h" + +#endif /* PRIVATE_H */ diff --git a/linphone/gsmlib/proto.h b/linphone/gsmlib/proto.h new file mode 100644 index 000000000..3cedd367e --- /dev/null +++ b/linphone/gsmlib/proto.h @@ -0,0 +1,65 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /sources/linphone/linphone/gsmlib/proto.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $*/ + +#ifndef PROTO_H +#define PROTO_H + +#if __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#undef P /* gnu stdio.h actually defines this... */ +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#if NeedFunctionPrototypes + +# define P( protos ) protos + +# define P0() (void) +# define P1(x, a) (a) +# define P2(x, a, b) (a, b) +# define P3(x, a, b, c) (a, b, c) +# define P4(x, a, b, c, d) (a, b, c, d) +# define P5(x, a, b, c, d, e) (a, b, c, d, e) +# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) +# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) +# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) + +#else /* !NeedFunctionPrototypes */ + +# define P( protos ) ( /* protos */ ) + +# define P0() () +# define P1(x, a) x a; +# define P2(x, a, b) x a; b; +# define P3(x, a, b, c) x a; b; c; +# define P4(x, a, b, c, d) x a; b; c; d; +# define P5(x, a, b, c, d, e) x a; b; c; d; e; +# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; +# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; +# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; + +#endif /* !NeedFunctionPrototypes */ + +#endif /* PROTO_H */ diff --git a/linphone/gsmlib/rpe.c b/linphone/gsmlib/rpe.c new file mode 100644 index 000000000..15a359c76 --- /dev/null +++ b/linphone/gsmlib/rpe.c @@ -0,0 +1,488 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/rpe.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION + */ + +/* 4.2.13 */ + +static void Weighting_filter P2((e, x), + register word * e, /* signal [-5..0.39.44] IN */ + word * x /* signal [0..39] OUT */ +) +/* + * The coefficients of the weighting filter are stored in a table + * (see table 4.4). The following scaling is used: + * + * H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +{ + /* word wt[ 50 ]; */ + + register longword L_result; + register int k /* , i */ ; + + /* Initialization of a temporary working array wt[0...49] + */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] + */ + for (k = 0; k <= 39; k++) { + + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) { + * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); + * L_result = GSM_L_ADD( L_result, L_temp ); + * } + */ + +#undef STEP +#define STEP( i, H ) (e[ k + i ] * (longword)H) + + /* Every one of these multiplications is done twice -- + * but I don't see an elegant way to optimize this. + * Do you? + */ + +#ifdef STUPID_COMPILER + L_result += STEP( 0, -134 ) ; + L_result += STEP( 1, -374 ) ; + /* + STEP( 2, 0 ) */ + L_result += STEP( 3, 2054 ) ; + L_result += STEP( 4, 5741 ) ; + L_result += STEP( 5, 8192 ) ; + L_result += STEP( 6, 5741 ) ; + L_result += STEP( 7, 2054 ) ; + /* + STEP( 8, 0 ) */ + L_result += STEP( 9, -374 ) ; + L_result += STEP( 10, -134 ) ; +#else + L_result += + STEP( 0, -134 ) + + STEP( 1, -374 ) + /* + STEP( 2, 0 ) */ + + STEP( 3, 2054 ) + + STEP( 4, 5741 ) + + STEP( 5, 8192 ) + + STEP( 6, 5741 ) + + STEP( 7, 2054 ) + /* + STEP( 8, 0 ) */ + + STEP( 9, -374 ) + + STEP(10, -134 ) + ; +#endif + + /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) + * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) + * + * x[k] = SASR( L_result, 16 ); + */ + + /* 2 adds vs. >>16 => 14, minus one shift to compensate for + * those we lost when replacing L_MULT by '*'. + */ + + L_result = SASR( L_result, 13 ); + x[k] = ( L_result < MIN_WORD ? MIN_WORD + : (L_result > MAX_WORD ? MAX_WORD : L_result )); + } +} + +/* 4.2.14 */ + +static void RPE_grid_selection P3((x,xM,Mc_out), + word * x, /* [0..39] IN */ + word * xM, /* [0..12] OUT */ + word * Mc_out /* OUT */ +) +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +{ + /* register word temp1; */ + register int /* m, */ i; + register longword L_result, L_temp; + longword EM; /* xxx should be L_EM? */ + word Mc; + + longword L_common_0_3; + + EM = 0; + Mc = 0; + + /* for (m = 0; m <= 3; m++) { + * L_result = 0; + * + * + * for (i = 0; i <= 12; i++) { + * + * temp1 = SASR( x[m + 3*i], 2 ); + * + * assert(temp1 != MIN_WORD); + * + * L_temp = GSM_L_MULT( temp1, temp1 ); + * L_result = GSM_L_ADD( L_temp, L_result ); + * } + * + * if (L_result > EM) { + * Mc = m; + * EM = L_result; + * } + * } + */ + +#undef STEP +#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ + L_result += L_temp * L_temp; + + /* common part of 0 and 3 */ + + L_result = 0; + STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); + STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); + STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP( 0, 0 ); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP( 1, 0 ); + STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); + STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); + STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 1; + EM = L_result; + } + + /* i = 2 */ + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 2; + EM = L_result; + } + + /* i = 3 */ + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result <<= 1; + if (L_result > EM) { + Mc = 3; + EM = L_result; + } + + /**/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; +} + +/* 4.12.15 */ + +static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), + word xmaxc, /* IN */ + word * exp_out, /* OUT */ + word * mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + + exp = 0; + if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + while (mant <= 7) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + assert( exp >= -4 && exp <= 6 ); + assert( mant >= 0 && mant <= 7 ); + + *exp_out = exp; + *mant_out = mant; +} + +static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), + word * xM, /* [0..12] IN */ + + word * xMc, /* [0..12] OUT */ + word * mant_out, /* OUT */ + word * exp_out, /* OUT */ + word * xmaxc_out /* OUT */ +) +{ + int i, itest; + + word xmax, xmaxc, temp, temp1, temp2; + word exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + for (i = 0; i <= 12; i++) { + temp = xM[i]; + temp = GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = SASR( xmax, 9 ); + itest = 0; + + for (i = 0; i <= 5; i++) { + + itest |= (temp <= 0); + temp = SASR( temp, 1 ); + + assert(exp <= 5); + if (itest == 0) exp++; /* exp = add (exp, 1) */ + } + + assert(exp <= 6 && exp >= 0); + temp = exp + 5; + + assert(temp <= 11 && temp >= 0); + xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + + APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + + /* Direct computation of xMc[0..12] using table 4.5 + */ + + assert( exp <= 4096 && exp >= -4096); + assert( mant >= 0 && mant <= 7 ); + + temp1 = 6 - exp; /* normalization by the exponent */ + temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ + + for (i = 0; i <= 12; i++) { + + assert(temp1 >= 0 && temp1 < 16); + + temp = xM[i] << temp1; + temp = GSM_MULT( temp, temp2 ); + temp = SASR(temp, 12); + xMc[i] = temp + 4; /* see note below */ + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +/* 4.2.16 */ + +static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), + register word * xMc, /* [0..12] IN */ + word mant, + word exp, + register word * xMp) /* [0..12] OUT */ +/* + * This part is for decoding the RPE sequence of coded xMc[0..12] + * samples to obtain the xMp[0..12] array. Table 4.6 is used to get + * the mantissa of xmaxc (FAC[0..7]). + */ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + assert( mant >= 0 && mant <= 7 ); + + temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); + + for (i = 13; i--;) { + + assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ + + /* temp = gsm_sub( *xMc++ << 1, 7 ); */ + temp = (*xMc++ << 1) - 7; /* restore sign */ + assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_asr( temp, temp2 ); + } +} + +/* 4.2.17 */ + +static void RPE_grid_positioning P3((Mc,xMp,ep), + word Mc, /* grid position IN */ + register word * xMp, /* [0..12] IN */ + register word * ep /* [0..39] OUT */ +) +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +{ + int i = 13; + + assert(0 <= Mc && Mc <= 3); + + switch (Mc) { + case 3: *ep++ = 0; + case 2: do { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + } while (--i); + } + while (++Mc < 4) *ep++ = 0; + + /* + + int i, k; + for (k = 0; k <= 39; k++) ep[k] = 0; + for (i = 0; i <= 12; i++) { + ep[ Mc + (3*i) ] = xMp[i]; + } + */ +} + +/* 4.2.18 */ + +/* This procedure adds the reconstructed long term residual signal + * ep[0..39] to the estimated signal dpp[0..39] from the long term + * analysis filter to compute the reconstructed short term residual + * signal dp[-40..-1]; also the reconstructed short term residual + * array dp[-120..-41] is updated. + */ + +#if 0 /* Has been inlined in code.c */ +void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp) /* [-120...-1] IN/OUT */ +{ + int k; + + for (k = 0; k <= 79; k++) + dp[ -120 + k ] = dp[ -80 + k ]; + + for (k = 0; k <= 39; k++) + dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); +} +#endif /* Has been inlined in code.c */ + +void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), + + struct gsm_state * S, + + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc) /* [0..12] OUT */ +{ + word x[40]; + word xM[13], xMp[13]; + word mant, exp; + + Weighting_filter(e, x); + RPE_grid_selection(x, xM, Mc); + + APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + APCM_inverse_quantization( xMc, mant, exp, xMp); + + RPE_grid_positioning( *Mc, xMp, e ); + +} + +void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), + struct gsm_state * S, + + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp /* [0..39] OUT */ +) +{ + word exp, mant; + word xMp[ 13 ]; + + APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); + APCM_inverse_quantization( xMcr, mant, exp, xMp ); + RPE_grid_positioning( Mcr, xMp, erp ); + +} diff --git a/linphone/gsmlib/short_term.c b/linphone/gsmlib/short_term.c new file mode 100644 index 000000000..951261edc --- /dev/null +++ b/linphone/gsmlib/short_term.c @@ -0,0 +1,429 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/short_term.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* + * SHORT TERM ANALYSIS FILTERING SECTION + */ + +/* 4.2.8 */ + +static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), + word * LARc, /* coded log area ratio [0..7] IN */ + word * LARpp) /* out: decoded .. */ +{ + register word temp1 /* , temp2 */; + register long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + * two tables. + * + * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + * MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + + /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { + * + * temp1 = GSM_ADD( *LARc, *MIC ) << 10; + * temp2 = *B << 1; + * temp1 = GSM_SUB( temp1, temp2 ); + * + * assert(*INVA != MIN_WORD); + * + * temp1 = GSM_MULT_R( *INVA, temp1 ); + * *LARpp = GSM_ADD( temp1, temp1 ); + * } + */ + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ + temp1 = GSM_SUB( temp1, B << 1 ); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore + * the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients + */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] + */ + +/* + * Within each frame of 160 analyzed speech samples the short term + * analysis and synthesis filters operate with four different sets of + * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + * and the actual set of decoded LARs (LARpp(j)) + * + * (Initial value: LARpp(j-1)[1..8] = 0.) + */ + +static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); + } +} + +static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); + } +} + +static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); + } +} + + +static void Coefficients_40_159 P2((LARpp_j, LARp), + register word * LARpp_j, + register word * LARp) +{ + register int i; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j++) + *LARp = *LARpp_j; +} + +/* 4.2.9.2 */ + +static void LARp_to_rp P1((LARp), + register word * LARp) /* [0..7] IN/OUT */ +/* + * The input of this procedure is the interpolated LARp[0..7] array. + * The reflection coefficients, rp[i], are used in the analysis + * filter and in the synthesis filter. + */ +{ + register int i; + register word temp; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++) { + + /* temp = GSM_ABS( *LARp ); + * + * if (temp < 11059) temp <<= 1; + * else if (temp < 20070) temp += 11059; + * else temp = GSM_ADD( temp >> 2, 26112 ); + * + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if (*LARp < 0) { + temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); + *LARp = - ((temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ))); + } else { + temp = *LARp; + *LARp = (temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 )); + } + } +} + + +/* 4.2.10 */ +static void Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +{ + register word * u = S->u; + register int i; + register word di, zzz, ui, sav, rpi; + register longword ltmp; + + for (; k_n--; s++) { + + di = sav = *s; + + for (i = 0; i < 8; i++) { /* YYY */ + + ui = u[i]; + rpi = rp[i]; + u[i] = sav; + + zzz = GSM_MULT_R(rpi, di); + sav = GSM_ADD( ui, zzz); + + zzz = GSM_MULT_R(rpi, ui); + di = GSM_ADD( di, zzz ); + } + + *s = di; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +{ + register word * u = S->u; + register int i; + + float uf[8], + rpf[8]; + + register float scalef = 3.0517578125e-5; + register float sav, di, temp; + + for (i = 0; i < 8; ++i) { + uf[i] = u[i]; + rpf[i] = rp[i] * scalef; + } + for (; k_n--; s++) { + sav = di = *s; + for (i = 0; i < 8; ++i) { + register float rpfi = rpf[i]; + register float ufi = uf[i]; + + uf[i] = sav; + temp = rpfi * di + ufi; + di += rpfi * ufi; + sav = temp; + } + *s = di; + } + for (i = 0; i < 8; ++i) u[i] = uf[i]; +} +#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ + +static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + register word sri, tmp1, tmp2; + register longword ltmp; /* for GSM_ADD & GSM_SUB */ + + while (k--) { + sri = *wt++; + for (i = 8; i--;) { + + /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); + */ + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + + 16384) >> 15)) ; + + sri = GSM_SUB( sri, tmp2 ); + + /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); + */ + tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)sri + + 16384) >> 15)) ; + + v[i+1] = GSM_ADD( v[i], tmp1); + } + *sr++ = v[0] = sri; + } +} + + +#if defined(FAST) && defined(USE_FLOAT_MUL) + +static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + + float va[9], rrpa[8]; + register float scalef = 3.0517578125e-5, temp; + + for (i = 0; i < 8; ++i) { + va[i] = v[i]; + rrpa[i] = (float)rrp[i] * scalef; + } + while (k--) { + register float sri = *wt++; + for (i = 8; i--;) { + sri -= rrpa[i] * va[i]; + if (sri < -32768.) sri = -32768.; + else if (sri > 32767.) sri = 32767.; + + temp = va[i] + rrpa[i] * sri; + if (temp < -32768.) temp = -32768.; + else if (temp > 32767.) temp = 32767.; + va[i+1] = temp; + } + *sr++ = va[0] = sri; + } + for (i = 0; i < 9; ++i) v[i] = va[i]; +} + +#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ + +void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), + + struct gsm_state * S, + + word * LARc, /* coded log area ratio [0..7] IN */ + word * s /* signal [0..159] IN/OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) +# define FILTER (* (S->fast \ + ? Fast_Short_term_analysis_filtering \ + : Short_term_analysis_filtering )) + +#else +# define FILTER Short_term_analysis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, s + 13); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s + 27); + + Coefficients_40_159( LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 120, s + 40); +} + +void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), + struct gsm_state * S, + + word * LARcr, /* received log area ratios [0..7] IN */ + word * wt, /* received d [0..159] IN */ + + word * s /* signal s [0..159] OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) + +# define FILTER (* (S->fast \ + ? Fast_Short_term_synthesis_filtering \ + : Short_term_synthesis_filtering )) +#else +# define FILTER Short_term_synthesis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt, s ); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, wt + 13, s + 13 ); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt + 27, s + 27 ); + + Coefficients_40_159( LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER(S, LARp, 120, wt + 40, s + 40); +} diff --git a/linphone/gsmlib/table.c b/linphone/gsmlib/table.c new file mode 100644 index 000000000..46a090978 --- /dev/null +++ b/linphone/gsmlib/table.c @@ -0,0 +1,63 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/table.c,v 1.1.1.1 2001/11/19 19:50:12 smorlat Exp $ */ + +/* Most of these tables are inlined at their point of use. + */ + +/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP + * CODER AND DECODER + * + * (Most of them inlined, so watch out.) + */ + +#define GSM_TABLE_C +#include "private.h" +#include "gsm.h" + +/* Table 4.1 Quantization of the Log.-Area Ratios + */ +/* i 1 2 3 4 5 6 7 8 */ +word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; +word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; +word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; +word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; + + +/* Table 4.2 Tabulation of 1/A[1..8] + */ +word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; + + +/* Table 4.3a Decision level of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; + + +/* Table 4.3b Quantization levels of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; + + +/* Table 4.4 Coefficients of the weighting filter + */ +/* i 0 1 2 3 4 5 6 7 8 9 10 */ +word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; + + +/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; + + +/* Table 4.6 Normalized direct mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; diff --git a/linphone/gsmlib/toast.h b/linphone/gsmlib/toast.h new file mode 100644 index 000000000..4c33a35d2 --- /dev/null +++ b/linphone/gsmlib/toast.h @@ -0,0 +1,109 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /sources/linphone/linphone/gsmlib/toast.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $ */ + +#ifndef TOAST_H +#define TOAST_H /* Guard against multiple includes */ + +#include "config.h" + +#include +#include + +#include +#include +#include + +#include +#ifndef HAS_ERRNO_DECL + extern int errno; +#endif + +#ifdef HAS_LIMITS_H +#include +#endif + +#ifdef HAS_FCNTL_H +# include +#endif + +#ifdef HAS_UTIME +# ifdef HAS_UTIME_H +# include +# endif +#endif + +#include "gsm.h" + +#ifndef S_ISREG +#define S_ISREG(x) ((x) & S_IFREG) +#endif /* S_ISREG */ + + +# define READ "rb" +# define WRITE "wb" +#ifdef O_BINARY +# define O_WRITE_EXCL O_WRONLY|O_CREAT|O_EXCL|O_BINARY +#else +# define O_WRITE_EXCL O_WRONLY|O_CREAT|O_EXCL +#endif + +#ifndef SIGHANDLER_T +#define SIGHANDLER_T void /* what does a signal handler return? */ +#endif + + +#ifdef HAS_STRING_H +#include +#else +# ifdef HAS_STRINGS_H +# include +# else +# include "proto.h" + + extern int strlen P((char *)); + extern char * strcpy P((char *, char *)); + extern char * strcat P((char *, char *)); + extern char * strrchr P((char *, int)); + +# include "unproto.h" +# endif +#endif + + +#ifdef HAS_STDLIB_H +#include +#else +# include "proto.h" +# ifdef HAS_MALLOC_H +# include +# else + extern char * malloc P((unsigned)); +# endif + extern int exit P((int)); +# include "unproto.h" +#endif + + +#ifdef HAS_UNISTD_H +# include +#endif + +/* + * This suffix is tacked onto/removed from filenames + * similar to the way freeze and compress do it. + */ +#define SUFFIX_TOASTED ".gsm" + +#include "proto.h" + +extern int audio_init_input P((void)), audio_init_output P((void)); +extern int ulaw_input P((gsm_signal*)), ulaw_output P((gsm_signal *)); +extern int alaw_input P((gsm_signal*)), alaw_output P((gsm_signal *)); +extern int linear_input P((gsm_signal*)), linear_output P((gsm_signal *)); + +#endif /* TOAST_H */ diff --git a/linphone/gsmlib/unproto.h b/linphone/gsmlib/unproto.h new file mode 100644 index 000000000..6ef49e36f --- /dev/null +++ b/linphone/gsmlib/unproto.h @@ -0,0 +1,23 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /sources/linphone/linphone/gsmlib/unproto.h,v 1.1.1.1 2001/11/19 19:50:11 smorlat Exp $*/ + +#ifdef PROTO_H /* sic */ +#undef PROTO_H + +#undef P +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#endif /* PROTO_H */ diff --git a/linphone/gtk-glade/Makefile.am b/linphone/gtk-glade/Makefile.am new file mode 100644 index 000000000..8145c5964 --- /dev/null +++ b/linphone/gtk-glade/Makefile.am @@ -0,0 +1,57 @@ +GLADE_FILES= about.glade \ + gtk-linphone.glade \ + main.glade \ + password.glade \ + contact.glade \ + incoming_call.glade \ + parameters.glade \ + sip_account.glade \ + chatroom.glade \ + call_logs.glade \ + log.glade + +PIXMAPS= linphone2.png \ + linphone.png \ + stock_people.png + +EXTRA_DIST= $(PIXMAPS) \ + $(GLADE_FILES) + +if BUILD_GLADE_UI + +bin_PROGRAMS=linphone-3 + +linphone_3_SOURCES= main.c\ + propertybox.c \ + friendlist.c \ + support.c \ + chat.c \ + calllogs.c \ + logging.c \ + linphone.h + +linphone_3_LDADD=$(top_builddir)/oRTP/src/libortp.la \ + $(top_builddir)/mediastreamer2/src/libmediastreamer.la \ + $(top_builddir)/coreapi/liblinphone.la \ + $(LIBGTK_LIBS) $(INTLLIBS) \ + $(LIBGLADE_LIBS) + +linphone_3_LDFLAGS=-export-dynamic + +gladedir=$(datadir)/linphone +glade_DATA=$(GLADE_FILES) $(PIXMAPS) + +#all-local: gtk-linphone.ui + +#gtk-linphone.ui: gtk-linphone.glade +# gtk-builder-convert gtk-linphone.glade $@ + +endif + + +AM_CFLAGS= -I$(top_srcdir)/coreapi/ \ + -I$(top_srcdir)/mediastreamer2/include/ \ + $(LIBGLADE_CFLAGS) $(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(IPV6_CFLAGS) \ + $(ORTP_CFLAGS) $(OSIP_CFLAGS) + + diff --git a/linphone/gtk-glade/about.glade b/linphone/gtk-glade/about.glade new file mode 100644 index 000000000..96c6b5f10 --- /dev/null +++ b/linphone/gtk-glade/about.glade @@ -0,0 +1,61 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + About linphone + False + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + Linphone + undef + Created by Simon Morlat + + An internet video phone using the standart SIP (rfc3261) protocol. + http://www.linphone.org + GPL + Simon Morlat + + fr: Simon Morlat +en: Simon Morlat and Delphine Perreau +it: Alberto Zanoni <alberto.zanoni@-NO-SPAM-PLEASE!-tiscalinet.it> +de: Jean-Jacques Sarton <jj.sarton@-NO-SPAM-PLEASE-t-online.de> +sv: Daniel Nylander <po@danielnylander.se> +es: Jesus Benitez <gnelson at inMail dot sk> +ja: YAMAGUCHI YOSHIYA <yushiya@anet.ne.jp> +pt_BR: Rafael Caesar Lenzi <rc_lenzi@yahoo.com.br> +pl: Robert Nasiadek <darkone@darkone.pl> +cs: Petr Pisar <petr.pisar@atlas.cz> +hu: anonymous + + Icons by Pablo Marcello Moia + + linphone.png + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/call_logs.glade b/linphone/gtk-glade/call_logs.glade new file mode 100644 index 000000000..d2ac682d3 --- /dev/null +++ b/linphone/gtk-glade/call_logs.glade @@ -0,0 +1,66 @@ + + + + + + 500 + 370 + 5 + Call history + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + 2 + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + True + False + GTK_WRAP_WORD + + + + + 1 + + + + + True + GTK_BUTTONBOX_END + + + + + + True + True + True + gtk-close + True + 0 + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/calllogs.c b/linphone/gtk-glade/calllogs.c new file mode 100644 index 000000000..59a8bcbda --- /dev/null +++ b/linphone/gtk-glade/calllogs.c @@ -0,0 +1,68 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" + +void linphone_gtk_call_log_update(GtkWidget *w){ + GtkTextView *v=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"logtextview")); + GtkTextBuffer *b=gtk_text_view_get_buffer(v); + GtkTextIter iter,begin; + int off; + char *logmsg; + MSList *logs; + for (logs=linphone_core_get_call_logs(linphone_gtk_get_core());logs!=NULL;logs=logs->next){ + LinphoneCallLog *cl=(LinphoneCallLog*)logs->data; + logmsg=linphone_call_log_to_str(cl); + gtk_text_buffer_get_end_iter(b,&iter); + off=gtk_text_iter_get_offset(&iter); + gtk_text_buffer_insert(b,&iter,logmsg,-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,"\n",-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_get_iter_at_offset(b,&begin,off); + gtk_text_buffer_apply_tag_by_name(b,cl->dir==LinphoneCallOutgoing ? "green" : "blue" ,&begin,&iter); + ms_free(logmsg); + } + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_view_scroll_to_iter(v,&iter,0,FALSE,0,0); +} + +void linphone_gtk_call_log_response(GtkWidget *w){ + GtkWidget *mw=linphone_gtk_get_main_window(); + g_object_set_data(G_OBJECT(mw),"call_logs",NULL); + gtk_widget_destroy(w); +} + +GtkWidget * linphone_gtk_show_call_logs(void){ + GtkWidget *mw=linphone_gtk_get_main_window(); + GtkTextBuffer *b; + GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs"); + if (w==NULL){ + w=linphone_gtk_create_window("call_logs"); + g_object_set_data(G_OBJECT(mw),"call_logs",w); + g_signal_connect(G_OBJECT(w),"response",(GCallback)linphone_gtk_call_log_response,NULL); + gtk_widget_show(w); + b=gtk_text_view_get_buffer(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"logtextview"))); + gtk_text_buffer_create_tag(b,"blue","foreground","blue",NULL); + gtk_text_buffer_create_tag(b,"green","foreground","green",NULL); + linphone_gtk_call_log_update(w); + }else gtk_window_present(GTK_WINDOW(w)); + return w; +} + diff --git a/linphone/gtk-glade/chat.c b/linphone/gtk-glade/chat.c new file mode 100644 index 000000000..bc61850a8 --- /dev/null +++ b/linphone/gtk-glade/chat.c @@ -0,0 +1,108 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" + +GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const char *with){ + GtkWidget *w; + GtkTextBuffer *b; + gchar *tmp; + w=linphone_gtk_create_window("chatroom"); + tmp=g_strdup_printf(_("Chat with %s"),with); + gtk_window_set_title(GTK_WINDOW(w),tmp); + g_free(tmp); + g_object_set_data(G_OBJECT(w),"cr",cr); + gtk_widget_show(w); + linphone_chat_room_set_user_data(cr,w); + b=gtk_text_view_get_buffer(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog"))); + gtk_text_buffer_create_tag(b,"blue","foreground","blue",NULL); + gtk_text_buffer_create_tag(b,"green","foreground","green",NULL); + return w; +} + +void linphone_gtk_create_chatroom(const char *with){ + LinphoneChatRoom *cr=linphone_core_create_chat_room(linphone_gtk_get_core(),with); + if (!cr) return; + linphone_gtk_init_chatroom(cr,with); +} + +void linphone_gtk_chat_destroyed(GtkWidget *w){ + LinphoneChatRoom *cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(w),"cr"); + linphone_chat_room_destroy(cr); +} + +void linphone_gtk_chat_close(GtkWidget *button){ + GtkWidget *w=gtk_widget_get_toplevel(button); + gtk_widget_destroy(w); +} + +void linphone_gtk_push_text(GtkTextView *v, const char *from, const char *message, gboolean me){ + GtkTextBuffer *b=gtk_text_view_get_buffer(v); + GtkTextIter iter,begin; + int off; + gtk_text_buffer_get_end_iter(b,&iter); + off=gtk_text_iter_get_offset(&iter); + gtk_text_buffer_insert(b,&iter,from,-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,":\t",-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_get_iter_at_offset(b,&begin,off); + gtk_text_buffer_apply_tag_by_name(b,me ? "green" : "blue" ,&begin,&iter); + gtk_text_buffer_insert(b,&iter,message,-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,"\n",-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_view_scroll_to_iter(v,&iter,0,FALSE,0,0); +} + +const char* linphone_gtk_get_used_identity(){ + LinphoneCore *lc=linphone_gtk_get_core(); + LinphoneProxyConfig *cfg; + linphone_core_get_default_proxy(lc,&cfg); + if (cfg) return linphone_proxy_config_get_identity(cfg); + else return linphone_core_get_primary_contact(lc); +} + +void linphone_gtk_send_text(GtkWidget *button){ + GtkWidget *w=gtk_widget_get_toplevel(button); + GtkWidget *entry=linphone_gtk_get_widget(w,"text_entry"); + LinphoneChatRoom *cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(w),"cr"); + const gchar *entered; + entered=gtk_entry_get_text(GTK_ENTRY(entry)); + if (strlen(entered)>0) { + linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")), + linphone_gtk_get_used_identity(), + entered,TRUE); + linphone_chat_room_send_message(cr,entered); + gtk_entry_set_text(GTK_ENTRY(entry),""); + } +} + +void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message){ + GtkWidget *w=(GtkWidget*)linphone_chat_room_get_user_data(room); + if (w==NULL){ + w=linphone_gtk_init_chatroom(room,from); + } + linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")), + from, + message,FALSE); + gtk_window_present(GTK_WINDOW(w)); + /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/ +} + diff --git a/linphone/gtk-glade/chatroom.glade b/linphone/gtk-glade/chatroom.glade new file mode 100644 index 000000000..870ae537e --- /dev/null +++ b/linphone/gtk-glade/chatroom.glade @@ -0,0 +1,100 @@ + + + + + + + + + True + + + 200 + 200 + True + True + False + GTK_WRAP_WORD + + + + + True + + + True + True + True + + + + + + True + True + True + 0 + + + + True + + + True + gtk-ok + + + + + True + Send + + + 7 + 1 + + + + + + + False + False + 1 + + + + + False + False + 1 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-close + True + 0 + + + + GTK_PACK_END + + + + + False + 2 + + + + + + diff --git a/linphone/gtk-glade/contact.glade b/linphone/gtk-glade/contact.glade new file mode 100644 index 000000000..31f806f80 --- /dev/null +++ b/linphone/gtk-glade/contact.glade @@ -0,0 +1,179 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Name + + + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP Address + + + 1 + 2 + GTK_FILL + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + GTK_FILL + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Show this contact presence status + 0 + True + True + + + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Allow this contact to see my presence status + 0 + True + True + + + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Contact information + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/friendlist.c b/linphone/gtk-glade/friendlist.c new file mode 100644 index 000000000..95f1779d0 --- /dev/null +++ b/linphone/gtk-glade/friendlist.c @@ -0,0 +1,454 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include "linphone.h" + +static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list); + +enum{ + FRIEND_PRESENCE_IMG, + FRIEND_NAME, + FRIEND_PRESENCE_STATUS, + FRIEND_ID, + FRIEND_SIP_ADDRESS, + FRIEND_LIST_NCOL +}; + + +typedef struct _status_picture_tab_t{ + LinphoneOnlineStatus status; + const char *img; +} status_picture_tab_t; + +status_picture_tab_t status_picture_tab[]={ + { LINPHONE_STATUS_UNKNOWN, "sip-closed.png" }, + { LINPHONE_STATUS_ONLINE, "sip-online.png" }, + { LINPHONE_STATUS_BUSY, "sip-busy.png" }, + { LINPHONE_STATUS_BERIGHTBACK, "sip-bifm.png" }, + { LINPHONE_STATUS_AWAY, "sip-away.png" }, + { LINPHONE_STATUS_ONTHEPHONE, "sip-otp.png" }, + { LINPHONE_STATUS_OUTTOLUNCH, "sip-otl.png" }, + { LINPHONE_STATUS_NOT_DISTURB, "sip-closed.png" }, + { LINPHONE_STATUS_MOVED, "sip-closed.png" }, + { LINPHONE_STATUS_ALT_SERVICE, "sip-closed.png" }, + { LINPHONE_STATUS_OFFLINE, "sip-away.png" }, + { LINPHONE_STATUS_PENDING, "sip-wfa.png" }, + { LINPHONE_STATUS_CLOSED, "sip-closed.png" }, + { LINPHONE_STATUS_END, NULL }, +}; + +static GdkPixbuf *create_status_picture(LinphoneOnlineStatus ss){ + status_picture_tab_t *t=status_picture_tab; + while(t->img!=NULL){ + if (ss==t->status){ + GdkPixbuf *pixbuf; + pixbuf = create_pixbuf(t->img); + return pixbuf; + } + ++t; + } + g_error("No pixmap defined for status %i",ss); + return NULL; +} + +void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){ + GtkTreeIter iter; + LinphoneFriend *tmp=0; + gboolean found=FALSE; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); + if (gtk_tree_model_get_iter_first(model,&iter)) { + do{ + gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1); + //printf("tmp=%i, fid=%i",tmp,fid); + if (fid==tmp) { + GdkPixbuf *pixbuf; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1); + pixbuf = create_pixbuf(img); + if (pixbuf) + { + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } + found=TRUE; + } + }while(gtk_tree_model_iter_next(model,&iter)); + } + +} + + +static void linphone_gtk_set_selection_to_uri_bar(GtkTreeView *treeview){ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneFriend *lf=NULL; + gchar* friend; + select = gtk_tree_view_get_selection (treeview); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + friend=linphone_friend_get_url(lf); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),friend); + ms_free(friend); + } +} + +static void linphone_gtk_call_selected(GtkTreeView *treeview){ + linphone_gtk_set_selection_to_uri_bar(treeview); + linphone_gtk_start_call(linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(treeview)), + "start_call")); +} + +void linphone_gtk_contact_activated(GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data) +{ + linphone_gtk_set_selection_to_uri_bar(treeview); +} + +static GtkWidget * create_presence_menu(){ + GtkWidget *menu=gtk_menu_new(); + GtkWidget *menu_item; + GdkPixbuf *pbuf; + status_picture_tab_t *t; + for(t=status_picture_tab;t->img!=NULL;++t){ + if (t->status==LINPHONE_STATUS_UNKNOWN || + t->status==LINPHONE_STATUS_PENDING){ + continue; + } + menu_item=gtk_image_menu_item_new_with_label(linphone_online_status_to_string(t->status)); + pbuf=create_status_picture(t->status); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), + gtk_image_new_from_pixbuf(pbuf)); + g_object_unref(G_OBJECT(pbuf)); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_set_my_presence,GINT_TO_POINTER(t->status)); + } + return menu; +} + +void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss){ + GtkWidget *button=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"presence_button"); + GdkPixbuf *pbuf=create_status_picture(ss); + GtkWidget *image=gtk_image_new_from_pixbuf(pbuf); + GtkWidget *menu; + g_object_unref(G_OBJECT(pbuf)); + gtk_button_set_label(GTK_BUTTON(button),linphone_online_status_to_string(ss)); + gtk_button_set_image(GTK_BUTTON(button),image); + /*prepare menu*/ + menu=(GtkWidget*)g_object_get_data(G_OBJECT(button),"presence_menu"); + if (menu==NULL){ + menu=create_presence_menu(); + /*the menu is destroyed when the button is destroyed*/ + g_object_weak_ref(G_OBJECT(button),(GWeakNotify)gtk_widget_destroy,menu); + g_object_set_data(G_OBJECT(button),"presence_menu",menu); + } + linphone_core_set_presence_info(linphone_gtk_get_core(),0,NULL,ss); +} + +void linphone_gtk_my_presence_clicked(GtkWidget *button){ + GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(button),"presence_menu"); + gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0, + gtk_get_current_event_time()); + gtk_widget_show(menu); +} + + +static void linphone_gtk_friend_list_init(GtkWidget *friendlist) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + + + store = gtk_list_store_new(FRIEND_LIST_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, + G_TYPE_STRING); + /* need to add friends to the store here ...*/ + + gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes (NULL, + renderer, + "pixbuf", FRIEND_PRESENCE_IMG, + NULL); + gtk_tree_view_column_set_min_width (column, 29); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", FRIEND_NAME, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); + + column = gtk_tree_view_column_new_with_attributes (_("Presence status"), + renderer, + "text", FRIEND_PRESENCE_STATUS, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); + + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (friendlist)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + + gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(friendlist),FRIEND_SIP_ADDRESS); + + gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget( + gtk_widget_get_toplevel(friendlist),"show_category")),0); +} + +void linphone_gtk_show_friends(void){ + GtkWidget *mw=linphone_gtk_get_main_window(); + GtkWidget *friendlist=linphone_gtk_get_widget(mw,"contact_list"); + GtkListStore *store=NULL; + GtkTreeIter iter; + const MSList *itf; + GtkWidget *category=linphone_gtk_get_widget(mw,"show_category"); + GtkWidget *filter=linphone_gtk_get_widget(mw,"search_bar"); + LinphoneCore *core=linphone_gtk_get_core(); + const gchar *search=NULL; + gboolean online_only=FALSE,lookup=FALSE; + + if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){ + linphone_gtk_friend_list_init(friendlist); + } + store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))); + gtk_list_store_clear(store); + + online_only=(gtk_combo_box_get_active(GTK_COMBO_BOX(category))==1); + search=gtk_entry_get_text(GTK_ENTRY(filter)); + if (search==NULL || search[0]=='\0') + lookup=FALSE; + else lookup=TRUE; + + for(itf=linphone_core_get_friend_list(core);itf!=NULL;itf=ms_list_next(itf)){ + LinphoneFriend *lf=(LinphoneFriend*)itf->data; + char *uri=linphone_friend_get_url(lf); + char *name=linphone_friend_get_name(lf); + char *addr=linphone_friend_get_addr(lf); + char *display=name; + char *escaped=NULL; + if (lookup){ + if (strstr(uri,search)==NULL){ + ms_free(uri); + if (name) ms_free(name); + if (addr) ms_free(addr); + continue; + } + } + if (!online_only || (linphone_friend_get_status(lf)!=LINPHONE_STATUS_OFFLINE)){ + if (name==NULL || name[0]=='\0') display=addr; + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,FRIEND_NAME, display, + FRIEND_PRESENCE_STATUS, linphone_online_status_to_string(linphone_friend_get_status(lf)), + FRIEND_ID,lf,-1); + gtk_list_store_set(store,&iter, + FRIEND_PRESENCE_IMG, create_status_picture(linphone_friend_get_status(lf)), + -1); + escaped=g_markup_escape_text(uri,-1); + gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1); + g_free(escaped); + } + ms_free(uri); + if (name) ms_free(name); + if (addr) ms_free(addr); + } +} + +void linphone_gtk_add_contact(void){ + GtkWidget *w=linphone_gtk_create_window("contact"); + gtk_widget_show(w); +} + +void linphone_gtk_remove_contact(GtkWidget *button){ + GtkWidget *w=gtk_widget_get_toplevel(button); + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneFriend *lf=NULL; + select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list"))); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + linphone_core_remove_friend(linphone_gtk_get_core(),lf); + linphone_gtk_show_friends(); + } +} + +void linphone_gtk_show_contact(LinphoneFriend *lf){ + GtkWidget *w=linphone_gtk_create_window("contact"); + char *uri,*name; + uri=linphone_friend_get_addr(lf); + name=linphone_friend_get_name(lf); + if (uri) { + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address")),uri); + ms_free(uri); + } + if (name){ + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name")),name); + ms_free(name); + } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")), + linphone_friend_get_send_subscribe(lf)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")), + linphone_friend_get_inc_subscribe_policy(lf)==LinphoneSPAccept); + g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + gtk_widget_show(w); +} + +void linphone_gtk_edit_contact(GtkWidget *button){ + GtkWidget *w=gtk_widget_get_toplevel(button); + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneFriend *lf=NULL; + select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list"))); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + linphone_gtk_show_contact(lf); + } +} + +void linphone_gtk_chat_selected(GtkWidget *item){ + GtkWidget *w=gtk_widget_get_toplevel(item); + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneFriend *lf=NULL; + select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list"))); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + char *uri; + gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + uri=linphone_friend_get_url(lf); + linphone_gtk_create_chatroom(uri); + ms_free(uri); + } +} + +void linphone_gtk_contact_cancel(GtkWidget *button){ + gtk_widget_destroy(gtk_widget_get_toplevel(button)); +} + +void linphone_gtk_contact_ok(GtkWidget *button){ + GtkWidget *w=gtk_widget_get_toplevel(button); + LinphoneFriend *lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(w),"friend_ref"); + gboolean editing=FALSE,show_presence,allow_presence; + const gchar *name,*uri; + if (lf==NULL){ + lf=linphone_friend_new(); + }else{ + editing=TRUE; + } + name=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name"))); + uri=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address"))); + show_presence=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence"))); + allow_presence=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence"))); + linphone_friend_set_sip_addr(lf,uri); + linphone_friend_set_name(lf,name); + linphone_friend_send_subscribe(lf,show_presence); + linphone_friend_set_inc_subscribe_policy(lf,allow_presence==TRUE ? LinphoneSPAccept : LinphoneSPDeny); + if (editing){ + linphone_friend_done(lf); + }else{ + linphone_core_add_friend(linphone_gtk_get_core(),lf); + } + linphone_gtk_show_friends(); + gtk_widget_destroy(w); +} + +static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ + GtkWidget *menu=gtk_menu_new(); + GtkWidget *menu_item; + gchar *call_label=NULL; + gchar *text_label=NULL; + gchar *name=NULL; + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *image; + g_signal_connect(G_OBJECT(menu), "selection-done", G_CALLBACK (gtk_widget_destroy), NULL); + select = gtk_tree_view_get_selection(GTK_TREE_VIEW(contact_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)){ + gtk_tree_model_get(model, &iter,FRIEND_NAME , &name, -1); + call_label=g_strdup_printf(_("Call %s"),name); + text_label=g_strdup_printf(_("Send text to %s"),name); + g_free(name); + }else g_warning("No selection"); + if (call_label){ + menu_item=gtk_image_menu_item_new_with_label(call_label); + image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); + gtk_widget_show(image); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_selected,contact_list); + } + if (text_label){ + menu_item=gtk_image_menu_item_new_with_label(text_label); + image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); + gtk_widget_show(image); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_chat_selected,contact_list); + } + menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_EDIT,NULL); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_edit_contact,contact_list); + menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE,NULL); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_remove_contact,contact_list); + menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_add_contact,contact_list); + gtk_widget_show(menu); + gtk_menu_attach_to_widget (GTK_MENU (menu), contact_list, NULL); + if (call_label) g_free(call_label); + if (text_label) g_free(text_label); + return menu; +} + + +gboolean linphone_gtk_popup_contact_menu(GtkWidget *list, GdkEventButton *event){ + GtkWidget *m=linphone_gtk_create_contact_menu(list); + gtk_menu_popup (GTK_MENU (m), NULL, NULL, NULL, NULL, + event ? event->button : 0, event ? event->time : gtk_get_current_event_time()); + return TRUE; +} + +gboolean linphone_gtk_contact_list_button_pressed(GtkWidget *widget, GdkEventButton *event){ + /* Ignore double-clicks and triple-clicks */ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + return linphone_gtk_popup_contact_menu(widget, event); + } + return FALSE; +} + diff --git a/linphone/gtk-glade/gtk-linphone.glade b/linphone/gtk-glade/gtk-linphone.glade new file mode 100644 index 000000000..8b2771f6d --- /dev/null +++ b/linphone/gtk-glade/gtk-linphone.glade @@ -0,0 +1,2417 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + linphone2.png + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + É_dition + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + _Properties + True + + + + True + gtk-preferences + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Modes + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio only + True + True + menuitem3 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio & Video + True + True + True + menuitem1 + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Aid_e + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Show logs + True + + + + gtk-dialog-info + + + + + + + True + _About + True + + + + True + gtk-about + + + + + + + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-close + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Terminate call + + + 1 + + + + + + + False + False + GTK_PACK_END + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-forward + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Start call + + + 1 + + + + + + + False + False + GTK_PACK_END + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Current call + True + + + label_item + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_OUT + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Show All +Show Online + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search: + + + 8 + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Display filters + True + + + label_item + + + + + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + GTK_BUTTONBOX_SPREAD + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + True + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-edit + True + 0 + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-remove + True + 0 + + + 2 + + + + + False + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Contact list</b> + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_OUT + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Proxy in use + True + + + label_item + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_OUT + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 4 + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + D + 0 + + + 3 + 4 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + # + 0 + + + 2 + 3 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + 1 + 2 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + * + 0 + + + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + C + 0 + + + 3 + 4 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 9 + 0 + + + 2 + 3 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 8 + 0 + + + 1 + 2 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 7 + 0 + + + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + B + 0 + + + 3 + 4 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + 0 + + + 2 + 3 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + 0 + + + 1 + 2 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 0 + + + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + A + 0 + + + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 0 + + + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 0 + + + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + 0 + + + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Digits + True + + + label_item + + + + + False + False + 1 + + + + + 1 + + + + + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + False + 2 + + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + linphone2.png + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Use IPv6 instead of IPv4 + 0 + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>IPv6 usage</b> + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + 1 + 2 + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Video RTP/UDP + + + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio RTP/UDP + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP (UDP) + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Ports used</b> + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Public IP address + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Stun server + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + + + + + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Firewall settings</b> + True + + + label_item + + + + + 2 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-network + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Network settings + + + 1 + + + + + tab + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-media-play + True + 0 + + + 1 + + + + + 1 + 2 + 4 + 5 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring sound + + + 4 + 5 + GTK_FILL + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + ALSA special device (optional) + + + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Capture device + + + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring device + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Playback device + + + GTK_FILL + GTK_FILL + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Sound + True + + + label_item + + + + + + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-missing-image + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Multimedia settings + + + 1 + + + + + tab + 1 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + This section defines your SIP address when not using a SIP account + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your display name (eg: John Doe): + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your username: + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your resulting SIP address: + + + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + 1 + 2 + 2 + 3 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Default identity + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Add + + + 1 + + + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-edit + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Edit + + + 1 + + + + + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Remove + + + 1 + + + + + + + 2 + + + + + False + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Proxy accounts + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Erase all passwords + + + 1 + + + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Privacy + True + + + label_item + + + + + 2 + + + + + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + stock_people.png + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Manage SIP Accounts + + + 1 + + + + + tab + 2 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Audio codecs +Video codecs + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_OUT + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-up + True + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-down + True + 0 + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-yes + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Enable + + + 1 + + + + + + + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-no + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Disable + + + 1 + + + + + + + 3 + + + + + False + 1 + + + + + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Codecs + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + 0 -1 100000 1 10 10 + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + 0 -1 100000 1 10 10 + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Upload limit in kbits/sec + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Download limit in kbits/sec + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Bandwidth usage + True + + + label_item + + + + + 1 + + + + + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-execute + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Codecs + + + 1 + + + + + tab + 3 + False + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-close + True + 0 + + + + + 1 + + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Linphone - Configure a SIP account + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 0 100000 1 10 10 + + + 1 + 2 + 3 + 4 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Registration period (sec): + + + 3 + 4 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Route (optional): + + + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP Proxy address: + + + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your SIP identity: + + + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Publish presence information + 0 + True + + + False + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Configure a SIP account + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + 1 + + + + + False + GTK_PACK_END + + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Linphone - Authentication required + True + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Please enter your password for domain... + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP Address + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Name + + + GTK_FILL + + + + + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Show this contact presence status + 0 + True + True + + + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Allow this contact to see my presence status + 0 + True + True + + + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Contact information + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/incoming_call.glade b/linphone/gtk-glade/incoming_call.glade new file mode 100644 index 000000000..303c815f9 --- /dev/null +++ b/linphone/gtk-glade/incoming_call.glade @@ -0,0 +1,140 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WINDOW_POPUP + Linphone - Incoming call + True + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_NOTIFICATION + True + False + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Incoming call from + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Incoming call + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_SPREAD + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-yes + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Accept + + + 1 + + + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-no + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Decline + + + 1 + + + + + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/linphone.dev b/linphone/gtk-glade/linphone.dev new file mode 100755 index 000000000..b4a14f0d9 --- /dev/null +++ b/linphone/gtk-glade/linphone.dev @@ -0,0 +1,165 @@ +[Project] +FileName=linphone.dev +Name=linphone +UnitCount=8 +PchHead=-1 +PchSource=-1 +Ver=3 +IsCpp=1 +ProfilesCount=2 +ProfileIndex=0 +Folders= + +[Unit1] +FileName=support.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=calllogs.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=chat.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=friendlist.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=linphone.h +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=logging.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=main.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=propertybox.c +CompileCpp=0 +Folder=linphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription= +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 + +[Profile1] +ProfileName=Mingw 3.4.2 +Type=0 +ObjFiles= +Includes=C:\Dev-Cpp\gtk+2.12\include\gtk-2.0;C:\Dev-Cpp\gtk+2.12\include\libglade-2.0;../coreapi;C:\Dev-Cpp\gtk+2.12\include\cairo;C:\Dev-Cpp\gtk+2.12\include\pango-1.0;C:\Dev-Cpp\gtk+2.12\include\glib-2.0;C:\Dev-Cpp\gtk+2.12\lib\glib-2.0\include;C:\Dev-Cpp\gtk+2.12\lib\gtk-2.0\include;C:\Dev-Cpp\gtk+2.12\include\atk-1.0;../../linphone-deps/include;../oRTP/include;../mediastreamer2/include;C:\Dev-Cpp\gtk+2.12\include +Libs=../win32;C:\Dev-Cpp\gtk+2.12\lib;../mediastreamer2/build/win32native;../oRTP/build/win32native;../../linphone-deps/lib +ResourceIncludes= +MakeIncludes= +Compiler=-ggdb -O2_@@_-DENABLE_NLS_@@__@@_ +CppCompiler= +Linker=-mwindows_@@_-Wl,--export-all-symbols_@@_-Wl,--add-stdcall-alias_@@_-llinphone_@@_-lmediastreamer2_@@_-lortp_@@_-lglade-2.0_@@_-lgtk-win32-2.0_@@_-lglib-2.0_@@_-lintl_@@_-lgdk_pixbuf-2.0_@@_-latk-1.0_@@_-lgobject-2.0_@@_-lgthread-2.0_@@_-lgdk-win32-2.0_@@_-losip2_@@_-losipparser2_@@_-leXosip2_@@_-lws2_32_@@_ +PreprocDefines= +CompilerSettings=0000000000000000000000 +Icon=linphone.ico +ExeOutput= +ObjectOutput=Objects +OverrideOutput=0 +OverrideOutputName=linphone.exe +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + +[Profile2] +ProfileName=MS VC++ 2005 +Type=1 +ObjFiles= +Includes= +Libs= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +PreprocDefines= +CompilerSettings=000000000000010000000000000000000000 +Icon= +ExeOutput=Output\MSVC++2005 +ObjectOutput=Objects\MSVC++2005 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +compilerType=1 + diff --git a/linphone/gtk-glade/linphone.h b/linphone/gtk-glade/linphone.h new file mode 100644 index 000000000..e0ccc8446 --- /dev/null +++ b/linphone/gtk-glade/linphone.h @@ -0,0 +1,53 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define PACKAGE_DATA_DIR "./" +#define LINPHONE_VERSION "2.99.4" +#endif + +#include +#include "linphonecore.h" + +#include +#define _(String) gettext (String) + +GdkPixbuf * create_pixbuf(const gchar *filename); +void add_pixmap_directory(const gchar *directory); +GtkWidget *linphone_gtk_create_window(const char *window_name); +GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); +LinphoneCore *linphone_gtk_get_core(void); +GtkWidget *linphone_gtk_get_main_window(); +void linphone_gtk_start_call(GtkWidget *button); +void linphone_gtk_show_friends(void); +void linphone_gtk_show_contact(LinphoneFriend *lf); +void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss); +void linphone_gtk_show_parameters(void); +void linphone_gtk_load_identities(void); +void linphone_gtk_create_chatroom(const char *with); +void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message); +void linphone_gtk_call_log_update(GtkWidget *w); +void linphone_gtk_create_log_window(void); +void linphone_gtk_log_show(void); +void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args); +void linphone_gtk_destroy_log_window(void); +gboolean linphone_gtk_check_logs(); + diff --git a/linphone/gtk-glade/linphone.iss b/linphone/gtk-glade/linphone.iss new file mode 100755 index 000000000..c5808db71 --- /dev/null +++ b/linphone/gtk-glade/linphone.iss @@ -0,0 +1,69 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +[Setup] +AppName=Linphone +AppVerName=Linphone for windows 2.99.4 (gtk/glade interface based on liblinphone) +AppPublisher=linphone.org +AppPublisherURL=http://www.linphone.org +AppSupportURL=http://www.linphone.org +AppUpdatesURL=http://www.linphone.org +DefaultDirName={pf}\Linphone +DefaultGroupName=Linphone +LicenseFile=C:\Documents and Settings\simorl.EMEA\cvs\linphone\COPYING +InfoBeforeFile=C:\Documents and Settings\simorl.EMEA\cvs\linphone\README +OutputBaseFilename=setup +Compression=lzma +SolidCompression=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\gtk-glade\linphone.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\build\win32native\mediastream.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\gtk-glade\*.glade"; DestDir: "{app}/linphone"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\pixmaps\*.png"; DestDir: "{app}/linphone"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\pixmaps\*.png"; DestDir: "{app}/pixmaps"; Flags: ignoreversion +Source: "C:\Dev-Cpp\gtk+2.12\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Dev-Cpp\gtk+2.12\etc\gtk-2.0\*"; DestDir: "{app}\etc\gtk-2.0\"; Flags: ignoreversion +Source: "C:\Dev-Cpp\libxml2-2.6.32+.win32\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Dev-Cpp\iconv-1.9.2.win32\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Dev-Cpp\gtk+2.12\lib\gtk-2.0\2.10.0\engines\*"; DestDir: "{app}\lib\gtk-2.0\2.10.0\engines"; Flags: ignoreversion +Source: "C:\Dev-Cpp\gtk+2.12\lib\gtk-2.0\2.10.0\loaders\*"; DestDir: "{app}\lib\gtk-2.0\2.10.0\loaders"; Flags: ignoreversion +Source: "C:\Dev-Cpp\gtk+2.12\lib\gtk-2.0\2.10.0\immodules\*"; DestDir: "{app}\lib\gtk-2.0\2.10.0\immodules"; Flags: ignoreversion +; all icons: +;Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\win32\linphonec.exe"; DestDir: "{app}"; Flags: ignoreversion +;Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\win32\linphonec-remote.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\src\nowebcamCIF.jpg"; DestDir: "{app}\images"; Flags: ignoreversion + +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\COPYING"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\ringback.wav"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\rings\orig.wav"; DestDir: "{app}\rings"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\rings\bigben.wav"; DestDir: "{app}\rings"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\rings\toy.wav"; DestDir: "{app}\rings"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\rings\tapping.wav"; DestDir: "{app}\rings"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\share\rings\oldphone.wav"; DestDir: "{app}\rings"; Flags: ignoreversion + +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\osipparser2.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\osip2.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\exosip2.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\libogg.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\speex.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\avcodec.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone-deps\bin\avutil.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\build\win32native\mediastreamer2.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\oRTP\build\win32native\ortp.dll"; DestDir: "{app}"; Flags: ignoreversion + +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\Linphone"; Filename: "{app}\linphone.exe" ; WorkingDir: "{app}" +Name: "{userdesktop}\Linphone"; Filename: "{app}\linphone.exe"; WorkingDir: "{app}" ; Tasks: desktopicon + +[Run] +Filename: "{app}\linphone.exe"; Description: "{cm:LaunchProgram,Linphone}"; WorkingDir: "{app}" ; Flags: nowait postinstall skipifsilent + diff --git a/linphone/gtk-glade/linphone.png b/linphone/gtk-glade/linphone.png new file mode 100644 index 0000000000000000000000000000000000000000..06cf18315e755813a393d246ba1d27d51c0aaaeb GIT binary patch literal 11971 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 V7sWprRrO3P?wqO6LN1et%fjmaN&|?tY)=KKHrr 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 literal 0 HcmV?d00001 diff --git a/linphone/gtk-glade/log.glade b/linphone/gtk-glade/log.glade new file mode 100644 index 000000000..0dfc558de --- /dev/null +++ b/linphone/gtk-glade/log.glade @@ -0,0 +1,71 @@ + + + + + + 540 + 290 + 5 + Linphone debug window + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + False + + + + True + 2 + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_CORNER_BOTTOM_LEFT + True + GTK_SHADOW_IN + + + True + True + False + GTK_WRAP_WORD + + + + + 1 + + + + + True + GTK_BUTTONBOX_END + + + + + + True + True + True + gtk-close + True + 0 + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/logging.c b/linphone/gtk-glade/logging.c new file mode 100644 index 000000000..a8211d1ea --- /dev/null +++ b/linphone/gtk-glade/logging.c @@ -0,0 +1,125 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" + +static GtkWidget *log_window=NULL; +static GStaticMutex log_mutex=G_STATIC_MUTEX_INIT; +static GList *log_queue=NULL; + +typedef struct _LinphoneGtkLog{ + OrtpLogLevel lev; + gchar *msg; +}LinphoneGtkLog; + +void linphone_gtk_create_log_window(void){ + GtkTextBuffer *b; + log_window=linphone_gtk_create_window("log"); + b=gtk_text_view_get_buffer(GTK_TEXT_VIEW(linphone_gtk_get_widget(log_window,"textview"))); + gtk_text_buffer_create_tag(b,"red","foreground","red",NULL); + gtk_text_buffer_create_tag(b,"orange","foreground","orange",NULL); +} + +void linphone_gtk_destroy_log_window(void){ + GtkWidget *w=log_window; + g_static_mutex_lock(&log_mutex); + log_window=NULL; + gtk_widget_destroy(w); + g_static_mutex_unlock(&log_mutex); +} + +void linphone_gtk_log_show(void){ + gtk_widget_show(log_window); + gtk_window_present(GTK_WINDOW(log_window)); +} + +static void linphone_gtk_display_log(OrtpLogLevel lev, const char *msg){ + GtkTextIter iter,begin; + int off; + static GtkTextView *v=NULL; + GtkTextBuffer *b; + const char *lname="undef"; + + if (log_window==NULL) { + return; + } + + if (v==NULL) v=GTK_TEXT_VIEW(linphone_gtk_get_widget(log_window,"textview")); + b=gtk_text_view_get_buffer(v); + switch(lev){ + case ORTP_DEBUG: + lname="debug"; + break; + case ORTP_MESSAGE: + lname="message"; + break; + case ORTP_WARNING: + lname="warning"; + break; + case ORTP_ERROR: + lname="error"; + break; + case ORTP_FATAL: + lname="fatal"; + break; + default: + g_error("Bad level !"); + } + gtk_text_buffer_get_end_iter(b,&iter); + off=gtk_text_iter_get_offset(&iter); + gtk_text_buffer_insert(b,&iter,lname,-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,": ",-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,msg,-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_insert(b,&iter,"\n",-1); + gtk_text_buffer_get_end_iter(b,&iter); + gtk_text_buffer_get_iter_at_offset(b,&begin,off); + if (lev==ORTP_ERROR || lev==ORTP_FATAL) gtk_text_buffer_apply_tag_by_name(b,"red",&begin,&iter); + else if (lev==ORTP_WARNING) gtk_text_buffer_apply_tag_by_name(b,"orange",&begin,&iter); + gtk_text_buffer_get_end_iter(b,&iter); + //gtk_text_view_scroll_to_iter(v,&iter,0,FALSE,0,0); +} + +gboolean linphone_gtk_check_logs(){ + GList *elem; + g_static_mutex_lock(&log_mutex); + for(elem=log_queue;elem!=NULL;elem=elem->next){ + LinphoneGtkLog *lgl=(LinphoneGtkLog*)elem->data; + linphone_gtk_display_log(lgl->lev,lgl->msg); + g_free(lgl->msg); + g_free(lgl); + } + if (log_queue) g_list_free(log_queue); + log_queue=NULL; + g_static_mutex_unlock(&log_mutex); + return TRUE; +} + +void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args){ + gchar *msg=g_strdup_vprintf(fmt,args); + LinphoneGtkLog *lgl=g_new(LinphoneGtkLog,1); + lgl->lev=lev; + lgl->msg=msg; + g_static_mutex_lock(&log_mutex); + log_queue=g_list_append(log_queue,lgl); + g_static_mutex_unlock(&log_mutex); +} + diff --git a/linphone/gtk-glade/main.c b/linphone/gtk-glade/main.c new file mode 100644 index 000000000..5a59e443a --- /dev/null +++ b/linphone/gtk-glade/main.c @@ -0,0 +1,725 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define USE_LIBGLADE 1 + +#include "lpconfig.h" + +#include "linphone.h" + +#ifdef USE_LIBGLADE +#include +#endif + +#include +#include +#include + +#ifndef GETTEXT_PACKAGE +#define GETTEXT_PACKAGE "linphone" +#endif + +#ifndef PACKAGE_LOCALE_DIR +#define PACKAGE_LOCALE_DIR "po" +#endif + + +static LinphoneCore *the_core=NULL; +static GtkWidget *the_ui=NULL; + +static void linphone_gtk_show(LinphoneCore *lc); +static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from); +static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from); +static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img); +static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url); +static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username); +static void linphone_gtk_display_status(LinphoneCore *lc, const char *status); +static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg); +static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning); +static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url); +static void linphone_gtk_display_question(LinphoneCore *lc, const char *question); +static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl); +static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate); + +static LinphoneCoreVTable vtable={ + .show=linphone_gtk_show, + .inv_recv=linphone_gtk_inv_recv, + .bye_recv=linphone_gtk_bye_recv, + .notify_recv=linphone_gtk_notify_recv, + .new_unknown_subscriber=linphone_gtk_new_unknown_subscriber, + .auth_info_requested=linphone_gtk_auth_info_requested, + .display_status=linphone_gtk_display_status, + .display_message=linphone_gtk_display_message, + .display_warning=linphone_gtk_display_warning, + .display_url=linphone_gtk_display_url, + .display_question=linphone_gtk_display_question, + .call_log_updated=linphone_gtk_call_log_updated, + .text_received=linphone_gtk_text_received, + .general_state=linphone_gtk_general_state +}; + +static gboolean verbose=0; +static GOptionEntry linphone_options[2]={ + { + .long_name="verbose", + .short_name= '\0', + .arg=G_OPTION_ARG_NONE, + .arg_data= (gpointer)&verbose, + .description="log to stdout some debug information while running." + } +}; + +#define INSTALLED_XML_DIR PACKAGE_DATA_DIR "/linphone" +#define BUILD_TREE_XML_DIR "gtk-glade" +#define CONFIG_FILE ".linphonerc" + +static void linphone_gtk_init_liblinphone(){ + const char *home; + char file[1024]; + /*try accessing a local file first if exists*/ + if (access(CONFIG_FILE,F_OK)==0){ + snprintf(file,sizeof(file),"%s",CONFIG_FILE); + }else{ +#ifdef WIN32 + const char *appdata=getenv("APPDATA"); + if (appdata){ + snprintf(file,sizeof(file),"%s\\%s",appdata,"Linphone\\"); + CreateDirectory(file,NULL); + snprintf(file,sizeof(file),"%s\\%s",appdata,"Linphone\\linphonerc"); + } +#else + home=getenv("HOME"); + if (home==NULL) home=""; + snprintf(file,sizeof(file),"%s/%s",home,CONFIG_FILE); +#endif + } + the_core=linphone_core_new(&vtable,file,NULL); +} + + + +LinphoneCore *linphone_gtk_get_core(void){ + return the_core; +} + +GtkWidget *linphone_gtk_get_main_window(){ + return the_ui; +} + +#ifdef USE_LIBGLADE + +GtkWidget *linphone_gtk_create_window(const char *window_name){ + GtkWidget *w; + GladeXML *gxml; + char path[2048]; + snprintf(path,sizeof(path),"%s/%s.glade",BUILD_TREE_XML_DIR,window_name); + if (access(path,F_OK)!=0){ + snprintf(path,sizeof(path),"%s/%s.glade",INSTALLED_XML_DIR,window_name); + if (access(path,F_OK)!=0){ + g_error("Could not locate neither %s/%s.glade and %s/%s.glade .",BUILD_TREE_XML_DIR,window_name, + INSTALLED_XML_DIR,window_name); + return NULL; + } + } + gxml=glade_xml_new(path,NULL,NULL); + glade_xml_signal_autoconnect(gxml); + w=glade_xml_get_widget(gxml,window_name); + if (w==NULL) g_error("Could not retrieve '%s' window from xml file",window_name); + return w; +} + +GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){ + GtkWidget *w; + GladeXML *gxml=glade_get_widget_tree(window); + if (gxml==NULL) g_error("Could not retrieve XML tree of window %s",name); + w=glade_xml_get_widget(gxml,name); + if (w==NULL) g_error("Could not retrieve widget %s",name); + return GTK_WIDGET(w); +} + +#else + +GtkWidget *linphone_gtk_create_window(const char *window_name){ + +} + +GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){ + GObject *w=gtk_builder_get_object(the_ui,name); + if (w==NULL){ + g_error("No widget named %s found in xml interface.",name); + } + return GTK_WIDGET(w); +} + +#endif + +void linphone_gtk_display_something(GtkMessageType type,const gchar *message){ + GtkWidget *dialog; + GtkWidget *main_window=linphone_gtk_get_main_window(); + + gtk_widget_show(main_window); + if (type==GTK_MESSAGE_QUESTION) + { + /* draw a question box. link to dialog_click callback */ + dialog = gtk_message_dialog_new ( + GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + (const gchar*)message); + /* connect to some callback : REVISIT */ + /* + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (dialog_click), + G_OBJECT (dialog)); + */ + /* actually show the box */ + gtk_widget_show(dialog); + } + else + { + dialog = gtk_message_dialog_new (GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + GTK_BUTTONS_CLOSE, + (const gchar*)message); + /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); + gtk_widget_show(dialog); + } +} + +void linphone_gtk_about_response(GtkDialog *dialog, gint id){ + if (id==GTK_RESPONSE_CANCEL){ + gtk_widget_destroy(GTK_WIDGET(dialog)); + } +} + +void linphone_gtk_show_about(){ + struct stat filestat; + const char *license_file=PACKAGE_DATA_DIR "/doc/COPYING"; + GtkWidget *about; + + about=linphone_gtk_create_window("about"); + memset(&filestat,0,sizeof(filestat)); + if (stat(license_file,&filestat)!=0){ + license_file="COPYING"; + stat(license_file,&filestat); + } + if (filestat.st_size>0){ + char *license=g_malloc(filestat.st_size+1); + FILE *f=fopen(license_file,"r"); + if (f && fread(license,filestat.st_size,1,f)==1){ + license[filestat.st_size]='\0'; + gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),license); + } + g_free(license); + } + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LINPHONE_VERSION); + + gtk_widget_show(about); +} + +static gboolean linphone_gtk_iterate(LinphoneCore *lc){ + linphone_core_iterate(lc); + return TRUE; +} + +static void load_uri_history(){ + GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")); + LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core()); + char key[20]; + int i; + GtkEntryCompletion *gep=gtk_entry_completion_new(); + GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING); + for (i=0;;i++){ + const char *uri; + snprintf(key,sizeof(key),"uri%i",i); + uri=lp_config_get_string(cfg,"GtkUi",key,NULL); + if (uri!=NULL) { + GtkTreeIter iter; + gtk_list_store_append(model,&iter); + gtk_list_store_set(model,&iter,0,uri,-1); + if (i==0) gtk_entry_set_text(uribar,uri); + } + else break; + } + gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model)); + gtk_entry_completion_set_text_column(gep,0); + gtk_entry_set_completion(uribar,gep); +} + +static void save_uri_history(){ + LinphoneCore *lc=linphone_gtk_get_core(); + LpConfig *cfg=linphone_core_get_config(lc); + GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")); + char key[20]; + int i=0; + char *uri=NULL; + GtkTreeIter iter; + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar)); + + if (!gtk_tree_model_get_iter_first(model,&iter)) return; + do { + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri) { + snprintf(key,sizeof(key),"uri%i",i); + lp_config_set_string(cfg,"GtkUi",key,uri); + g_free(uri); + }else break; + i++; + if (i>5) break; + }while(gtk_tree_model_iter_next(model,&iter)); + lp_config_sync(cfg); +} + +static void completion_add_text(GtkEntry *entry, const char *text){ + GtkTreeIter iter; + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry)); + + if (gtk_tree_model_get_iter_first(model,&iter)){ + do { + gchar *uri=NULL; + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri!=NULL){ + if (strcmp(uri,text)==0) { + /*remove text */ + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + g_free(uri); + break; + } + g_free(uri); + } + }while (gtk_tree_model_iter_next(model,&iter)); + } + /* and prepend it on top of the list */ + gtk_list_store_prepend(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1); + save_uri_history(); +} + +static void linphone_gtk_call_started(GtkWidget *mw){ + gtk_widget_hide(linphone_gtk_get_widget(mw,"start_call")); + gtk_widget_show(linphone_gtk_get_widget(mw,"terminate_call")); +} + +void linphone_gtk_start_call(GtkWidget *button){ + LinphoneCore *lc=linphone_gtk_get_core(); + if (linphone_core_inc_invite_pending(lc)){ + /*already in call */ + }else{ + GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"uribar"); + const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar)); + if (linphone_core_invite(lc,entered)==0) { + linphone_gtk_call_started(linphone_gtk_get_main_window()); + completion_add_text(GTK_ENTRY(uri_bar),entered); + } + } +} + +static void linphone_gtk_call_terminated(GtkWidget *mw){ + gtk_widget_hide(linphone_gtk_get_widget(mw,"terminate_call")); + gtk_widget_show(linphone_gtk_get_widget(mw,"start_call")); + g_object_set_data(G_OBJECT(mw),"incoming_call",NULL); +} + +void linphone_gtk_terminate_call(GtkWidget *button){ + linphone_core_terminate_call(linphone_gtk_get_core(),NULL); + linphone_gtk_call_terminated(gtk_widget_get_toplevel(button)); +} + +void linphone_gtk_decline_call(GtkWidget *button){ + linphone_core_terminate_call(linphone_gtk_get_core(),NULL); + linphone_gtk_call_terminated(gtk_widget_get_toplevel(button)); + gtk_widget_destroy(gtk_widget_get_toplevel(button)); +} + +void linphone_gtk_accept_call(GtkWidget *button){ + linphone_core_accept_call(linphone_gtk_get_core(),NULL); + g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",NULL); + gtk_widget_destroy(gtk_widget_get_toplevel(button)); + linphone_gtk_call_started(linphone_gtk_get_main_window()); +} + +void linphone_gtk_set_audio_video(){ + linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE); +} + +void linphone_gtk_set_audio_only(){ + linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE); +} + +void linphone_gtk_used_identity_changed(GtkWidget *w){ + int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w)); + char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + if (sel && strlen(sel)>0) //avoid a dummy "changed" at gui startup + linphone_core_set_default_proxy_index(linphone_gtk_get_core(),(active==0) ? -1 : (active-1)); +} + +static void linphone_gtk_show_main_window(){ + GtkWidget *w=linphone_gtk_get_main_window(); + LinphoneCore *lc=linphone_gtk_get_core(); + linphone_core_enable_video_preview(lc,linphone_core_video_enabled(lc)); + gtk_widget_show(w); + gtk_window_present(GTK_WINDOW(w)); +} + +static void linphone_gtk_show(LinphoneCore *lc){ + linphone_gtk_show_main_window(); +} + +static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){ + GtkWidget *w=linphone_gtk_create_window("incoming_call"); + GtkWidget *label; + gchar *msg; + gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window())); + gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT); + + label=linphone_gtk_get_widget(w,"message"); + msg=g_strdup_printf(_("Incoming call from %s"),from); + gtk_label_set_text(GTK_LABEL(label),msg); + gtk_window_set_title(GTK_WINDOW(w),msg); + gtk_widget_show(w); + gtk_window_present(GTK_WINDOW(w)); + /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/ + g_free(msg); + g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")), + from); +} + +static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){ + GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call")); + if (icw!=NULL){ + gtk_widget_destroy(icw); + } + linphone_gtk_call_terminated(linphone_gtk_get_main_window()); +} + +static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img){ +} + +static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){ + switch(response_id){ + case GTK_RESPONSE_YES: + linphone_gtk_show_contact(lf); + break; + default: + linphone_core_reject_subscriber(linphone_gtk_get_core(),lf); + } + gtk_widget_destroy(dialog); +} + +static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ + GtkWidget *dialog; + gchar *message=g_strdup_printf(_("%s would like to add you to his contact list.\nWould you allow him to see your presence status or add him to your contact list ?\nIf you answer no, this person will be temporarily blacklisted."),url); + dialog = gtk_message_dialog_new ( + GTK_WINDOW(linphone_gtk_get_main_window()), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + message); + g_free(message); + g_signal_connect(G_OBJECT (dialog), "response", + G_CALLBACK (linphone_gtk_new_subscriber_response),lf); + /* actually show the box */ + gtk_widget_show(dialog); +} + +typedef struct _AuthTimeout{ + GtkWidget *w; +} AuthTimeout; + + +static void auth_timeout_clean(AuthTimeout *tout){ + tout->w=NULL; +} + +static gboolean auth_timeout_destroy(AuthTimeout *tout){ + if (tout->w) { + g_object_weak_unref(G_OBJECT(tout->w),(GWeakNotify)auth_timeout_clean,tout); + gtk_widget_destroy(tout->w); + } + g_free(tout); + return FALSE; +} + +static AuthTimeout * auth_timeout_new(GtkWidget *w){ + AuthTimeout *tout=g_new(AuthTimeout,1); + tout->w=w; + /*so that the timeout no more references the widget when it is destroyed:*/ + g_object_weak_ref(G_OBJECT(w),(GWeakNotify)auth_timeout_clean,tout); + /*so that the widget is automatically destroyed after some time */ + g_timeout_add(30000,(GtkFunction)auth_timeout_destroy,tout); + return tout; +} + +void linphone_gtk_password_cancel(GtkWidget *w){ + LinphoneAuthInfo *info; + GtkWidget *window=gtk_widget_get_toplevel(w); + info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info"); + linphone_core_abort_authentication(linphone_gtk_get_core(),info); + gtk_widget_destroy(window); +} + +void linphone_gtk_password_ok(GtkWidget *w){ + GtkWidget *entry; + GtkWidget *window=gtk_widget_get_toplevel(w); + LinphoneAuthInfo *info; + info=(LinphoneAuthInfo*)g_object_get_data(G_OBJECT(window),"auth_info"); + g_object_weak_unref(G_OBJECT(window),(GWeakNotify)linphone_auth_info_destroy,info); + entry=linphone_gtk_get_widget(window,"password_entry"); + linphone_auth_info_set_passwd(info,gtk_entry_get_text(GTK_ENTRY(entry))); + linphone_core_add_auth_info(linphone_gtk_get_core(),info); + gtk_widget_destroy(window); +} + +static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){ + GtkWidget *w=linphone_gtk_create_window("password"); + GtkWidget *label=linphone_gtk_get_widget(w,"message"); + LinphoneAuthInfo *info; + gchar *msg; + msg=g_strdup_printf(_("Please enter your password for domain %s:"),realm); + gtk_label_set_text(GTK_LABEL(label),msg); + g_free(msg); + info=linphone_auth_info_new(username, NULL, NULL, NULL,realm); + g_object_set_data(G_OBJECT(w),"auth_info",info); + g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_auth_info_destroy,info); + gtk_widget_show(w); + auth_timeout_new(w); +} + +static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){ + GtkWidget *w=linphone_gtk_get_main_window(); + GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar"); + gtk_statusbar_push(GTK_STATUSBAR(status_bar), + gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""), + status); +} + +static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){ + linphone_gtk_display_something(GTK_MESSAGE_INFO,msg); +} + +static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){ + linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning); +} + +static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){ + char richtext[4096]; + snprintf(richtext,sizeof(richtext),"%s %s",msg,url); + linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext); +} + +static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){ + linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question); +} + +static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){ + GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs"); + if (w) linphone_gtk_call_log_update(w); +} + +static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){ +} + + +static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){ + GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu"); + gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time); +} + +static GtkWidget *create_icon_menu(){ + GtkWidget *menu=gtk_menu_new(); + GtkWidget *menu_item; + menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_about,NULL); + menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)gtk_main_quit,NULL); + gtk_widget_show(menu); + return menu; +} + +static void linphone_gtk_init_status_icon(){ + GtkStatusIcon *icon; + GdkPixbuf *pbuf=create_pixbuf("linphone2.png"); + GtkWidget *menu=create_icon_menu(); + icon=gtk_status_icon_new_from_pixbuf(pbuf); + g_object_unref(G_OBJECT(pbuf)); + g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)linphone_gtk_show_main_window,linphone_gtk_get_main_window()); + g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL); + gtk_status_icon_set_tooltip(icon,_("Linphone - a video internet phone")); + g_object_set_data(G_OBJECT(icon),"menu",menu); + g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu); +} + +void linphone_gtk_load_identities(void){ + const MSList *elem; + GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities")); + char *def_identity; + LinphoneProxyConfig *def=NULL; + int def_index=0,i; + GtkListStore *store; + + store=GTK_LIST_STORE(gtk_combo_box_get_model(box)); + gtk_list_store_clear(store); + + linphone_core_get_default_proxy(linphone_gtk_get_core(),&def); + def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core())); + gtk_combo_box_append_text(box,def_identity); + g_free(def_identity); + for(i=1,elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core()); + elem!=NULL; + elem=ms_list_next(elem),i++){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; + gtk_combo_box_append_text(box,linphone_proxy_config_get_identity(cfg)); + if (cfg==def) { + def_index=i; + } + } + gtk_combo_box_set_active(box,def_index); +} + +static void linphone_gtk_dtmf_clicked(GtkButton *button){ + const char *label=gtk_button_get_label(button); + linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]); +} + +static void linphone_gtk_connect_digits(void){ + GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table")); + GList *children=gtk_container_get_children(cont); + GList *elem; + for(elem=children;elem!=NULL;elem=elem->next){ + GtkButton *button=GTK_BUTTON(elem->data); + g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL); + } +} + +static void linphone_gtk_check_menu_items(void){ + bool_t audio_only=!linphone_core_video_enabled(linphone_gtk_get_core()); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(linphone_gtk_get_widget( + linphone_gtk_get_main_window(), + audio_only ? "audio_only_item" : "video_item")), TRUE); +} + +static void linphone_gtk_init_main_window(){ + load_uri_history(); + linphone_gtk_load_identities(); + linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core())); + linphone_gtk_show_friends(); + linphone_gtk_connect_digits(); + linphone_gtk_check_menu_items(); + if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started( + linphone_gtk_get_main_window());/*hide the call button, show terminate button*/ +} + +void linphone_gtk_close(){ + /* couldn't find a way to prevent closing to destroy the main window*/ + linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); + the_ui=NULL; + the_ui=linphone_gtk_create_window("main"); + linphone_gtk_init_main_window(); +} + +void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){ + if (verbose){ + const char *lname="undef"; + char *msg; + #ifdef __linux + va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/ + #endif + switch(lev){ + case ORTP_DEBUG: + lname="debug"; + break; + case ORTP_MESSAGE: + lname="message"; + break; + case ORTP_WARNING: + lname="warning"; + break; + case ORTP_ERROR: + lname="error"; + break; + case ORTP_FATAL: + lname="fatal"; + break; + default: + g_error("Bad level !"); + } +#ifdef __linux + va_copy(cap,args); + msg=g_strdup_vprintf(fmt,cap); + va_end(cap); +#else + msg=g_strdup_vprintf(fmt,args); +#endif + fprintf(stdout,"linphone-%s : %s\n",lname,msg); + ortp_free(msg); + } + linphone_gtk_log_push(lev,fmt,args); +} + +int main(int argc, char *argv[]){ + void *p; + g_thread_init(NULL); + gdk_threads_init(); +#ifdef ENABLE_NLS + p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + if (p==NULL) perror("bindtextdomain failed"); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); +#else + g_message("NLS disabled.\n"); +#endif + gdk_threads_enter(); + if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"), + linphone_options,NULL,NULL)){ + gdk_threads_leave(); + return -1; + } + + add_pixmap_directory("pixmaps"); + add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone"); + + the_ui=linphone_gtk_create_window("main"); + + linphone_gtk_create_log_window(); + linphone_core_enable_logs_with_cb(linphone_gtk_log_handler); + + linphone_gtk_init_liblinphone(); + gtk_timeout_add(20,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core()); + gtk_timeout_add(20,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL); + linphone_gtk_init_main_window(); + linphone_gtk_init_status_icon(); + gtk_widget_show(the_ui); + gtk_main(); + gdk_threads_leave(); + linphone_gtk_destroy_log_window(); + linphone_core_destroy(the_core); + return 0; +} + + diff --git a/linphone/gtk-glade/main.glade b/linphone/gtk-glade/main.glade new file mode 100644 index 000000000..d8eb57990 --- /dev/null +++ b/linphone/gtk-glade/main.glade @@ -0,0 +1,804 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + linphone2.png + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + É_dition + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + _Properties + True + + + + True + gtk-preferences + + + + + + + True + Call history + True + + + + True + gtk-info + + + + + + + True + gtk-quit + True + True + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Modes + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio only + True + True + video_item + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio & Video + True + True + True + audio_only_item + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Aid_e + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Show debug window + True + + + + gtk-dialog-info + + + + + + + True + _About + True + + + + True + gtk-about + + + + + + + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-close + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Terminate call + + + 1 + + + + + + + False + False + GTK_PACK_END + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-forward + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Start call + + + 1 + + + + + + + False + False + GTK_PACK_END + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Current call + True + + + label_item + + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Show All +Show Online + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search: + + + 8 + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Display filters + True + + + label_item + + + + + False + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + 120 + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + + + + + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Contact list</b> + True + + + label_item + + + + + 8 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 15 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 4 + True + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + D + 0 + + + 3 + 4 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + # + 0 + + + 2 + 3 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + 1 + 2 + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + * + 0 + + + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + C + 0 + + + 3 + 4 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 9 + 0 + + + 2 + 3 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 8 + 0 + + + 1 + 2 + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 7 + 0 + + + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + B + 0 + + + 3 + 4 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + 0 + + + 2 + 3 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + 0 + + + 1 + 2 + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 0 + + + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + A + 0 + + + 3 + 4 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 0 + + + 2 + 3 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 0 + + + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + 0 + + + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Digits + True + + + label_item + + + + + False + False + + + + + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Default + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + My identity : + True + + + label_item + + + + + False + False + 2 + + + + + 1 + + + + + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + + + True + True + True + 0 + + + + + + + False + 1 + + + + + False + 2 + + + + + + diff --git a/linphone/gtk-glade/parameters.glade b/linphone/gtk-glade/parameters.glade new file mode 100644 index 000000000..2061f0b91 --- /dev/null +++ b/linphone/gtk-glade/parameters.glade @@ -0,0 +1,1393 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + linphone2.png + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Use IPv6 instead of IPv4 + 0 + True + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>IPv6 usage</b> + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + + 1 + 2 + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 1 65535 1 10 10 + + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Video RTP/UDP + + + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Audio RTP/UDP + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP (UDP) + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Ports used</b> + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Public IP address + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Stun server + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + + + + + 1 + + + + + True + True + I'm not behing a firewall + 0 + True + True + + + + 2 + + + + + True + True + I'm behind a firewall, use supplied public IP address + 0 + True + True + no_nat + + + + 3 + + + + + True + True + Use the supplied stun server above and do as best as possible + 0 + True + True + no_nat + + + + 4 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Firewall settings</b> + True + + + label_item + + + + + 2 + + + + + True + 0 + GTK_SHADOW_NONE + + + True + 12 + + + True + 2 + 2 + + + + + + True + True + 500 500 3001 1 10 10 + + + + 1 + 2 + + + + + True + True + Set Maximum Transmission Unit + 0 + True + + + + + + True + True + Send DTMFs as SIP info + 0 + True + + + + 1 + 2 + + + + + + + + + True + <b>Miscelaneous</b> + True + + + label_item + + + + + 3 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-network + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Network settings + + + 1 + + + + + tab + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + 2 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-media-play + True + 0 + + + + 1 + + + + + 1 + 2 + 4 + 5 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring sound + + + 4 + 5 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + default soundcard + + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + default soundcard + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + ALSA special device (optional) + + + 3 + 4 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Capture device + + + 2 + 3 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring device + + + 1 + 2 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Playback device + + + GTK_FILL + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + a sound card + + + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + True + Enable echo cancelation + 0 + True + + + + 1 + 2 + 5 + 6 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Sound</b> + True + + + label_item + + + + + + + True + 0 + + + True + 12 + + + True + 1 + 2 + + + True + Video input device + + + GTK_EXPAND + + + + + True + default camera + + + + 1 + 2 + GTK_EXPAND + + + + + + + + + True + <b>Video</b> + True + + + label_item + + + + + False + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-media-play + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Multimedia settings + + + 1 + + + + + tab + 1 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + This section defines your SIP address when not using a SIP account + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your display name (eg: John Doe): + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your username: + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your resulting SIP address: + + + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + 1 + 2 + 2 + 3 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Default identity</b> + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Add + + + 1 + + + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-edit + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Edit + + + 1 + + + + + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Remove + + + 1 + + + + + + + 2 + + + + + False + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Proxy accounts</b> + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Erase all passwords + + + 1 + + + + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Privacy</b> + True + + + label_item + + + + + 2 + + + + + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + stock_people.png + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Manage SIP Accounts + + + 1 + + + + + tab + 2 + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Audio codecs +Video codecs + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_OUT + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-up + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-go-down + True + 0 + + + + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-yes + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Enable + + + 1 + + + + + + + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-no + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Disable + + + 1 + + + + + + + 3 + + + + + False + 1 + + + + + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Codecs</b> + True + + + label_item + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + 0 -1 100000 1 10 10 + + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + 0 -1 100000 1 10 10 + + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Upload limit in kbits/sec + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Download limit in kbits/sec + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Bandwidth usage</b> + True + + + label_item + + + + + 1 + + + + + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-execute + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Codecs + + + 1 + + + + + tab + 3 + False + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-close + True + 0 + + + + + + 1 + + + + + + diff --git a/linphone/gtk-glade/password.glade b/linphone/gtk-glade/password.glade new file mode 100644 index 000000000..5e391eb35 --- /dev/null +++ b/linphone/gtk-glade/password.glade @@ -0,0 +1,89 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Linphone - Authentication required + True + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Please enter your password for domain... + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + + 1 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/propertybox.c b/linphone/gtk-glade/propertybox.c new file mode 100644 index 000000000..da6b5d059 --- /dev/null +++ b/linphone/gtk-glade/propertybox.c @@ -0,0 +1,648 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" + +static void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected){ + const char **p=devices; + int i=0,active=0; + /* glade creates a combo box without list model and text renderer, + unless we fill it with a dummy text. + This dummy text needs to be removed first*/ + gtk_combo_box_remove_text(GTK_COMBO_BOX(combo),0); + for(;*p!=NULL;++p,++i){ + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),*p); + if (strcmp(selected,*p)==0) active=i; + } + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active); +} + +void linphone_gtk_parameters_closed(GtkWidget *button){ + GtkWidget *pb=gtk_widget_get_toplevel(button); + gtk_widget_destroy(pb); +} + +void linphone_gtk_update_my_contact(GtkWidget *w){ + GtkWidget *pb=gtk_widget_get_toplevel(w); + const char *username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username"))); + const char *displayname=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname"))); + int port=linphone_core_get_sip_port(linphone_gtk_get_core()); + osip_from_t *parsed=linphone_core_get_primary_contact_parsed(linphone_gtk_get_core()); + char *contact; + g_return_if_fail(parsed!=NULL); + if (username[0]=='\0') return; + if (port!=5060) + contact=g_strdup_printf("%s ",displayname,username,parsed->url->host,port); + else + contact=g_strdup_printf("%s ",displayname,username,parsed->url->host); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"sip_address")),contact); + linphone_core_set_primary_contact(linphone_gtk_get_core(),contact); + g_free(contact); + linphone_gtk_load_identities(); +} + +void linphone_gtk_stun_server_changed(GtkWidget *w){ + const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w)); + linphone_core_set_stun_server(linphone_gtk_get_core(),addr); +} + +void linphone_gtk_nat_address_changed(GtkWidget *w){ + const gchar *addr=gtk_entry_get_text(GTK_ENTRY(w)); + linphone_core_set_nat_address(linphone_gtk_get_core(),addr); +} + +void linphone_gtk_ipv6_toggled(GtkWidget *w){ + linphone_core_enable_ipv6(linphone_gtk_get_core(), + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); +} + +void linphone_gtk_sip_port_changed(GtkWidget *w){ + linphone_core_set_sip_port(linphone_gtk_get_core(), + (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); +} + +void linphone_gtk_audio_port_changed(GtkWidget *w){ + linphone_core_set_audio_port(linphone_gtk_get_core(), + (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); +} + +void linphone_gtk_video_port_changed(GtkWidget *w){ + linphone_core_set_video_port(linphone_gtk_get_core(), + (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); +} + +void linphone_gtk_no_firewall_toggled(GtkWidget *w){ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) + linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_NO_FIREWALL); +} + +void linphone_gtk_use_nat_address_toggled(GtkWidget *w){ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) + linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_USE_NAT_ADDRESS); +} + +void linphone_gtk_use_stun_toggled(GtkWidget *w){ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) + linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_USE_STUN); +} + +void linphone_gtk_mtu_changed(GtkWidget *w){ + if (GTK_WIDGET_SENSITIVE(w)) + linphone_core_set_mtu(linphone_gtk_get_core(),gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); +} + +void linphone_gtk_use_sip_info_dtmf_toggled(GtkWidget *w){ + linphone_core_set_use_info_for_dtmf(linphone_gtk_get_core(), + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); +} + +void linphone_gtk_mtu_set(GtkWidget *w){ + GtkWidget *mtu=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"mtu"); + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){ + gtk_widget_set_sensitive(mtu,TRUE); + linphone_gtk_mtu_changed(mtu); + }else{ + gtk_widget_set_sensitive(mtu,FALSE); + linphone_core_set_mtu(linphone_gtk_get_core(),0); + } +} + +void linphone_gtk_playback_device_changed(GtkWidget *w){ + gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + linphone_core_set_playback_device(linphone_gtk_get_core(),sel); + g_free(sel); +} + +void linphone_gtk_capture_device_changed(GtkWidget *w){ + gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + linphone_core_set_capture_device(linphone_gtk_get_core(),sel); + g_free(sel); +} + +void linphone_gtk_ring_device_changed(GtkWidget *w){ + gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + linphone_core_set_ringer_device(linphone_gtk_get_core(),sel); + g_free(sel); +} + +void linphone_gtk_alsa_special_device_changed(GtkWidget *w){ + /* + const gchar *dev=gtk_entry_get_text(GTK_ENTRY(w)); + ...*/ +} + +void linphone_gtk_cam_changed(GtkWidget *w){ + gchar *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + linphone_core_set_video_device(linphone_gtk_get_core(),sel); + g_free(sel); +} + +void linphone_gtk_ring_file_set(GtkWidget *w){ + gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w)); + linphone_core_set_ring(linphone_gtk_get_core(),file); + g_free(file); +} + +static void linphone_gtk_end_of_ring(LinphoneCore *lc, void *user_data){ + gtk_widget_set_sensitive((GtkWidget*)user_data,TRUE); +} + +void linphone_gtk_play_ring_file(GtkWidget *w){ + if (linphone_core_preview_ring(linphone_gtk_get_core(), + linphone_core_get_ring(linphone_gtk_get_core()), + linphone_gtk_end_of_ring, + w)==0){ + gtk_widget_set_sensitive(w,FALSE); + } +} + +void linphone_gtk_echo_cancelation_toggled(GtkWidget *w){ + linphone_core_enable_echo_cancelation(linphone_gtk_get_core(), + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); +} + +enum { + CODEC_NAME, + CODEC_RATE, + CODEC_BITRATE, + CODEC_STATUS, + CODEC_PARAMS, + CODEC_PRIVDATA, + CODEC_COLOR, + CODEC_INFO, + CODEC_NCOLUMNS +}; + +static void linphone_gtk_init_codec_list(GtkTreeView *listview){ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + + GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING,G_TYPE_INT, + G_TYPE_FLOAT, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_POINTER, + G_TYPE_STRING, + G_TYPE_STRING); + + gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", CODEC_NAME, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"), + renderer, + "text", CODEC_RATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Status"), + renderer, + "text", CODEC_STATUS, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"), + renderer, + "text", CODEC_BITRATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Parameters"), + renderer, + "text", CODEC_PARAMS, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + /* Setup the selection handler */ + select = gtk_tree_view_get_selection (listview); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); +} + +static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codeclist) +{ + const MSList *elem; + GtkTreeIter iter; + GtkListStore *store=GTK_LIST_STORE(gtk_tree_view_get_model(listview)); + GtkTreeSelection *selection; + + gtk_list_store_clear(store); + + for(elem=codeclist; elem!=NULL; elem=elem->next){ + gchar *status; + gint rate; + gfloat bitrate; + gchar *color; + const char *params=""; + struct _PayloadType *pt=(struct _PayloadType *)elem->data; + if (payload_type_enabled(pt)) status=_("Enabled"); + else status=_("Disabled"); + if (linphone_core_check_payload_type_usability(linphone_gtk_get_core(),pt)) color="blue"; + else color="red"; + /* get an iterator */ + gtk_list_store_append(store,&iter); + bitrate=payload_type_get_bitrate(pt)/1000.0; + rate=payload_type_get_rate(pt); + if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp; + gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt), + CODEC_RATE,rate, + CODEC_BITRATE,bitrate, + CODEC_STATUS,status, + CODEC_PARAMS,params, + CODEC_PRIVDATA,(gpointer)pt, + CODEC_COLOR,(gpointer)color, + CODEC_INFO,(gpointer)payload_type_get_description(pt), + -1); + } + + + + /* Setup the selection handler */ + selection = gtk_tree_view_get_selection (listview); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces)); + gtk_tree_view_set_tooltip_column(listview,CODEC_INFO); +} + +static void linphone_gtk_check_codec_bandwidth(GtkTreeView *v){ + GtkTreeIter iter; + GtkTreeModel *model; + model=gtk_tree_view_get_model(v); + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + PayloadType *pt=NULL; + const gchar *color; + gfloat bitrate; + gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1); + if (linphone_core_check_payload_type_usability(linphone_gtk_get_core(),pt)) color="blue"; + else color="red"; + bitrate=payload_type_get_bitrate(pt)/1000.0; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR, (gpointer)color, + CODEC_BITRATE, bitrate,-1); + }while(gtk_tree_model_iter_next(model,&iter)); +} + +static void linphone_gtk_select_codec(GtkTreeView *v, PayloadType *ref){ + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *selection; + selection=gtk_tree_view_get_selection(v); + model=gtk_tree_view_get_model(v); + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + PayloadType *pt=NULL; + gtk_tree_model_get(model,&iter,CODEC_PRIVDATA,&pt,-1); + if (pt==ref){ + gtk_tree_selection_select_iter(selection,&iter); + } + + }while(gtk_tree_model_iter_next(model,&iter)); +} + +static void linphone_gtk_draw_codec_list(GtkTreeView *v, int type){ /* 0=audio, 1=video*/ + const MSList *list; + if (type==0) list=linphone_core_get_audio_codecs(linphone_gtk_get_core()); + else list=linphone_core_get_video_codecs(linphone_gtk_get_core()); + linphone_gtk_show_codecs(v,list); +} + +void linphone_gtk_codec_view_changed(GtkWidget *w){ + GtkWidget *listview=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"); + int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w)); + linphone_gtk_draw_codec_list(GTK_TREE_VIEW(listview),active); +} + +void linphone_gtk_download_bw_changed(GtkWidget *w){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list")); + linphone_core_set_download_bandwidth(linphone_gtk_get_core(), + (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); + linphone_gtk_check_codec_bandwidth(v); +} + +void linphone_gtk_upload_bw_changed(GtkWidget *w){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list")); + linphone_core_set_upload_bandwidth(linphone_gtk_get_core(), + (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); + linphone_gtk_check_codec_bandwidth(v); +} + +static void linphone_gtk_codec_move(GtkWidget *button, int dir){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list")); + GtkTreeSelection *sel=gtk_tree_view_get_selection(v); + GtkTreeModel *mod; + GtkTreeIter iter; + PayloadType *pt=NULL; + LinphoneCore *lc=linphone_gtk_get_core(); + if (gtk_tree_selection_get_selected(sel,&mod,&iter)){ + MSList *sel_elem,*before; + MSList *codec_list; + gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1); + if (pt->type==PAYLOAD_VIDEO) + codec_list=ms_list_copy(linphone_core_get_video_codecs(lc)); + else codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc)); + sel_elem=ms_list_find(codec_list,pt); + if (dir>0) { + if (sel_elem->prev) before=sel_elem->prev; + else before=sel_elem; + codec_list=ms_list_insert(codec_list,before,pt); + } + else{ + if (sel_elem->next) before=sel_elem->next->next; + else before=sel_elem; + codec_list=ms_list_insert(codec_list,before,pt); + } + codec_list=ms_list_remove_link(codec_list,sel_elem); + if (pt->type==PAYLOAD_VIDEO) + linphone_core_set_video_codecs(lc,codec_list); + else linphone_core_set_audio_codecs(lc,codec_list); + linphone_gtk_show_codecs(v,codec_list); + linphone_gtk_select_codec(v,pt); + } +} + +static void linphone_gtk_codec_set_enable(GtkWidget *button, gboolean enabled){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list")); + GtkTreeSelection *sel=gtk_tree_view_get_selection(v); + GtkTreeModel *mod; + GtkListStore *store; + GtkTreeIter iter; + PayloadType *pt=NULL; + + if (gtk_tree_selection_get_selected(sel,&mod,&iter)){ + store=GTK_LIST_STORE(mod); + gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1); + payload_type_set_enable(pt,enabled); + gtk_list_store_set(store,&iter,CODEC_STATUS, enabled ? _("Enabled") : _("Disabled"), -1); + } +} + +void linphone_gtk_codec_up(GtkWidget *button){ + linphone_gtk_codec_move(button,+1); +} + +void linphone_gtk_codec_down(GtkWidget *button){ + linphone_gtk_codec_move(button,-1); +} + +void linphone_gtk_codec_enable(GtkWidget *button){ + linphone_gtk_codec_set_enable(button,TRUE); +} + +void linphone_gtk_codec_disable(GtkWidget *button){ + linphone_gtk_codec_set_enable(button,FALSE); +} + +void linphone_gtk_clear_passwords(GtkWidget *button){ + linphone_core_clear_all_auth_info(linphone_gtk_get_core()); +} + +enum{ + PROXY_CONFIG_IDENTITY, + PROXY_CONFIG_REF, + PROXY_CONFIG_NCOL +}; + +void linphone_gtk_show_sip_accounts(GtkWidget *w){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"proxy_list")); + GtkTreeModel *model=gtk_tree_view_get_model(v); + GtkListStore *store; + GtkTreeSelection *select; + const MSList *elem; + if (!model){ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + /* create the proxy list */ + store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model(v,GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Account"), + renderer, + "text", PROXY_CONFIG_IDENTITY, + NULL); + gtk_tree_view_append_column (v, column); + + select = gtk_tree_view_get_selection (v); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + model=GTK_TREE_MODEL(store); + }else { + store=GTK_LIST_STORE(model); + } + gtk_list_store_clear(store); + for(elem=linphone_core_get_proxy_config_list(linphone_gtk_get_core());elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; + GtkTreeIter iter; + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,PROXY_CONFIG_IDENTITY,linphone_proxy_config_get_identity(cfg), + PROXY_CONFIG_REF,cfg,-1); + } +} + +static void linphone_gtk_proxy_closed(GtkWidget *w){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config"); + if (cfg){ + linphone_proxy_config_done(cfg); + } +} + +void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){ + GtkWidget *w=linphone_gtk_create_window("sip_account"); + const char *tmp; + if (cfg){ + linphone_proxy_config_edit(cfg); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")), + linphone_proxy_config_get_identity(cfg)); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")), + linphone_proxy_config_get_addr(cfg)); + tmp=linphone_proxy_config_get_route(cfg); + if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")), + linphone_proxy_config_get_expires(cfg)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")), + linphone_proxy_config_register_enabled(cfg)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")), + linphone_proxy_config_publish_enabled(cfg)); + } + g_object_set_data(G_OBJECT(w),"config",(gpointer)cfg); + g_object_set_data(G_OBJECT(w),"parameters",(gpointer)pb); + g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_proxy_closed,w); + gtk_widget_show(w); +} + +void linphone_gtk_proxy_cancel(GtkButton *button){ + GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button)); + gtk_widget_destroy(w); +} + +void linphone_gtk_proxy_ok(GtkButton *button){ + GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button)); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config"); + gboolean was_editing=TRUE; + if (!cfg){ + was_editing=FALSE; + cfg=linphone_proxy_config_new(); + } + linphone_proxy_config_set_identity(cfg, + gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")))); + linphone_proxy_config_set_server_addr(cfg, + gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")))); + linphone_proxy_config_set_route(cfg, + gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")))); + linphone_proxy_config_expires(cfg, + (int)gtk_spin_button_get_value( + GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")))); + linphone_proxy_config_enable_publish(cfg, + gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")))); + linphone_proxy_config_enable_register(cfg, + gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")))); + if (was_editing){ + if (linphone_proxy_config_done(cfg)==-1) + return; + } + else { + if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) return; + linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg); + } + g_object_set_data(G_OBJECT(w),"config",NULL); + linphone_gtk_show_sip_accounts(GTK_WIDGET(g_object_get_data(G_OBJECT(w),"parameters"))); + gtk_widget_destroy(w); + /* also update the main window's list of identities*/ + linphone_gtk_load_identities(); +} + +static LinphoneProxyConfig *linphone_gtk_get_selected_proxy_config(GtkWidget* pb){ + GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(pb,"proxy_list")); + GtkTreeSelection *selection=gtk_tree_view_get_selection(v); + GtkTreeIter iter; + GtkTreeModel *model; + if (gtk_tree_selection_get_selected(selection,&model,&iter)){ + LinphoneProxyConfig *cfg=NULL; + gtk_tree_model_get(model,&iter,PROXY_CONFIG_REF,&cfg,-1); + return cfg; + } + return NULL; +} + +void linphone_gtk_add_proxy(GtkButton *button){ + linphone_gtk_show_proxy_config(gtk_widget_get_toplevel(GTK_WIDGET(button)),NULL); +} + +void linphone_gtk_remove_proxy(GtkButton *button){ + LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config( + gtk_widget_get_toplevel(GTK_WIDGET(button))); + if (cfg){ + linphone_core_remove_proxy_config(linphone_gtk_get_core(),cfg); + linphone_gtk_show_sip_accounts(gtk_widget_get_toplevel(GTK_WIDGET(button))); + } +} + +void linphone_gtk_edit_proxy(GtkButton *button){ + GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(button)); + LinphoneProxyConfig *cfg=linphone_gtk_get_selected_proxy_config(pb); + if (cfg) + linphone_gtk_show_proxy_config(pb,cfg); +} + +void linphone_gtk_show_parameters(void){ + GtkWidget *pb=linphone_gtk_create_window("parameters"); + LinphoneCore *lc=linphone_gtk_get_core(); + const char **sound_devices=linphone_core_get_sound_devices(lc); + const char *tmp; + osip_from_t *contact; + LinphoneFirewallPolicy pol; + GtkWidget *codec_list=linphone_gtk_get_widget(pb,"codec_list"); + int mtu; + /* NETWORK CONFIG */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")), + linphone_core_ipv6_enabled(lc)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"sip_port")), + linphone_core_get_sip_port(lc)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"audio_rtp_port")), + linphone_core_get_audio_port(lc)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_rtp_port")), + linphone_core_get_video_port(lc)); + tmp=linphone_core_get_nat_address(lc); + if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"nat_address")),tmp); + tmp=linphone_core_get_stun_server(lc); + if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"stun_server")),tmp); + pol=linphone_core_get_firewall_policy(lc); + switch(pol){ + case LINPHONE_POLICY_NO_FIREWALL: + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"no_nat")),TRUE); + break; + case LINPHONE_POLICY_USE_NAT_ADDRESS: + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_nat_address")),TRUE); + break; + case LINPHONE_POLICY_USE_STUN: + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_stun")),TRUE); + break; + } + mtu=linphone_core_get_mtu(lc); + if (mtu<=0){ + gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),FALSE); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),1500); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),FALSE); + }else{ + gtk_widget_set_sensitive(linphone_gtk_get_widget(pb,"mtu"),TRUE); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"mtu")),mtu); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"mtu_set")),TRUE); + } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"dtmf_sipinfo")), + linphone_core_get_use_info_for_dtmf(lc)); + /* MUTIMEDIA CONFIG */ + linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"playback_device"), sound_devices, + linphone_core_get_playback_device(lc)); + linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"ring_device"), sound_devices, + linphone_core_get_ringer_device(lc)); + linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"capture_device"), sound_devices, + linphone_core_get_capture_device(lc)); + linphone_gtk_fill_combo_box(linphone_gtk_get_widget(pb,"webcams"),linphone_core_get_video_devices(lc), + linphone_core_get_video_device(lc)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")), + linphone_core_echo_cancelation_enabled(lc)); + + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(linphone_gtk_get_widget(pb,"ring_chooser")), + linphone_core_get_ring(lc)); + /* SIP CONFIG */ + contact=linphone_core_get_primary_contact_parsed(lc); + if (contact){ + if (contact->displayname) + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"displayname")),contact->displayname); + if (contact->url->username) + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")),contact->url->username); + } + linphone_gtk_show_sip_accounts(pb); + /* CODECS CONFIG */ + linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list)); + gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")), + linphone_core_get_download_bandwidth(lc)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")), + linphone_core_get_upload_bandwidth(lc)); + gtk_widget_show(pb); +} diff --git a/linphone/gtk-glade/sip_account.glade b/linphone/gtk-glade/sip_account.glade new file mode 100644 index 000000000..f578f009e --- /dev/null +++ b/linphone/gtk-glade/sip_account.glade @@ -0,0 +1,220 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + Linphone - Configure a SIP account + GTK_WIN_POS_CENTER_ON_PARENT + linphone2.png + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 4 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your SIP identity: + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP Proxy address: + + + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + sip: + + + 1 + 2 + 1 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Route (optional): + + + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 1 + 2 + 2 + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Registration period (sec): + + + 3 + 4 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3600 0 100000 1 10 10 + + + 1 + 2 + 3 + 4 + + + + + + + True + True + Register at startup + 0 + True + True + + + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Publish presence information + 0 + True + + + False + 2 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Configure a SIP account + True + + + label_item + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-ok + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/gtk-glade/stock_people.png b/linphone/gtk-glade/stock_people.png new file mode 100644 index 0000000000000000000000000000000000000000..ed2d33b9f861db2daebf5d371047f3af5884f869 GIT binary patch literal 764 zcmVWFU8GbZ8({Xk{QrNlj4iWF>9@00Ll1L_t(|+O3mINK|1I z$A90wGmbNkI?d?hBOMtHja&p#1Z|_GElS%(3(>#~$u^16GH4UjqI}RQF^e8Vn+he0 zYK%xrdQzB4=A$v4JJ&mpd+*mG6-|j2{oyRm;e3Do=lstHe@8LU4#>r5Uab8yns4-V z%ZagJdv5xJ-PdzT0@qhIh?Pl2MY%5;ovl$-XSJdzo>*+YY2@Vq`FZ~39$&C>)jP*Z z0>enQ$K&zl+S*!Yc6K&hU0w9_-r_(>1lzJG-G6zFL}g_%H8oLxq@f|BEEE#mogG4v zHdn9R#BFP2%J{l7t|AC}q-URUn>~6b4~_=7*AyU_?FGiT3Z?cwy#T&FcAT- zz?bDF*X_dP0Iw6CkLx`7qyccM?Kr>-#iedrv&5|h4&z)+ZszOB6bTb{muGOeKgEV! z0Ybhoda=T^HjQW2V@1wKR6r~#5aDn|-F(_L7E2}hHgEB5&SEBJkP<3}kwM{(O6IK? z0D3@I|8$`$rfHpr8cuk6N1pNO-D9NUWYoKpO(8eKckWZQc>+hCN+K;WQzokj@`DAD zgAJ`Y_)GDGl3Y1`hO`O&gKzlwb&A5GY94iTQPxson@LOBhO`0aGJ((U_m+mY@MSWJ zDIMeoHzI|K+dE2*H;Yu-L`pY9Cx@0sR)rA9q?Es1uu+wTgn_2%q-?=lOy}pE4pLHI zx0g(p6QQVbap?jOQpyX<3QWspX66SAaScO{ad+S;LUHo`^EeL&-;z!yu&lJT-XSg7 u*qD=7baCzXkRXu~DYfYLHsCD(8@~V#yY_XBcII;c0000data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/linphone/gtk/.cvsignore b/linphone/gtk/.cvsignore new file mode 100644 index 000000000..ce7656e3e --- /dev/null +++ b/linphone/gtk/.cvsignore @@ -0,0 +1,5 @@ +.deps +.libs +Makefile +Makefile.in +linphone diff --git a/linphone/gtk/GNOME_LinphoneApplet.server.in.in b/linphone/gtk/GNOME_LinphoneApplet.server.in.in new file mode 100644 index 000000000..79920977f --- /dev/null +++ b/linphone/gtk/GNOME_LinphoneApplet.server.in.in @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/gtk/GNOME_LinphoneApplet.xml b/linphone/gtk/GNOME_LinphoneApplet.xml new file mode 100644 index 000000000..9a5350fd2 --- /dev/null +++ b/linphone/gtk/GNOME_LinphoneApplet.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/linphone/gtk/Makefile.am b/linphone/gtk/Makefile.am new file mode 100644 index 000000000..506bcf4e0 --- /dev/null +++ b/linphone/gtk/Makefile.am @@ -0,0 +1,77 @@ +## Process this file with automake to produce Makefile.in + +linphone_common_sources=\ + linphone.c linphone.h \ + gui_utils.c gui_utils.h \ + support.c support.h \ + interface.c interface.h \ + callbacks.c callbacks.h \ + presence.c presence.h \ + propertybox.c propertybox.h \ + addressbook.c addressbook.h \ + friends.c friends.h + + +INCLUDES = \ + -I$(top_srcdir)\ + -I$(top_srcdir)/intl \ + -I$(top_srcdir)/coreapi \ + -I$(top_srcdir)/mediastreamer2/include + +if BUILD_GTK + +bin_PROGRAMS = linphone + +linphone_SOURCES = \ + main.c \ + $(linphone_common_sources) + +linphone_LDADD = $(LIBGTK_LIBS) $(INTLLIBS) \ + $(ORTP_LIBS) \ + $(top_builddir)/mediastreamer2/src/libmediastreamer.la \ + $(top_builddir)/coreapi/liblinphone.la + +endif + +AM_CFLAGS=$(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(IPV6_CFLAGS) \ + $(ORTP_CFLAGS) $(OSIP_CFLAGS) + +@INTLTOOL_SERVER_RULE@ + +if BUILD_GNOME_APPLET + +gnome_appletdir=$(libexecdir) + +gnome_applet_PROGRAMS = linphone_applet + +linphone_applet_SOURCES = \ + $(linphone_common_sources)\ + applet.c + +linphone_applet_CFLAGS=$(AM_CFLAGS) $(GNOME_APPLETS_CFLAGS) -DLINPHONE_APPLET + +linphone_applet_LDADD = \ + $(GNOME_APPLETS_LIBS) \ + $(top_builddir)/coreapi/liblinphone.la \ + $(OSIP_LIBS) + + +serverdir = $(libdir)/bonobo/servers +server_in_files = GNOME_LinphoneApplet.server.in +server_DATA = $(server_in_files:.server.in=.server) + +$(server_in_files): $(server_in_files:.server.in=.server.in.in) + sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ + + +uidir = $(datadir)/gnome-2.0/ui +ui_DATA = GNOME_LinphoneApplet.xml + +endif + +EXTRA_DIST = \ + GNOME_LinphoneApplet.server.in.in \ + applet.c \ + $(ui_DATA) + +DISTCLEANFILES=GNOME_LinphoneApplet.server.in GNOME_LinphoneApplet.server diff --git a/linphone/gtk/addressbook.c b/linphone/gtk/addressbook.c new file mode 100644 index 000000000..edefde3d0 --- /dev/null +++ b/linphone/gtk/addressbook.c @@ -0,0 +1,306 @@ +/*************************************************************************** + addressbook.c - + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "linphone.h" + +#define get_address_book() (&uiobj->addressbook) +#define get_main_window() (&uiobj->main_window) +#define get_core() (uiobj->core) +#define get_uiobj() (uiobj) + +void fill_address_book(GtkWidget *address_list); + +void ab_destroyed(){ + get_uiobj()->ab=NULL; +} + +void show_address_book(){ + if (get_uiobj()->ab!=NULL){ + gtk_widget_show(get_uiobj()->ab); + }else{ + get_uiobj()->ab=create_and_fill_address_book(); + g_signal_connect(G_OBJECT(get_uiobj()->ab),"destroy",G_CALLBACK(ab_destroyed),NULL); + gtk_widget_show(get_uiobj()->ab); + } +} + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +void contact_draw(GtkWidget *w, LinphoneProxyConfig *cfg){ + GtkWidget *table=lookup_widget(w,"table10"); + GtkWidget *combo; + combo=proxy_combo_box_new(cfg); + gtk_widget_show(combo); + gtk_table_attach(GTK_TABLE(table),combo,1,2,2,3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + GLADE_HOOKUP_OBJECT(w,combo,"proxy"); + combo=gtk_combo_box_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Wait")); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Deny")); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Accept")); + gtk_widget_show(combo); + gtk_table_attach(GTK_TABLE(table),combo,1,2,3,4, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + GLADE_HOOKUP_OBJECT(w,combo,"pol"); +} + +GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab){ + GtkWidget *w=create_contact_box(); + contact_draw(w,NULL); + gtk_widget_show(w); + g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab); + g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE)); + gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe); + return w; +} + +GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab){ + GtkWidget *w=create_contact_box(); + gchar *tmpstr; + contact_draw(w,lf->proxy); + + g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + linphone_friend_edit(lf); + tmpstr=linphone_friend_get_name(lf); + if (tmpstr!=NULL) { + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"name")),tmpstr); + g_free(tmpstr); + } + tmpstr=linphone_friend_get_addr(lf); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"sipaddr")),tmpstr); + g_free(tmpstr); + + gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe); + + gtk_widget_show(w); + if (ab!=NULL) g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab); + return w; +} + +GtkWidget * subscriber_edit(LinphoneFriend *lf){ + GtkWidget *w=contact_edit(lf,NULL); + g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE)); + return w; +} + +gint contact_ok(GtkWidget *dialog){ + gchar *name,*sipaddr; + gchar *url; + gboolean add=FALSE; + GtkWidget *ab; + LinphoneFriend *lf; + int err; + lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref"); + add=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dialog),"add")); + name=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"name")),0,-1); + sipaddr=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"sipaddr")),0,-1); + url=g_strdup_printf("%s <%s>",name,sipaddr); + /* workaround a bug in osip ? */ + /* something doesn't like addresses like "machin <>" */ + if (strchr(sipaddr,'<')==NULL){ + err=linphone_friend_set_sip_addr(lf,url); + }else err=-1; + if (err<0){ + linphone_gnome_ui_display_something(get_uiobj(),GTK_MESSAGE_WARNING,_("Bad sip address: a sip address looks like sip:user@domain")); + linphone_friend_destroy(lf); + g_free(name); + g_free(sipaddr); + g_free(url); + return -1; + } + g_free(name); + g_free(sipaddr); + g_free(url); + linphone_friend_set_proxy(lf,proxy_combo_box_get_selected(lookup_widget(dialog,"proxy"))); + linphone_friend_set_inc_subscribe_policy(lf,gtk_combo_box_get_active(GTK_COMBO_BOX(lookup_widget(dialog,"pol")))); + linphone_friend_send_subscribe(lf,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"send_subscribe")))); + if (add){ + linphone_core_add_friend(get_core(),lf); + } + else linphone_friend_done(lf); + /* ask the address book to redraw itself */ + ab=g_object_get_data(G_OBJECT(dialog),"address_book"); + if (ab!=NULL) fill_address_book(lookup_widget(ab,"address_list")); + return 0; +} + +enum{ + SIP_ADDRESS_COLUMN, + FRIEND_REFERENCE, + AB_NCOLUMNS +}; + +void choose_address_and_close(GtkWidget *ab){ + GtkTreeSelection *select; + GtkWidget *addressentry=get_main_window()->addressentry; + GtkTreeIter iter; + GtkTreeModel *model; + gchar *address=NULL; + GtkWidget *address_list=lookup_widget(ab,"address_list"); + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (select==NULL) return; + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,SIP_ADDRESS_COLUMN , &address, -1); + } + if (address!=NULL){ + gtk_entry_set_text (GTK_ENTRY(addressentry),address); + g_free(address); + } + gtk_widget_destroy(ab); +} +void +address_book_close (GtkWidget *object, + gpointer user_data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(object)); +} + +void address_selection_changed_cb(GtkTreeSelection *selection, gpointer data) +{ + +} +gboolean address_button_press(GtkWidget *widget,GdkEventButton *event,gpointer user_data) +{ + GtkWidget *ab=(GtkWidget*)user_data; + if (event->type==GDK_2BUTTON_PRESS){ + choose_address_and_close(ab); + return TRUE; + } + return FALSE; +} + +void fill_address_book(GtkWidget *address_list){ + GtkListStore *store; + GtkTreeIter iter; + GtkTreeModel *model; + const MSList *elem; + gchar *tmpstr; + /* fill the store */ + elem=linphone_core_get_friend_list(get_core()); + model=gtk_tree_view_get_model(GTK_TREE_VIEW(address_list)); + store=GTK_LIST_STORE(model); + gtk_list_store_clear(store); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneFriend *lf=(LinphoneFriend*)elem->data; + tmpstr=linphone_friend_get_url(lf); + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,SIP_ADDRESS_COLUMN,tmpstr,FRIEND_REFERENCE,(gpointer)lf,-1); + ms_free(tmpstr); + } +} + +GtkWidget *create_and_fill_address_book(){ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + GtkWidget *address_list; + GtkWidget *ret=create_address_book(); + + address_list=lookup_widget(ret,"address_list"); + store = gtk_list_store_new (AB_NCOLUMNS, G_TYPE_STRING,G_TYPE_POINTER); + gtk_tree_view_set_model(GTK_TREE_VIEW(address_list),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Contact list"), + renderer, + "text", SIP_ADDRESS_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (address_list), column); + + /* Setup the selection handler */ + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT (select), "changed", + G_CALLBACK (address_selection_changed_cb), + NULL); + + /* setup handler for double click */ + g_signal_connect(G_OBJECT(address_list),"button-press-event",G_CALLBACK(address_button_press),(gpointer)ret); + + fill_address_book(address_list); + return ret; +} + +void +on_modify_address_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list"); + + /* change the address in the view */ + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + LinphoneFriend *lf=NULL; + gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1); + contact_edit(lf,gtk_widget_get_toplevel(GTK_WIDGET(button))); + } +} + +void on_add_address_clicked(GtkButton *button,gpointer user_data) +{ + LinphoneFriend *lf=linphone_friend_new(); + contact_new(lf,gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + +void on_remove_address_clicked(GtkButton *button,gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list"); + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + LinphoneFriend *lf=NULL; + gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1); + linphone_core_remove_friend(get_core(),lf); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + } +} + +void on_select_address_clicked(GtkButton *button,gpointer user_data) +{ + choose_address_and_close(gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + + +void +on_contact_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch (response_id){ + case GTK_RESPONSE_OK: + contact_ok(GTK_WIDGET(dialog)); + break; + default: + break; + } + gtk_widget_destroy(GTK_WIDGET(dialog)); +} diff --git a/linphone/gtk/addressbook.h b/linphone/gtk/addressbook.h new file mode 100644 index 000000000..f5f5431e3 --- /dev/null +++ b/linphone/gtk/addressbook.h @@ -0,0 +1,28 @@ +/*************************************************************************** + addressbook.h - + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef ADDRESSBOOK_H +#define ADDRESSBOOK_H + +GtkWidget *create_and_fill_address_book(); +void show_address_book(); +GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab); +GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab); +GtkWidget * subscriber_edit(LinphoneFriend *lf); + +#endif diff --git a/linphone/gtk/applet.c b/linphone/gtk/applet.c new file mode 100644 index 000000000..68149e652 --- /dev/null +++ b/linphone/gtk/applet.c @@ -0,0 +1,185 @@ +/*************************************************************************** + applet.c - Applet code for linphone's gnome + interface + ------------------- + begin : Sat Dec 14 2002 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "linphone.h" + +#define get_uiobj() (uiobj) + +LinphoneCore core; +LinphoneGnomeUI ui; +static int show=0; +static gulong signal_ref; +static GtkWidget *applet_button=NULL; +static GdkPixbuf *original_icon=NULL; +static GtkWidget *icon=NULL; + +void draw_icon(GtkWidget *button, int size) +{ + GdkPixbuf *resized; + if (original_icon==NULL){ + original_icon=gdk_pixbuf_new_from_file(PACKAGE_DATA_DIR "/pixmaps/linphone/linphone2.xpm", + NULL); + g_return_if_fail( original_icon!=NULL); + } + if (icon!=NULL){ + gtk_container_remove(GTK_CONTAINER(button),icon); + gtk_widget_destroy(icon); + } + resized=gdk_pixbuf_scale_simple(original_icon,size,size,GDK_INTERP_BILINEAR); + g_return_if_fail(resized!=NULL); + icon=gtk_image_new_from_pixbuf(resized); + g_return_if_fail(icon!=NULL); + gdk_pixbuf_unref(resized); + gtk_container_add(GTK_CONTAINER(button),icon); + gtk_widget_show(icon); +} + +void linphone_applet_about_cb(gpointer p) +{ + GtkWidget *about2; + about2 = create_about2 (); + gtk_widget_show (about2); +} + + + +static void applet_change_pixel_size(GtkWidget *applet, int size) +{ + g_return_if_fail(applet_button!=NULL); + draw_icon(applet_button,size); +} + +static void applet_destroy_cb(GtkWidget *widget, gpointer data) +{ + if (get_uiobj()->main_window.window!=NULL){ + gtk_widget_destroy(get_uiobj()->main_window.window); + } + linphone_gnome_uninit(get_uiobj()); +} + +static gboolean +gui_destroy_cb (GtkWidget *widget, gpointer data) +{ + linphone_gnome_ui_uninit(get_uiobj()); + show=0; + return FALSE; +} + +static gboolean button_press_cb(GtkWidget *applet, GdkEventButton* event, gpointer data) +{ + if (event->button!=1) return FALSE; + if (show){ + g_signal_handlers_disconnect_by_func(G_OBJECT(get_uiobj()->main_window.window), + G_CALLBACK(gui_destroy_cb),NULL); + linphone_gnome_ui_hide(get_uiobj()); + + show=0; + }else { + linphone_gnome_ui_show(get_uiobj()); + signal_ref=g_signal_connect(G_OBJECT(get_uiobj()->main_window.window), + "destroy", + G_CALLBACK(gui_destroy_cb),NULL); + show=1; + } + return FALSE; +} + +const BonoboUIVerb linphone_applet_menu_verbs [] = { + BONOBO_UI_UNSAFE_VERB ("About", linphone_applet_about_cb), + BONOBO_UI_VERB_END +}; + +static gboolean +linphone_applet_fill (PanelApplet *applet) +{ + gint size=panel_applet_get_size(applet); + + applet_button=gtk_frame_new(NULL); + gtk_container_add(GTK_CONTAINER(applet),applet_button); + gtk_widget_show(applet_button); + + draw_icon(applet_button,size); + + g_signal_connect(G_OBJECT(applet),"button-press-event",G_CALLBACK(button_press_cb),NULL); + + + g_signal_connect(G_OBJECT(applet),"change_size", + G_CALLBACK(applet_change_pixel_size), + NULL); + + + g_signal_connect (G_OBJECT (applet), "destroy", + G_CALLBACK (applet_destroy_cb), NULL); + + //sizehint = panel_applet_get_size (PANEL_APPLET (applet)); + panel_applet_setup_menu_from_file (applet, + NULL, + "GNOME_LinphoneApplet.xml", + NULL, + linphone_applet_menu_verbs, + NULL); + + /* tracing for osip */ + TRACE_INITIALIZE(5,stdout); + + linphone_gnome_init(&ui,&core); + gtk_widget_show_all (GTK_WIDGET (applet)); + + return TRUE; +} + + +static gboolean +linphone_applet_factory (PanelApplet *applet, + const gchar *iid, + gpointer data) +{ + static int instances=0; + GtkWidget *dialog; + if (!strcmp (iid, "OAFIID:GNOME_LinphoneApplet")){ + if (instances>0){ + dialog = gtk_message_dialog_new (GTK_WINDOW(applet), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_CLOSE, + (const gchar*) _("Cannot run multiples instances of the linphone applet.")); + /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); + gtk_widget_show(GTK_WIDGET(dialog)); + return FALSE; + } + return linphone_applet_fill (applet); + } + return FALSE; +} + +#define GNOMELOCALEDIR PACKAGE_LOCALE_DIR + +PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_LinphoneApplet_Factory", + PANEL_TYPE_APPLET, + "linphone_applet", + "0", + linphone_applet_factory, + NULL) diff --git a/linphone/gtk/callbacks.c b/linphone/gtk/callbacks.c new file mode 100644 index 000000000..78f293db6 --- /dev/null +++ b/linphone/gtk/callbacks.c @@ -0,0 +1,707 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +callbacks.c -- gtk callbacks, and osipua callbacks. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphone.h" +#include + +#define get_core() (uiobj->core) +#define get_main_window() (&uiobj->main_window) +#define get_uiobj() (uiobj) + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + GtkWidget *about2; + about2 = create_about2 (); + gtk_widget_show (about2); +} + + +gint +on_prop1_close (GtkDialog *gnomedialog, + gpointer user_data) +{ +#ifdef NOTYET + LinphoneMainWindow *obj=get_main_window(); + gnome_appbar_clear_stack( GNOME_APPBAR(obj->status_bar)); +#endif + + return(FALSE); +} + +void +on_parametres1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + linphone_property_box_init(&ui->propbox); +} + + + +void +on_user_manual1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ +#ifdef NOTYET + gnome_help_display("index.xml",NULL,NULL); +#endif +} + + +gboolean +on_play_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_play_level(get_core(),vol); + return FALSE; +} + + +gboolean +on_rec_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_rec_level(get_core(),vol); + return FALSE; +} + + +gboolean +on_ring_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + int vol; + vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value; + linphone_core_set_ring_level(get_core(),vol); + return FALSE; +} + + +void +on_prop1_help (GtkDialog *gnomepropertybox, + gint arg1, + gpointer user_data) +{ +#ifdef NOTYET + gnome_help_display("index.html",NULL,NULL); +#endif +} + + + + +void +on_fermer1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + linphone_gnome_ui_hide(get_uiobj()); +} + + + +#if 0 +/*this is when the panel size changes*/ +void applet_change_pixel_size(GtkWidget *w, int size, gpointer data) +{ + GtkWidget *pixmap,*button; + + pixmap=gtk_object_get_data(GTK_OBJECT(applet),"applet_pixmap"); + button=(GtkWidget*)gtk_object_get_data(GTK_OBJECT(applet),"applet_button"); + if (button==NULL) + { + printf("Cannot find applet button\n"); + return; + } + if (pixmap!=NULL) gtk_widget_destroy(pixmap); + pixmap = gnome_pixmap_new_from_xpm_d_at_size(linphone2_xpm, + size-4, size-4); + gtk_object_set_data(GTK_OBJECT(applet),"applet_pixmap",pixmap); + gtk_widget_show(pixmap); + gtk_container_add(GTK_CONTAINER(button), pixmap); +} +#endif + +void +on_adresse_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + show_address_book(); +} + +void on_address_book_show(GtkWidget *widget,gpointer user_data) +{ + +} + + + +void +on_showmore_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + gint state; + GtkWidget *optioncontrols=get_main_window()->optioncontrols; + state=gtk_toggle_button_get_active(togglebutton); + if (state) gtk_widget_show(optioncontrols); + else { + gtk_widget_hide(optioncontrols); + } +} + + +void +on_useRPC_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ +#ifdef VINCENT_MAURY_RSVP + LinphoneCore *lc=get_core(); + gboolean state; + state=gtk_toggle_button_get_active(togglebutton); + /* change RPC settings according to state */ + if (state) + { + if (linphone_core_set_rpc_mode(lc,1)!=0) /* set rpc on */ + { + printf("RPC error. unable to set rpc on !\n"); + printf("Check to see if RPC server is running\n"); + gtk_toggle_button_set_active(togglebutton,FALSE); + /*linphone_core_set_rpc_mode(lc,0);*/ + } + } + else + { + if (linphone_core_set_rpc_mode(lc,0)!=0) /* set rpc off */ + printf("RPC error. That's impossible !!\n"); + } +#endif +} + +void +on_useRSVP_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ +#ifdef VINCENT_MAURY_RSVP + LinphoneCore *lc=get_core(); + LinphoneGnomeUI *ui=get_uiobj(); + gboolean state; + state=gtk_toggle_button_get_active(togglebutton); + /* change the QoS settings function of the state */ + if (state) + { + linphone_core_set_rsvp_mode(lc,1); /* set RSVP on */ + gtk_widget_show(lookup_widget(ui->propbox.prop,"useRPC")); /* show RPC checkbox */ + } + else + { + linphone_core_set_rsvp_mode(lc,0); /* set RSVP off */ + /* uncheck RPC if necessary and hide RPC checkbox */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( + lookup_widget(ui->propbox.prop,"useRPC")),FALSE); + gtk_widget_hide(lookup_widget(ui->propbox.prop,"useRPC")); + } +#endif +} + +#ifdef VINCENT_MAURY_RSVP +/* callback called when you click the yes/no dialog box + * send yes or no to the core_change_qos which knows the question + * and will be able to ajust qos */ +void dialog_click (GtkDialog *dialog,gint arg1,gpointer user_data) +{ + LinphoneCore *lc=get_core(); + if (lc->call==NULL) + return; + + if (arg1==GTK_RESPONSE_YES) + { + printf("YES\n"); + linphone_core_change_qos(lc, 1); /* 1 = yes */ + } + else + { + printf("NO\n"); + linphone_core_change_qos(lc, 0); /* 0 = no */ + } + gtk_widget_destroy((GtkWidget*)dialog); +} +#endif + + +void +on_alt_href_clicked (GtkButton *button, + gpointer user_data) +{ +#ifdef NOTYET + gchar *url; + GtkWidget *label; + osip_from_t * from; + LinphoneGnomeUI *ui=get_uiobj(); + label=GTK_BIN(button)->child; + gtk_label_get(GTK_LABEL(label),&url); + osip_from_init(&from); + if ( osip_from_parse(from,url) <0){ + /* do something here */ + }else + { /* it was a sip url, so display it in the entry*/ + gtk_entry_set_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(ui->main_window.addressentry))),url); + } + osip_from_free(from); +#endif +} + +void +on_alt_href_realize (GtkWidget *widget, + gpointer user_data) +{ + GdkCursor *cursor = gdk_cursor_new(GDK_HAND2); + gdk_window_set_cursor(widget->window, cursor); + gdk_cursor_destroy(cursor); +} + + +void +on_dtmf_3_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"3"); +} + + +void +on_dmtf_2_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"2"); +} + + +void +on_dtmf_1_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"1"); +} + + +void +on_dtmf_4_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"4"); +} + + +void +on_dtmf_5_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"5"); +} + + +void +on_dtmf_6_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"6"); +} + + +void +on_dtmf_7_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"7"); +} + + +void +on_dtmf_8_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"8"); + +} + + +void +on_dtmf_9_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"9"); + +} + + +void +on_dtmf_star_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"*"); + +} + + +void +on_dtmf_0_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"0"); + +} + + +void +on_dtmf_pound_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dtmf_entry=get_main_window()->dtmfentry; + gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"#"); + +} + + +void +on_dtmf_entry_changed (GtkEditable *editable, + gpointer user_data) +{ + gchar *dtmfs; + gint len; + /* get the last entry in the text box and plays it */ + dtmfs=gtk_editable_get_chars(editable,0,-1); + g_return_if_fail(dtmfs!=NULL); + len=strlen(dtmfs); + if (len>0){ + g_message("Sending dtmf %c",dtmfs[len-1]); + linphone_core_send_dtmf(get_uiobj()->core,dtmfs[len-1]); + } + g_free(dtmfs); +} + + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ +#ifdef LINPHONE_APPLET +#else + gtk_widget_destroy(get_uiobj()->main_window.window); +#endif +} + + +void on_app1_destroy(GtkWidget *app1, gpointer user_data) +{ +#ifdef LINPHONE_APPLET +#else + gtk_main_quit(); +#endif +} + +void +on_display_ab_clicked (GtkButton *button, + gpointer user_data) +{ + show_address_book(); +} + + +void +on_inc_subscr_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + LinphoneFriend *lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref"); + switch(response_id){ + case GTK_RESPONSE_ACCEPT: + subscriber_edit(lf); + break; + case GTK_RESPONSE_REJECT: + linphone_core_reject_subscriber(get_core(),lf); + break; + } + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +void authentication_dialog_ok(GtkWidget *w) +{ + gchar *realm,*username,*userid,*passwd; + LinphoneAuthInfo *info; + realm=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"realm")),0,-1); + username=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"username")),0,-1); + userid=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"userid")),0,-1); + passwd=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"passwd")),0,-1); + info=linphone_auth_info_new(username,userid,passwd,NULL,realm); + linphone_core_add_auth_info(get_core(),info); + g_free(username); + g_free(userid); + g_free(passwd); + g_free(realm); +} + +void +on_authentication_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch(response_id){ + case GTK_RESPONSE_OK: + authentication_dialog_ok(GTK_WIDGET(dialog)); + gtk_widget_destroy(GTK_WIDGET(dialog)); + break; + case GTK_RESPONSE_CANCEL: + gtk_widget_destroy(GTK_WIDGET(dialog)); + } +} + +void +on_clear_auth_info_clicked (GtkButton *button, + gpointer user_data) +{ + linphone_core_clear_all_auth_info(get_core()); +} + + +void +on_call_history_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + linphone_gnome_show_call_logs_window(get_uiobj()); +} + + +void +on_call_logs_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + + +void +on_call_logs_destroy (GtkObject *object, + gpointer user_data) +{ + get_uiobj()->logs=NULL; +} + + +static void completion_add_text(GtkEntry *entry, const char *text){ + GtkTreeIter iter; + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry)); + + if (gtk_tree_model_get_iter_first(model,&iter)){ + do { + gchar *uri=NULL; + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri!=NULL){ + if (strcmp(uri,text)==0) { + /*remove text */ + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + g_free(uri); + break; + } + g_free(uri); + } + }while (gtk_tree_model_iter_next(model,&iter)); + } + /* and prepend it on top of the list */ + gtk_list_store_prepend(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1); +} + + +void +on_callbutton_clicked (GtkButton *button, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + LinphoneCore *lc=get_core(); + GtkEntry *entry=GTK_ENTRY(ui->main_window.addressentry); + + if (lc->call==NULL){ + const gchar *sipurl=NULL; + int err; + /* we have no dialog in progress */ + /* get the url to call */ + sipurl=gtk_entry_get_text(entry); + err=linphone_core_invite(lc,sipurl); + if (err==0) completion_add_text(entry,sipurl); + }else { + linphone_core_accept_call(lc,NULL); + gdk_window_set_keep_above (ui->main_window.window->window, 0); + } +} + +void +on_hangup_clicked (GtkButton *button, + gpointer user_data) +{ + LinphoneGnomeUI *ui=get_uiobj(); + LinphoneCore *lc=get_core(); + gdk_window_set_keep_above (ui->main_window.window->window, 0); + if (lc->call!=NULL){ + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone"); + linphone_core_terminate_call(lc,NULL); + } +} + +GtkWidget *chatroom_new(const gchar *url, LinphoneChatRoom *cr){ + GtkWidget *gcr=NULL; + if (cr==NULL) + cr=linphone_core_create_chat_room(get_core(),url); + if (cr!=NULL){ + gchar *tmp; + gcr=create_chatroom(); + g_object_set_data(G_OBJECT(gcr),"chatroom",(gpointer)cr); + linphone_chat_room_set_user_data(cr,(gpointer)gcr); + tmp=g_strdup_printf(_("Chat with %s"),url); + gtk_window_set_title(GTK_WINDOW(gcr),tmp); + g_free(tmp); + } + return gcr; +} + +void chatroom_append(GtkWidget *gcr, const gchar *from, const gchar *message){ + GtkTextBuffer *tb; + gchar *str; + GtkTextIter enditer; + GtkTextView *tv=GTK_TEXT_VIEW(lookup_widget(gcr,"chattext")); + tb=gtk_text_view_get_buffer(tv); + g_return_if_fail(tb!=NULL); + gtk_text_buffer_get_end_iter(tb,&enditer); + str=g_strdup_printf("[%s]\t:%s\n",from,message); + gtk_text_buffer_insert(tb,&enditer,str,strlen(str)); + g_free(str); +} + +void chatroom_close(GtkWidget *gcr){ + LinphoneChatRoom *cr; + cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom"); + linphone_chat_room_destroy(cr); +} + + +void +on_chat_clicked (GtkButton *button, + gpointer user_data) +{ + gchar *sipurl; + + sipurl=gtk_editable_get_chars(GTK_EDITABLE(get_main_window()->addressentry),0,-1); + GtkWidget *gcr=chatroom_new(sipurl,NULL); + if (gcr!=NULL) gtk_widget_show(gcr); + g_free(sipurl); +} + + +void +on_chatbox_clicked (GtkButton *button, + gpointer user_data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button))); +} + + + +void +on_chatentry_activate (GtkEntry *entry, + gpointer user_data) +{ + LinphoneChatRoom *cr; + gchar *text; + text=gtk_editable_get_chars(GTK_EDITABLE(entry),0,-1); + if (strlen(text)>0){ + GtkWidget *gcr=gtk_widget_get_toplevel(GTK_WIDGET(entry)); + cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom"); + linphone_chat_room_send_message(cr,text); + chatroom_append(gcr,linphone_core_get_primary_contact(get_core()),text); + gtk_editable_delete_text(GTK_EDITABLE(entry),0,-1); + } +} + +void +on_chatroom_destroy (GtkObject *object, + gpointer user_data) +{ + chatroom_close(GTK_WIDGET(object)); +} + + + +void +on_addressentry_activate (GtkEntry *entry, + gpointer user_data) +{ + on_callbutton_clicked(NULL,NULL); +} + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data) +{ + linphone_gnome_save_uri_history(get_uiobj()); +} + +void +on_video_enabled_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + bool_t enabled=gtk_toggle_button_get_active(togglebutton); + linphone_core_enable_video(get_core(),enabled,enabled); +} + + +void +on_echocancelation_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + linphone_core_enable_echo_cancelation(get_core(), + gtk_toggle_button_get_active(togglebutton)); +} + + + + diff --git a/linphone/gtk/callbacks.h b/linphone/gtk/callbacks.h new file mode 100644 index 000000000..505539c47 --- /dev/null +++ b/linphone/gtk/callbacks.h @@ -0,0 +1,545 @@ +#include + + +void +on_app1_destroy (GtkObject *object, + gpointer user_data); + +void +on_adresse_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_parametres1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_fermer1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_user_manual1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_greenbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_redbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_showmore_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +gboolean +on_play_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_rec_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_ring_vol_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +void +on_reachable (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_busy (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_minutesaway_changed (GtkEditable *editable, + gpointer user_data); + +void +on_away (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_do_not_disturb (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_moved_tmply (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_alt_serv (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_contact_field_changed (GtkEditable *editable, + gpointer user_data); + +void +on_presence_validate_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_entry_changed (GtkEditable *editable, + gpointer user_data); + +void +on_dtmf_3_clicked (GtkButton *button, + gpointer user_data); + +void +on_dmtf_2_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_1_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_4_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_5_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_6_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_7_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_8_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_9_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_star_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_0_clicked (GtkButton *button, + gpointer user_data); + +void +on_dtmf_pound_clicked (GtkButton *button, + gpointer user_data); + +void +on_propertybox1_apply (GtkDialog *propertybox, + gint page_num, + gpointer user_data); + +void +on_property_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +gboolean +on_prop1_close (GtkDialog *gnomedialog, + gpointer user_data); + +void +on_prop1_help (GtkDialog *propertybox, + gint page_num, + gpointer user_data); + +gboolean +on_hscale1_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +void +on_audioport_changed (GtkEditable *editable, + gpointer user_data); + +void +on_sipport_changed (GtkEditable *editable, + gpointer user_data); + +void +on_user_name_changed (GtkEditable *editable, + gpointer user_data); + +void +on_domain_name_changed (GtkEditable *editable, + gpointer user_data); + +void +on_registrar_checked_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_rsvp_checked_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + + +void +on_redirect_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_proxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_obproxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_registrar_addr_changed (GtkEditable *editable, + gpointer user_data); + +void +on_reg_passwd_changed (GtkEditable *editable, + gpointer user_data); + +void +on_address_of_record_changed (GtkEditable *editable, + gpointer user_data); + +void +on_aucodec_up_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_down_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_enable_clicked (GtkButton *button, + gpointer user_data); + +void +on_aucodec_disable_clicked (GtkButton *button, + gpointer user_data); + +void +on_sounddriver_changed (GtkEditable *editable, + gpointer user_data); + +void +on_source_changed (GtkEditable *editable, + gpointer user_data); + +void +on_autokill_button1_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_address_book_show (GtkWidget *widget, + gpointer user_data); + +void +on_add_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_remove_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_select_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_modify_address_clicked (GtkButton *button, + gpointer user_data); + +void +on_alt_href_clicked (GtkButton *button, + gpointer user_data); + +void +on_alt_href_realize (GtkWidget *widget, + gpointer user_data); + + +void +on_exit1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +address_book_close (GtkButton *button, + gpointer user_data); + +void +on_card_changed (GtkEditable *editable, + gpointer user_data); + +void +on_audio_jittcomp_value_changed (GtkRange *range, + gpointer user_data); + +void +on_enable_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_nat_address_changed (GtkEditable *editable, + gpointer user_data); + +void +on_display_ab_clicked (GtkButton *button, + gpointer user_data); + +void +on_ringfileentry_changed (GtkEditable *editable, + gpointer user_data); + +void +on_ringpreview_clicked (GtkButton *button, + gpointer user_data); + +gboolean +on_property_box_closed (GtkDialog *gnomedialog, + gpointer user_data); + +void +on_address_book_close (GtkObject *object, + gpointer user_data); + +#ifndef VERSION +# define VERSION LINPHONE_VERSION +#endif + +void +on_addfriend_clicked (GtkButton *button, + gpointer user_data); + +void +on_removefriend_clicked (GtkButton *button, + gpointer user_data); + +void +on_add_adbk_clicked (GtkButton *button, + gpointer user_data); + +void +on_addfriend_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_friendlist_row_activated (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data); +void +on_useRSVP_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_useRPC_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +#ifdef VINCENT_MAURY_RSVP +void +dialog_click (GtkDialog *dialog, + gint arg1, + gpointer user_data); +#endif + +void +on_proxy_config_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_removeproxy_button_clicked (GtkButton *button, + gpointer user_data); + +void +on_addproxy_button_clicked (GtkButton *button, + gpointer user_data); + +void +on_editproxy_button_clicked (GtkButton *button, + gpointer user_data); + + +void +on_contact_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_inc_subscr_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_ob_proxy_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_authentication_dialog_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_clear_auth_info_clicked (GtkButton *button, + gpointer user_data); + +void +on_use_sipinfo_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_guess_hostname_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_call_history_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_call_logs_response (GtkDialog *dialog, + gint response_id, + gpointer user_data); + +void +on_call_logs_destroy (GtkObject *object, + gpointer user_data); + +void +on_enable_ipv6_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_play_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_capt_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_callbutton_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatbox_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatentry_activate (GtkEntry *entry, + gpointer user_data); + +void +on_hangup_clicked (GtkButton *button, + gpointer user_data); + +void +on_chat_clicked (GtkButton *button, + gpointer user_data); + +void +on_chatroom_destroy (GtkObject *object, + gpointer user_data); + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_addressentry_editing_done (GtkCellEditable *celleditable, + gpointer user_data); + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data); + +gboolean +on_addressentry_key_pressed (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); + +void +on_addressentry_changed (GtkComboBox *combobox, + gpointer user_data); + +void +on_addressentry_activate (GtkEntry *entry, + gpointer user_data); + +void +on_addressentry_destroy (GtkObject *object, + gpointer user_data); + +void +on_download_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); + +void +on_download_bw_editing_done (GtkCellEditable *celleditable, + gpointer user_data); + +void +on_download_bw_changed (GtkEditable *editable, + gpointer user_data); + +gboolean +on_upload_bw_output (GtkSpinButton *spinbutton, + gpointer user_data); + +void +on_upload_bw_change_value (GtkSpinButton *spinbutton, + GtkScrollType scroll, + gpointer user_data); + +void +on_upload_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); + +gboolean +on_upload_bw_leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer user_data); + +void +on_video_enabled_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_echocancelation_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_no_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_use_stun_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_static_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data); + +void +on_stun_server_changed (GtkEditable *editable, + gpointer user_data); diff --git a/linphone/gtk/friends.c b/linphone/gtk/friends.c new file mode 100644 index 000000000..d4da7828e --- /dev/null +++ b/linphone/gtk/friends.c @@ -0,0 +1,127 @@ +/*************************************************************************** + friends.c - display of friend's list + + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "linphone.h" + + +#define get_friend_list() (&uiobj->main_window.friendlist) +#define get_core() (uiobj->core) +#define get_main_window() (&uiobj->main_window) + +enum{ + FRIEND_PRESENCE_IMG, + FRIEND_SIP_ADDRESS, + FRIEND_PRESENCE_STATUS, + FRIEND_ID, + FRIEND_LIST_NCOL +}; + +void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){ + GtkTreeIter iter; + LinphoneFriend *tmp=0; + gboolean found=FALSE; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(fl->friendlist)); + if (gtk_tree_model_get_iter_first(model,&iter)) { + do{ + gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1); + //printf("tmp=%i, fid=%i",tmp,fid); + if (fid==tmp) { + GdkPixbuf *pixbuf; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1); + pixbuf = create_pixbuf(img); + if (pixbuf) + { + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } + found=TRUE; + } + }while(gtk_tree_model_iter_next(model,&iter)); + } + if (found==FALSE){ + //printf("Adding new notifier\n"); + GdkPixbuf *pixbuf; + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_SIP_ADDRESS, url, FRIEND_PRESENCE_STATUS,status,FRIEND_ID,fid,-1); + pixbuf = create_pixbuf(img); + if (pixbuf) gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } +} + + +void +on_friendlist_row_activated (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + gchar* friend; + select = gtk_tree_view_get_selection (treeview); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,FRIEND_SIP_ADDRESS , &friend, -1); + gtk_entry_set_text(GTK_ENTRY(get_main_window()->addressentry),friend); + g_free(friend); + } +} + +void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + + + store = gtk_list_store_new (FRIEND_LIST_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + fl->lc=lc; + fl->friendlist=lookup_widget(mainwidget,"friendlist"); + /* need to add friends to the store here ...*/ + + gtk_tree_view_set_model(GTK_TREE_VIEW(fl->friendlist),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes (NULL, + renderer, + "pixbuf", FRIEND_PRESENCE_IMG, + NULL); + gtk_tree_view_column_set_min_width (column, 29); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", FRIEND_SIP_ADDRESS, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + column = gtk_tree_view_column_new_with_attributes (_("Presence status"), + renderer, + "text", FRIEND_PRESENCE_STATUS, + NULL); + g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column); + + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (fl->friendlist)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + +} diff --git a/linphone/gtk/friends.h b/linphone/gtk/friends.h new file mode 100644 index 000000000..02bf65cb0 --- /dev/null +++ b/linphone/gtk/friends.h @@ -0,0 +1,29 @@ +/*************************************************************************** + friends.h - display of friend's list + + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +struct _FriendList { + LinphoneCore *lc; + GtkWidget *friendlist; +}; + +typedef struct _FriendList FriendList; + +void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget); +void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img); diff --git a/linphone/gtk/gui_utils.c b/linphone/gtk/gui_utils.c new file mode 100644 index 000000000..f58390bc2 --- /dev/null +++ b/linphone/gtk/gui_utils.c @@ -0,0 +1,102 @@ +/* +applet.c - some utils functions that cannot be set in interface.c. + +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "linphone.h" + + +/* creates the applet button* +GtkWidget *create_applet() +{ + GtkWidget *frame; + GtkWidget *button; + GtkWidget *vbox; + GtkWidget *applet; + + applet = applet_widget_new("linphone_applet"); + + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + gtk_widget_show(frame); + + vbox = gtk_vbox_new(FALSE, FALSE); + gtk_container_add(GTK_CONTAINER(frame), vbox); + gtk_widget_show(vbox); + + button = gtk_button_new(); + gtk_widget_ref(button); + GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_DEFAULT); + GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS); + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, TRUE, 0); + + + gtk_widget_show(button); + applet_widget_add (APPLET_WIDGET (applet), frame); + gtk_object_set_data_full(GTK_OBJECT(applet),"applet_button",button,(GtkDestroyNotify)gtk_widget_unref); + gtk_signal_connect(GTK_OBJECT(button), "button_press_event", + GTK_SIGNAL_FUNC(on_applet_clicked), NULL); + gtk_signal_connect(GTK_OBJECT(applet), "change_pixel_size", + GTK_SIGNAL_FUNC(applet_change_pixel_size), NULL); + applet_widget_set_tooltip( APPLET_WIDGET (applet),_("linphone")); + gtk_widget_show(applet); + return(applet); +}; + +*/ +/* this just sets level adjustements for startup*/ +void set_levels(LinphoneGnomeUI *ui,gint reclev, gint playlev, gint ringlev) +{ + GtkWidget *range; + GtkWidget *window=ui->main_window.window; + return; + if (window) + { + range=lookup_widget(window,"rec_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)reclev); + range=lookup_widget(window,"play_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)playlev); + range=lookup_widget(window,"ring_vol"); + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)ringlev); + } +} + + +void alt_ressource_display(LinphoneGnomeUI *ui,const gchar *url) +{ + GtkWidget *href; + GtkWidget *altdisplay; + GtkLabel *label; + gchar *pattern; + + altdisplay=create_altressource(); + g_object_set_data(G_OBJECT(altdisplay),"ui",(gpointer)ui); + href=lookup_widget(altdisplay,"alt_href"); + label=GTK_LABEL(GTK_BIN(href)->child); + gtk_label_set_text(label,url); + /* pattern used to set underline for string */ + pattern = g_strnfill(strlen(url), '_'); + gtk_label_set_pattern(label,pattern); + g_free(pattern); + gtk_widget_show(altdisplay); +} + + + + diff --git a/linphone/gtk/gui_utils.h b/linphone/gtk/gui_utils.h new file mode 100644 index 000000000..426de9c3d --- /dev/null +++ b/linphone/gtk/gui_utils.h @@ -0,0 +1,33 @@ +/* +applet.h - ome utils functions that cannot be set in interface.c. + +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef GUI_UTILS_H +#define GUI_UTILS_H + +#include "linphone.h" + +/* set audio levels on the main window*/ +void set_levels(LinphoneGnomeUI *ui,gint reclev, gint playlev, gint ringlev); + +/* display an alternate url (used in 380 response) */ +void alt_ressource_display(LinphoneGnomeUI *ui, const gchar *url); + +#endif + diff --git a/linphone/gtk/interface.c b/linphone/gtk/interface.c new file mode 100644 index 000000000..ced4cbeb6 --- /dev/null +++ b/linphone/gtk/interface.c @@ -0,0 +1,3045 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_app1 (void) +{ + GtkWidget *app1; + GdkPixbuf *app1_icon_pixbuf; + GtkWidget *dock1; + GtkWidget *menubar1; + GtkWidget *connexion1; + GtkWidget *connexion1_menu; + GtkWidget *addresse1; + GtkWidget *image39; + GtkWidget *parametres1; + GtkWidget *call_history; + GtkWidget *image40; + GtkWidget *separator1; + GtkWidget *exit1; + GtkWidget *image41; + GtkWidget *help1; + GtkWidget *help1_menu; + GtkWidget *about1; + GtkWidget *user_manual1; + GtkWidget *frame6; + GtkWidget *vbox4; + GtkWidget *vbox24; + GtkWidget *hbox15; + GtkWidget *frame7; + GtkWidget *addressentry; + GtkWidget *label1; + GtkWidget *display_ab; + GtkWidget *alignment22; + GtkWidget *hbox36; + GtkWidget *image33; + GtkWidget *label108; + GtkWidget *proxy_hbox; + GtkWidget *proxytouse_label; + GtkWidget *hbox2; + GtkWidget *callbutton; + GtkWidget *button14; + GtkWidget *button18; + GtkWidget *showmore; + GtkWidget *alignment5; + GtkWidget *hbox17; + GtkWidget *image12; + GtkWidget *label60; + GtkWidget *optioncontrols; + GtkWidget *vbox31; + GtkWidget *frame8; + GtkWidget *vbox5; + GtkWidget *label30; + GtkWidget *play_vol; + GtkWidget *label31; + GtkWidget *rec_vol; + GtkWidget *label110; + GtkWidget *ring_vol; + GtkWidget *label113; + GtkWidget *frame27; + GtkWidget *alignment23; + GtkWidget *vbox32; + GtkWidget *video_enabled; + GtkWidget *label114; + GtkWidget *label33; + GtkWidget *vbox6; + GtkWidget *presence_frame; + GtkWidget *presence_vbox; + GtkWidget *presence_reachable; + GSList *presence_reachable_group = NULL; + GtkWidget *hbox4; + GtkWidget *radiobutton2; + GtkWidget *minutesaway; + GtkWidget *label35; + GtkWidget *radiobutton3; + GtkWidget *radiobutton4; + GtkWidget *radiobutton5; + GtkWidget *radiobutton6; + GtkWidget *hbox5; + GtkWidget *label36; + GtkWidget *contact_field; + GtkWidget *label34; + GtkWidget *frame19; + GtkWidget *vbox18; + GtkWidget *dtmf_entry; + GtkWidget *table5; + GtkWidget *dtmf_3; + GtkWidget *dmtf_2; + GtkWidget *dtmf_1; + GtkWidget *dtmf_4; + GtkWidget *dtmf_5; + GtkWidget *dtmf_6; + GtkWidget *dtmf_7; + GtkWidget *dtmf_8; + GtkWidget *dtmf_9; + GtkWidget *dtmf_star; + GtkWidget *dtmf_0; + GtkWidget *dtmf_pound; + GtkWidget *label38; + GtkWidget *vbox22; + GtkWidget *scrolledwindow3; + GtkWidget *friendlist; + GtkWidget *label65; + GtkWidget *appbarframe1; + GtkWidget *appbar1; + GtkAccelGroup *accel_group; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + accel_group = gtk_accel_group_new (); + + app1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (app1), _("linphone")); + gtk_window_set_resizable (GTK_WINDOW (app1), FALSE); + app1_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (app1_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (app1), app1_icon_pixbuf); + gdk_pixbuf_unref (app1_icon_pixbuf); + } + + dock1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (dock1); + gtk_container_add (GTK_CONTAINER (app1), dock1); + + menubar1 = gtk_menu_bar_new (); + gtk_widget_show (menubar1); + gtk_box_pack_start (GTK_BOX (dock1), menubar1, TRUE, TRUE, 0); + + connexion1 = gtk_menu_item_new_with_mnemonic (_("Go")); + gtk_widget_show (connexion1); + gtk_container_add (GTK_CONTAINER (menubar1), connexion1); + + connexion1_menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (connexion1), connexion1_menu); + + addresse1 = gtk_image_menu_item_new_with_mnemonic (_("Address book")); + gtk_widget_show (addresse1); + gtk_container_add (GTK_CONTAINER (connexion1_menu), addresse1); + + image39 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU); + gtk_widget_show (image39); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (addresse1), image39); + + parametres1 = gtk_image_menu_item_new_from_stock ("gtk-preferences", accel_group); + gtk_widget_show (parametres1); + gtk_container_add (GTK_CONTAINER (connexion1_menu), parametres1); + + call_history = gtk_image_menu_item_new_with_mnemonic (_("Call history")); + gtk_widget_show (call_history); + gtk_container_add (GTK_CONTAINER (connexion1_menu), call_history); + gtk_tooltips_set_tip (tooltips, call_history, _("Shows calls"), NULL); + + image40 = gtk_image_new_from_stock ("gtk-justify-fill", GTK_ICON_SIZE_MENU); + gtk_widget_show (image40); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (call_history), image40); + + separator1 = gtk_separator_menu_item_new (); + gtk_widget_show (separator1); + gtk_container_add (GTK_CONTAINER (connexion1_menu), separator1); + gtk_widget_set_sensitive (separator1, FALSE); + + exit1 = gtk_image_menu_item_new_with_mnemonic (_("Exit")); + gtk_widget_show (exit1); + gtk_container_add (GTK_CONTAINER (connexion1_menu), exit1); + + image41 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_MENU); + gtk_widget_show (image41); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (exit1), image41); + + help1 = gtk_menu_item_new_with_mnemonic (_("Help")); + gtk_widget_show (help1); + gtk_container_add (GTK_CONTAINER (menubar1), help1); + + help1_menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (help1), help1_menu); + + about1 = gtk_image_menu_item_new_from_stock ("gtk-about", accel_group); + gtk_widget_show (about1); + gtk_container_add (GTK_CONTAINER (help1_menu), about1); + + user_manual1 = gtk_image_menu_item_new_from_stock ("gtk-help", accel_group); + gtk_widget_show (user_manual1); + gtk_container_add (GTK_CONTAINER (help1_menu), user_manual1); + + frame6 = gtk_frame_new (NULL); + gtk_widget_show (frame6); + gtk_box_pack_start (GTK_BOX (dock1), frame6, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame6), 9); + + vbox4 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox4); + gtk_container_add (GTK_CONTAINER (frame6), vbox4); + + vbox24 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox24); + gtk_box_pack_start (GTK_BOX (vbox4), vbox24, TRUE, TRUE, 0); + + hbox15 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox15); + gtk_box_pack_start (GTK_BOX (vbox24), hbox15, TRUE, TRUE, 0); + + frame7 = gtk_frame_new (NULL); + gtk_widget_show (frame7); + gtk_box_pack_start (GTK_BOX (hbox15), frame7, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame7), 5); + + addressentry = gtk_entry_new (); + gtk_widget_show (addressentry); + gtk_container_add (GTK_CONTAINER (frame7), addressentry); + gtk_tooltips_set_tip (tooltips, addressentry, _("Enter sip address or phone number here"), NULL); + gtk_entry_set_text (GTK_ENTRY (addressentry), _("sip:")); + + label1 = gtk_label_new (_("Sip address:")); + gtk_widget_show (label1); + gtk_frame_set_label_widget (GTK_FRAME (frame7), label1); + + display_ab = gtk_button_new (); + gtk_widget_show (display_ab); + gtk_box_pack_start (GTK_BOX (hbox15), display_ab, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (display_ab), 15); + gtk_tooltips_set_tip (tooltips, display_ab, _("Shows the address book"), NULL); + + alignment22 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment22); + gtk_container_add (GTK_CONTAINER (display_ab), alignment22); + + hbox36 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox36); + gtk_container_add (GTK_CONTAINER (alignment22), hbox36); + + image33 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image33); + gtk_box_pack_start (GTK_BOX (hbox36), image33, FALSE, FALSE, 0); + + label108 = gtk_label_new_with_mnemonic (_("...")); + gtk_widget_show (label108); + gtk_box_pack_start (GTK_BOX (hbox36), label108, FALSE, FALSE, 0); + + proxy_hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show (proxy_hbox); + gtk_box_pack_start (GTK_BOX (vbox24), proxy_hbox, TRUE, TRUE, 0); + + proxytouse_label = gtk_label_new (_("Proxy to use:")); + gtk_widget_show (proxytouse_label); + gtk_box_pack_start (GTK_BOX (proxy_hbox), proxytouse_label, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (proxytouse_label), GTK_JUSTIFY_CENTER); + + hbox2 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox2); + gtk_box_pack_start (GTK_BOX (vbox4), hbox2, TRUE, TRUE, 0); + + callbutton = gtk_button_new_with_mnemonic (_("Call or\nanswer")); + gtk_widget_show (callbutton); + gtk_box_pack_start (GTK_BOX (hbox2), callbutton, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (callbutton), 8); + + button14 = gtk_button_new_with_mnemonic (_("Hangup\nor refuse")); + gtk_widget_show (button14); + gtk_box_pack_start (GTK_BOX (hbox2), button14, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (button14), 8); + + button18 = gtk_button_new_with_mnemonic (_("Or chat !")); + gtk_widget_show (button18); + gtk_box_pack_start (GTK_BOX (vbox4), button18, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (button18), 8); + + showmore = gtk_check_button_new (); + gtk_widget_show (showmore); + gtk_box_pack_start (GTK_BOX (vbox4), showmore, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (showmore), TRUE); + + alignment5 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment5); + gtk_container_add (GTK_CONTAINER (showmore), alignment5); + + hbox17 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox17); + gtk_container_add (GTK_CONTAINER (alignment5), hbox17); + + image12 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image12); + gtk_box_pack_start (GTK_BOX (hbox17), image12, FALSE, FALSE, 0); + + label60 = gtk_label_new_with_mnemonic (_("Show more...")); + gtk_widget_show (label60); + gtk_box_pack_start (GTK_BOX (hbox17), label60, FALSE, FALSE, 0); + + optioncontrols = gtk_notebook_new (); + gtk_widget_show (optioncontrols); + gtk_box_pack_start (GTK_BOX (vbox4), optioncontrols, TRUE, TRUE, 0); + + vbox31 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox31); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox31); + + frame8 = gtk_frame_new (NULL); + gtk_widget_show (frame8); + gtk_box_pack_start (GTK_BOX (vbox31), frame8, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame8), 11); + + vbox5 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox5); + gtk_container_add (GTK_CONTAINER (frame8), vbox5); + gtk_container_set_border_width (GTK_CONTAINER (vbox5), 2); + + label30 = gtk_label_new (_("Playback level:")); + gtk_widget_show (label30); + gtk_box_pack_start (GTK_BOX (vbox5), label30, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label30), 7.45058e-09, 0.5); + + play_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (play_vol); + gtk_box_pack_start (GTK_BOX (vbox5), play_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (play_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (play_vol), 0); + + label31 = gtk_label_new (_("Recording level:")); + gtk_widget_show (label31); + gtk_box_pack_start (GTK_BOX (vbox5), label31, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label31), 7.45058e-09, 0.5); + + rec_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (rec_vol); + gtk_box_pack_start (GTK_BOX (vbox5), rec_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (rec_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (rec_vol), 0); + + label110 = gtk_label_new (_("Ring level:")); + gtk_widget_show (label110); + gtk_box_pack_start (GTK_BOX (vbox5), label110, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label110), 7.45058e-09, 0.5); + + ring_vol = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (75, 0, 100, 0, 0, 0))); + gtk_widget_show (ring_vol); + gtk_box_pack_start (GTK_BOX (vbox5), ring_vol, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (ring_vol), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (ring_vol), 0); + + label113 = gtk_label_new (_("Sound")); + gtk_widget_show (label113); + gtk_frame_set_label_widget (GTK_FRAME (frame8), label113); + + frame27 = gtk_frame_new (NULL); + gtk_widget_show (frame27); + gtk_box_pack_start (GTK_BOX (vbox31), frame27, FALSE, FALSE, 0); + + alignment23 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment23); + gtk_container_add (GTK_CONTAINER (frame27), alignment23); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment23), 0, 0, 12, 0); + + vbox32 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox32); + gtk_container_add (GTK_CONTAINER (alignment23), vbox32); + + video_enabled = gtk_check_button_new_with_mnemonic (_("Enable video")); + gtk_widget_show (video_enabled); + gtk_box_pack_start (GTK_BOX (vbox32), video_enabled, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (video_enabled), TRUE); + + label114 = gtk_label_new (_("Video")); + gtk_widget_show (label114); + gtk_frame_set_label_widget (GTK_FRAME (frame27), label114); + gtk_label_set_use_markup (GTK_LABEL (label114), TRUE); + + label33 = gtk_label_new (_("Controls")); + gtk_widget_show (label33); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 0), label33); + gtk_label_set_justify (GTK_LABEL (label33), GTK_JUSTIFY_CENTER); + + vbox6 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox6); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox6); + + presence_frame = gtk_frame_new (NULL); + gtk_widget_show (presence_frame); + gtk_box_pack_start (GTK_BOX (vbox6), presence_frame, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (presence_frame), 11); + + presence_vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (presence_vbox); + gtk_container_add (GTK_CONTAINER (presence_frame), presence_vbox); + + presence_reachable = gtk_radio_button_new_with_mnemonic (NULL, _("Reachable")); + gtk_widget_show (presence_reachable); + gtk_box_pack_start (GTK_BOX (presence_vbox), presence_reachable, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (presence_reachable), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (presence_reachable)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (presence_reachable), TRUE); + + hbox4 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox4); + gtk_box_pack_start (GTK_BOX (presence_vbox), hbox4, FALSE, TRUE, 0); + + radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, _("Busy, I'll be back in ")); + gtk_widget_show (radiobutton2); + gtk_box_pack_start (GTK_BOX (hbox4), radiobutton2, TRUE, TRUE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2)); + + minutesaway = gtk_entry_new (); + gtk_widget_show (minutesaway); + gtk_box_pack_start (GTK_BOX (hbox4), minutesaway, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, minutesaway, _("The other party will be informed that you'll be back in X minutes"), NULL); + gtk_entry_set_text (GTK_ENTRY (minutesaway), _("5")); + + label35 = gtk_label_new (_("mn")); + gtk_widget_show (label35); + gtk_box_pack_start (GTK_BOX (hbox4), label35, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label35), GTK_JUSTIFY_CENTER); + + radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("Away")); + gtk_widget_show (radiobutton3); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton3, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3)); + + radiobutton4 = gtk_radio_button_new_with_mnemonic (NULL, _("Do not disturb")); + gtk_widget_show (radiobutton4); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton4, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton4), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton4)); + + radiobutton5 = gtk_radio_button_new_with_mnemonic (NULL, _("Moved temporarily")); + gtk_widget_show (radiobutton5); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton5, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton5), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton5)); + + radiobutton6 = gtk_radio_button_new_with_mnemonic (NULL, _("Alternative service")); + gtk_widget_show (radiobutton6); + gtk_box_pack_start (GTK_BOX (presence_vbox), radiobutton6, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton6), presence_reachable_group); + presence_reachable_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton6)); + + hbox5 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox5); + gtk_box_pack_start (GTK_BOX (presence_vbox), hbox5, FALSE, TRUE, 0); + + label36 = gtk_label_new (_("URL:")); + gtk_widget_show (label36); + gtk_box_pack_start (GTK_BOX (hbox5), label36, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label36), GTK_JUSTIFY_CENTER); + + contact_field = gtk_entry_new (); + gtk_widget_show (contact_field); + gtk_box_pack_start (GTK_BOX (hbox5), contact_field, FALSE, FALSE, 0); + + label34 = gtk_label_new (_("Presence")); + gtk_widget_show (label34); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 1), label34); + gtk_label_set_justify (GTK_LABEL (label34), GTK_JUSTIFY_CENTER); + + frame19 = gtk_frame_new (NULL); + gtk_widget_show (frame19); + gtk_container_add (GTK_CONTAINER (optioncontrols), frame19); + gtk_container_set_border_width (GTK_CONTAINER (frame19), 15); + + vbox18 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox18); + gtk_container_add (GTK_CONTAINER (frame19), vbox18); + + dtmf_entry = gtk_entry_new (); + gtk_widget_show (dtmf_entry); + gtk_box_pack_start (GTK_BOX (vbox18), dtmf_entry, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, dtmf_entry, _("Press digits to send DTMFs."), NULL); + + table5 = gtk_table_new (4, 3, TRUE); + gtk_widget_show (table5); + gtk_box_pack_start (GTK_BOX (vbox18), table5, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (table5), 14); + gtk_table_set_row_spacings (GTK_TABLE (table5), 10); + gtk_table_set_col_spacings (GTK_TABLE (table5), 10); + + dtmf_3 = gtk_button_new_with_mnemonic (_(" 3\ndef")); + gtk_widget_show (dtmf_3); + gtk_table_attach (GTK_TABLE (table5), dtmf_3, 2, 3, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dmtf_2 = gtk_button_new_with_mnemonic (_(" 2\nabc")); + gtk_widget_show (dmtf_2); + gtk_table_attach (GTK_TABLE (table5), dmtf_2, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_1 = gtk_button_new_with_mnemonic (_("1")); + gtk_widget_show (dtmf_1); + gtk_table_attach (GTK_TABLE (table5), dtmf_1, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_4 = gtk_button_new_with_mnemonic (_(" 4\nghi")); + gtk_widget_show (dtmf_4); + gtk_table_attach (GTK_TABLE (table5), dtmf_4, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_5 = gtk_button_new_with_mnemonic (_(" 5\njkl")); + gtk_widget_show (dtmf_5); + gtk_table_attach (GTK_TABLE (table5), dtmf_5, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_6 = gtk_button_new_with_mnemonic (_(" 6\nmno")); + gtk_widget_show (dtmf_6); + gtk_table_attach (GTK_TABLE (table5), dtmf_6, 2, 3, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_7 = gtk_button_new_with_mnemonic (_(" 7\npqrs")); + gtk_widget_show (dtmf_7); + gtk_table_attach (GTK_TABLE (table5), dtmf_7, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_8 = gtk_button_new_with_mnemonic (_(" 8\ntuv")); + gtk_widget_show (dtmf_8); + gtk_table_attach (GTK_TABLE (table5), dtmf_8, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_9 = gtk_button_new_with_mnemonic (_(" 9\nwxyz")); + gtk_widget_show (dtmf_9); + gtk_table_attach (GTK_TABLE (table5), dtmf_9, 2, 3, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_star = gtk_button_new_with_mnemonic (_("*")); + gtk_widget_show (dtmf_star); + gtk_table_attach (GTK_TABLE (table5), dtmf_star, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_0 = gtk_button_new_with_mnemonic (_("0")); + gtk_widget_show (dtmf_0); + gtk_table_attach (GTK_TABLE (table5), dtmf_0, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + dtmf_pound = gtk_button_new_with_mnemonic (_("#")); + gtk_widget_show (dtmf_pound); + gtk_table_attach (GTK_TABLE (table5), dtmf_pound, 2, 3, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + + label38 = gtk_label_new (_("DTMF")); + gtk_widget_show (label38); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 2), label38); + gtk_label_set_justify (GTK_LABEL (label38), GTK_JUSTIFY_CENTER); + + vbox22 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox22); + gtk_container_add (GTK_CONTAINER (optioncontrols), vbox22); + + scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow3); + gtk_box_pack_start (GTK_BOX (vbox22), scrolledwindow3, TRUE, TRUE, 0); + + friendlist = gtk_tree_view_new (); + gtk_widget_show (friendlist); + gtk_container_add (GTK_CONTAINER (scrolledwindow3), friendlist); + + label65 = gtk_label_new (_("My online friends")); + gtk_widget_show (label65); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (optioncontrols), gtk_notebook_get_nth_page (GTK_NOTEBOOK (optioncontrols), 3), label65); + + appbarframe1 = gtk_frame_new (NULL); + gtk_widget_show (appbarframe1); + gtk_box_pack_start (GTK_BOX (dock1), appbarframe1, TRUE, TRUE, 0); + + appbar1 = gtk_statusbar_new (); + gtk_widget_show (appbar1); + gtk_container_add (GTK_CONTAINER (appbarframe1), appbar1); + + g_signal_connect ((gpointer) app1, "destroy", + G_CALLBACK (on_app1_destroy), + NULL); + g_signal_connect ((gpointer) addresse1, "activate", + G_CALLBACK (on_adresse_activate), + NULL); + g_signal_connect ((gpointer) parametres1, "activate", + G_CALLBACK (on_parametres1_activate), + NULL); + g_signal_connect ((gpointer) call_history, "activate", + G_CALLBACK (on_call_history_activate), + NULL); + g_signal_connect ((gpointer) exit1, "activate", + G_CALLBACK (on_exit1_activate), + NULL); + g_signal_connect ((gpointer) about1, "activate", + G_CALLBACK (on_about1_activate), + NULL); + g_signal_connect ((gpointer) user_manual1, "activate", + G_CALLBACK (on_user_manual1_activate), + NULL); + g_signal_connect ((gpointer) addressentry, "activate", + G_CALLBACK (on_addressentry_activate), + NULL); + g_signal_connect ((gpointer) addressentry, "destroy", + G_CALLBACK (on_addressentry_destroy), + NULL); + g_signal_connect ((gpointer) display_ab, "clicked", + G_CALLBACK (on_display_ab_clicked), + NULL); + g_signal_connect ((gpointer) callbutton, "clicked", + G_CALLBACK (on_callbutton_clicked), + NULL); + g_signal_connect ((gpointer) button14, "clicked", + G_CALLBACK (on_hangup_clicked), + NULL); + g_signal_connect ((gpointer) button18, "clicked", + G_CALLBACK (on_chat_clicked), + NULL); + g_signal_connect ((gpointer) showmore, "toggled", + G_CALLBACK (on_showmore_toggled), + NULL); + g_signal_connect ((gpointer) play_vol, "button_release_event", + G_CALLBACK (on_play_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) rec_vol, "button_release_event", + G_CALLBACK (on_rec_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) ring_vol, "button_release_event", + G_CALLBACK (on_rec_vol_button_release_event), + NULL); + g_signal_connect ((gpointer) video_enabled, "toggled", + G_CALLBACK (on_video_enabled_toggled), + NULL); + g_signal_connect ((gpointer) presence_reachable, "toggled", + G_CALLBACK (on_reachable), + NULL); + g_signal_connect ((gpointer) radiobutton2, "toggled", + G_CALLBACK (on_busy), + NULL); + g_signal_connect ((gpointer) minutesaway, "changed", + G_CALLBACK (on_minutesaway_changed), + NULL); + g_signal_connect ((gpointer) radiobutton3, "toggled", + G_CALLBACK (on_away), + NULL); + g_signal_connect ((gpointer) radiobutton4, "toggled", + G_CALLBACK (on_do_not_disturb), + NULL); + g_signal_connect ((gpointer) radiobutton5, "toggled", + G_CALLBACK (on_moved_tmply), + NULL); + g_signal_connect ((gpointer) radiobutton6, "toggled", + G_CALLBACK (on_alt_serv), + NULL); + g_signal_connect ((gpointer) contact_field, "changed", + G_CALLBACK (on_contact_field_changed), + NULL); + g_signal_connect ((gpointer) dtmf_entry, "changed", + G_CALLBACK (on_dtmf_entry_changed), + NULL); + g_signal_connect ((gpointer) dtmf_3, "clicked", + G_CALLBACK (on_dtmf_3_clicked), + NULL); + g_signal_connect ((gpointer) dmtf_2, "clicked", + G_CALLBACK (on_dmtf_2_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_1, "clicked", + G_CALLBACK (on_dtmf_1_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_4, "clicked", + G_CALLBACK (on_dtmf_4_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_5, "clicked", + G_CALLBACK (on_dtmf_5_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_6, "clicked", + G_CALLBACK (on_dtmf_6_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_7, "clicked", + G_CALLBACK (on_dtmf_7_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_8, "clicked", + G_CALLBACK (on_dtmf_8_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_9, "clicked", + G_CALLBACK (on_dtmf_9_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_star, "clicked", + G_CALLBACK (on_dtmf_star_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_0, "clicked", + G_CALLBACK (on_dtmf_0_clicked), + NULL); + g_signal_connect ((gpointer) dtmf_pound, "clicked", + G_CALLBACK (on_dtmf_pound_clicked), + NULL); + g_signal_connect ((gpointer) friendlist, "row_activated", + G_CALLBACK (on_friendlist_row_activated), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (app1, app1, "app1"); + GLADE_HOOKUP_OBJECT (app1, dock1, "dock1"); + GLADE_HOOKUP_OBJECT (app1, menubar1, "menubar1"); + GLADE_HOOKUP_OBJECT (app1, connexion1, "connexion1"); + GLADE_HOOKUP_OBJECT (app1, connexion1_menu, "connexion1_menu"); + GLADE_HOOKUP_OBJECT (app1, addresse1, "addresse1"); + GLADE_HOOKUP_OBJECT (app1, image39, "image39"); + GLADE_HOOKUP_OBJECT (app1, parametres1, "parametres1"); + GLADE_HOOKUP_OBJECT (app1, call_history, "call_history"); + GLADE_HOOKUP_OBJECT (app1, image40, "image40"); + GLADE_HOOKUP_OBJECT (app1, separator1, "separator1"); + GLADE_HOOKUP_OBJECT (app1, exit1, "exit1"); + GLADE_HOOKUP_OBJECT (app1, image41, "image41"); + GLADE_HOOKUP_OBJECT (app1, help1, "help1"); + GLADE_HOOKUP_OBJECT (app1, help1_menu, "help1_menu"); + GLADE_HOOKUP_OBJECT (app1, about1, "about1"); + GLADE_HOOKUP_OBJECT (app1, user_manual1, "user_manual1"); + GLADE_HOOKUP_OBJECT (app1, frame6, "frame6"); + GLADE_HOOKUP_OBJECT (app1, vbox4, "vbox4"); + GLADE_HOOKUP_OBJECT (app1, vbox24, "vbox24"); + GLADE_HOOKUP_OBJECT (app1, hbox15, "hbox15"); + GLADE_HOOKUP_OBJECT (app1, frame7, "frame7"); + GLADE_HOOKUP_OBJECT (app1, addressentry, "addressentry"); + GLADE_HOOKUP_OBJECT (app1, label1, "label1"); + GLADE_HOOKUP_OBJECT (app1, display_ab, "display_ab"); + GLADE_HOOKUP_OBJECT (app1, alignment22, "alignment22"); + GLADE_HOOKUP_OBJECT (app1, hbox36, "hbox36"); + GLADE_HOOKUP_OBJECT (app1, image33, "image33"); + GLADE_HOOKUP_OBJECT (app1, label108, "label108"); + GLADE_HOOKUP_OBJECT (app1, proxy_hbox, "proxy_hbox"); + GLADE_HOOKUP_OBJECT (app1, proxytouse_label, "proxytouse_label"); + GLADE_HOOKUP_OBJECT (app1, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (app1, callbutton, "callbutton"); + GLADE_HOOKUP_OBJECT (app1, button14, "button14"); + GLADE_HOOKUP_OBJECT (app1, button18, "button18"); + GLADE_HOOKUP_OBJECT (app1, showmore, "showmore"); + GLADE_HOOKUP_OBJECT (app1, alignment5, "alignment5"); + GLADE_HOOKUP_OBJECT (app1, hbox17, "hbox17"); + GLADE_HOOKUP_OBJECT (app1, image12, "image12"); + GLADE_HOOKUP_OBJECT (app1, label60, "label60"); + GLADE_HOOKUP_OBJECT (app1, optioncontrols, "optioncontrols"); + GLADE_HOOKUP_OBJECT (app1, vbox31, "vbox31"); + GLADE_HOOKUP_OBJECT (app1, frame8, "frame8"); + GLADE_HOOKUP_OBJECT (app1, vbox5, "vbox5"); + GLADE_HOOKUP_OBJECT (app1, label30, "label30"); + GLADE_HOOKUP_OBJECT (app1, play_vol, "play_vol"); + GLADE_HOOKUP_OBJECT (app1, label31, "label31"); + GLADE_HOOKUP_OBJECT (app1, rec_vol, "rec_vol"); + GLADE_HOOKUP_OBJECT (app1, label110, "label110"); + GLADE_HOOKUP_OBJECT (app1, ring_vol, "ring_vol"); + GLADE_HOOKUP_OBJECT (app1, label113, "label113"); + GLADE_HOOKUP_OBJECT (app1, frame27, "frame27"); + GLADE_HOOKUP_OBJECT (app1, alignment23, "alignment23"); + GLADE_HOOKUP_OBJECT (app1, vbox32, "vbox32"); + GLADE_HOOKUP_OBJECT (app1, video_enabled, "video_enabled"); + GLADE_HOOKUP_OBJECT (app1, label114, "label114"); + GLADE_HOOKUP_OBJECT (app1, label33, "label33"); + GLADE_HOOKUP_OBJECT (app1, vbox6, "vbox6"); + GLADE_HOOKUP_OBJECT (app1, presence_frame, "presence_frame"); + GLADE_HOOKUP_OBJECT (app1, presence_vbox, "presence_vbox"); + GLADE_HOOKUP_OBJECT (app1, presence_reachable, "presence_reachable"); + GLADE_HOOKUP_OBJECT (app1, hbox4, "hbox4"); + GLADE_HOOKUP_OBJECT (app1, radiobutton2, "radiobutton2"); + GLADE_HOOKUP_OBJECT (app1, minutesaway, "minutesaway"); + GLADE_HOOKUP_OBJECT (app1, label35, "label35"); + GLADE_HOOKUP_OBJECT (app1, radiobutton3, "radiobutton3"); + GLADE_HOOKUP_OBJECT (app1, radiobutton4, "radiobutton4"); + GLADE_HOOKUP_OBJECT (app1, radiobutton5, "radiobutton5"); + GLADE_HOOKUP_OBJECT (app1, radiobutton6, "radiobutton6"); + GLADE_HOOKUP_OBJECT (app1, hbox5, "hbox5"); + GLADE_HOOKUP_OBJECT (app1, label36, "label36"); + GLADE_HOOKUP_OBJECT (app1, contact_field, "contact_field"); + GLADE_HOOKUP_OBJECT (app1, label34, "label34"); + GLADE_HOOKUP_OBJECT (app1, frame19, "frame19"); + GLADE_HOOKUP_OBJECT (app1, vbox18, "vbox18"); + GLADE_HOOKUP_OBJECT (app1, dtmf_entry, "dtmf_entry"); + GLADE_HOOKUP_OBJECT (app1, table5, "table5"); + GLADE_HOOKUP_OBJECT (app1, dtmf_3, "dtmf_3"); + GLADE_HOOKUP_OBJECT (app1, dmtf_2, "dmtf_2"); + GLADE_HOOKUP_OBJECT (app1, dtmf_1, "dtmf_1"); + GLADE_HOOKUP_OBJECT (app1, dtmf_4, "dtmf_4"); + GLADE_HOOKUP_OBJECT (app1, dtmf_5, "dtmf_5"); + GLADE_HOOKUP_OBJECT (app1, dtmf_6, "dtmf_6"); + GLADE_HOOKUP_OBJECT (app1, dtmf_7, "dtmf_7"); + GLADE_HOOKUP_OBJECT (app1, dtmf_8, "dtmf_8"); + GLADE_HOOKUP_OBJECT (app1, dtmf_9, "dtmf_9"); + GLADE_HOOKUP_OBJECT (app1, dtmf_star, "dtmf_star"); + GLADE_HOOKUP_OBJECT (app1, dtmf_0, "dtmf_0"); + GLADE_HOOKUP_OBJECT (app1, dtmf_pound, "dtmf_pound"); + GLADE_HOOKUP_OBJECT (app1, label38, "label38"); + GLADE_HOOKUP_OBJECT (app1, vbox22, "vbox22"); + GLADE_HOOKUP_OBJECT (app1, scrolledwindow3, "scrolledwindow3"); + GLADE_HOOKUP_OBJECT (app1, friendlist, "friendlist"); + GLADE_HOOKUP_OBJECT (app1, label65, "label65"); + GLADE_HOOKUP_OBJECT (app1, appbarframe1, "appbarframe1"); + GLADE_HOOKUP_OBJECT (app1, appbar1, "appbar1"); + GLADE_HOOKUP_OBJECT_NO_REF (app1, tooltips, "tooltips"); + + gtk_window_add_accel_group (GTK_WINDOW (app1), accel_group); + + return app1; +} + +GtkWidget* +create_about2 (void) +{ + GtkWidget *about2; + const gchar *authors[] = { + "Simon MORLAT", + "Aymeric Moizard", + "Sharath K Udupa", + NULL + }; + const gchar *documenters[] = { + "Simon MORLAT", + "Philippe Beau", + NULL + }; + gchar *translators = "it: Alberto Zanoni\nde: Jean Jacques Sarton\nfr: Simon Morlat\nde: Jean-Jacques Sarton, Ursula Herles-Hartz\nes: Jesus Benitez, Nelson Benitez\nja: Yamaguchi Yoshiya\nnl: Hendrik-Jan Heins\npl: Robert Nasiadek <darkone@darkone.pl>\npt_BR: Rafael Caesar Lenzi \nsv: Daniel Nylander "; + GdkPixbuf *about2_logo_pixbuf; + + about2 = gtk_about_dialog_new (); + gtk_container_set_border_width (GTK_CONTAINER (about2), 5); + gtk_window_set_destroy_with_parent (GTK_WINDOW (about2), TRUE); + gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (about2), VERSION); + gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (about2), _("Linphone")); + gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (about2), _("C: 2001\nMade in Old Europe")); + gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (about2), _("Linphone is a web-phone.\nIt is compatible with SIP and RTP protocols.")); + gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (about2), " This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"); + gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (about2), "http://www.linphone.org"); + gtk_about_dialog_set_website_label (GTK_ABOUT_DIALOG (about2), _("http://www.linphone.org")); + gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (about2), authors); + gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (about2), documenters); + gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (about2), translators); + about2_logo_pixbuf = create_pixbuf ("linphone.png"); + gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (about2), about2_logo_pixbuf); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (about2, about2, "about2"); + + return about2; +} + +GtkWidget* +create_prop1 (void) +{ + GtkWidget *prop1; + GdkPixbuf *prop1_icon_pixbuf; + GtkWidget *prop1box; + GtkWidget *prop1notebook; + GtkWidget *vbox9; + GtkWidget *frame26; + GtkWidget *alignment21; + GtkWidget *vbox29; + GtkWidget *enable_ipv6; + GtkWidget *label105; + GtkWidget *frame21; + GtkWidget *vbox21; + GtkWidget *label56; + GtkWidget *table13; + GtkWidget *no_nat; + GSList *no_nat_group = NULL; + GtkWidget *use_stun; + GtkWidget *static_nat; + GtkWidget *nat_address; + GtkWidget *stun_server; + GtkWidget *label55; + GtkWidget *frame20; + GtkWidget *table6; + GtkWidget *audio_jittcomp; + GtkObject *audioport_adj; + GtkWidget *audioport; + GtkWidget *label52; + GtkWidget *label53; + GtkWidget *label54; + GtkWidget *frame25; + GtkWidget *alignment20; + GtkWidget *vbox28; + GtkWidget *use_sipinfo; + GtkWidget *label103; + GtkWidget *network; + GtkWidget *vbox12; + GtkWidget *vbox20; + GtkWidget *frame17; + GtkWidget *vbox16; + GtkWidget *table4; + GtkWidget *label10; + GtkWidget *combo3; + GList *combo3_items = NULL; + GtkWidget *rec_source; + GtkWidget *label106; + GtkWidget *play_card; + GtkWidget *capt_card; + GtkWidget *label11; + GtkWidget *ringsnddev_label; + GtkWidget *label63; + GtkWidget *ring_card; + GtkWidget *echocancelation; + GtkWidget *label115; + GtkWidget *hbox20; + GtkWidget *ringfileentry; + GtkWidget *ringpreview; + GtkWidget *alignment24; + GtkWidget *hbox37; + GtkWidget *image42; + GtkWidget *label118; + GtkWidget *label48; + GtkWidget *sound; + GtkWidget *vbox7; + GtkWidget *frame10; + GtkWidget *hbox6; + GtkWidget *label13; + GtkObject *sip_port_adj; + GtkWidget *sip_port; + GtkWidget *label43; + GtkWidget *frame11; + GtkWidget *vbox27; + GtkWidget *hbox7; + GtkWidget *label26; + GtkWidget *label27; + GtkWidget *user_name; + GtkWidget *label28; + GtkWidget *domain_name; + GtkWidget *guess_hostname; + GtkWidget *label44; + GtkWidget *frame1; + GtkWidget *vbox23; + GtkWidget *scrolledwindow4; + GtkWidget *proxy_list; + GtkWidget *hbuttonbox6; + GtkWidget *addproxy_button; + GtkWidget *alignment12; + GtkWidget *hbox25; + GtkWidget *image19; + GtkWidget *label77; + GtkWidget *editproxy_button; + GtkWidget *alignment13; + GtkWidget *hbox26; + GtkWidget *image20; + GtkWidget *label78; + GtkWidget *removeproxy_button; + GtkWidget *alignment14; + GtkWidget *hbox27; + GtkWidget *image21; + GtkWidget *label79; + GtkWidget *label45; + GtkWidget *frame24; + GtkWidget *alignment18; + GtkWidget *clear_auth_info; + GtkWidget *alignment19; + GtkWidget *hbox34; + GtkWidget *image27; + GtkWidget *label102; + GtkWidget *label101; + GtkWidget *sip_pref; + GtkWidget *vbox13; + GtkWidget *frame16; + GtkWidget *hbox9; + GtkWidget *vbox14; + GtkWidget *label9; + GtkWidget *codec_notebook; + GtkWidget *scrolledwindow2; + GtkWidget *au_codec_list; + GtkWidget *label116; + GtkWidget *scrolledwindow7; + GtkWidget *vid_codec_list; + GtkWidget *label117; + GtkWidget *hbuttonbox4; + GtkWidget *aucodec_up; + GtkWidget *aucodec_down; + GtkWidget *aucodec_enable; + GtkWidget *alignment1; + GtkWidget *hbox11; + GtkWidget *image4; + GtkWidget *label50; + GtkWidget *aucodec_disable; + GtkWidget *alignment2; + GtkWidget *hbox12; + GtkWidget *image5; + GtkWidget *label51; + GtkWidget *table12; + GtkWidget *label112; + GtkWidget *label111; + GtkObject *download_bw_adj; + GtkWidget *download_bw; + GtkObject *upload_bw_adj; + GtkWidget *upload_bw; + GtkWidget *vbox17; + GtkWidget *label22; + GtkWidget *frame18; + GtkWidget *codec_info; + GtkWidget *label47; + GtkWidget *label46; + GtkWidget *codecs_pref; + GtkWidget *hbuttonbox7; + GtkWidget *prop_help_button; + GtkWidget *prop_apply_button; + GtkWidget *prop_close_button; + GtkWidget *prop_ok_button; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + prop1 = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (prop1), _("Parameters")); + gtk_window_set_resizable (GTK_WINDOW (prop1), FALSE); + prop1_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (prop1_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (prop1), prop1_icon_pixbuf); + gdk_pixbuf_unref (prop1_icon_pixbuf); + } + + prop1box = GTK_DIALOG (prop1)->vbox; + + prop1notebook = gtk_notebook_new (); + gtk_widget_show (prop1notebook); + gtk_box_pack_start (GTK_BOX (prop1box), prop1notebook, TRUE, TRUE, 0); + + vbox9 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox9); + gtk_container_add (GTK_CONTAINER (prop1notebook), vbox9); + + frame26 = gtk_frame_new (NULL); + gtk_widget_show (frame26); + gtk_box_pack_start (GTK_BOX (vbox9), frame26, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame26), 6); + + alignment21 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment21); + gtk_container_add (GTK_CONTAINER (frame26), alignment21); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment21), 0, 0, 12, 0); + + vbox29 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox29); + gtk_container_add (GTK_CONTAINER (alignment21), vbox29); + + enable_ipv6 = gtk_check_button_new_with_mnemonic (_("Use IPv6 network (if available)")); + gtk_widget_show (enable_ipv6); + gtk_box_pack_start (GTK_BOX (vbox29), enable_ipv6, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, enable_ipv6, _("Toggle this if you are on an ipv6 network and you wish linphone to use it."), NULL); + + label105 = gtk_label_new (_("Global")); + gtk_widget_show (label105); + gtk_frame_set_label_widget (GTK_FRAME (frame26), label105); + gtk_label_set_use_markup (GTK_LABEL (label105), TRUE); + + frame21 = gtk_frame_new (NULL); + gtk_widget_show (frame21); + gtk_box_pack_start (GTK_BOX (vbox9), frame21, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame21), 5); + + vbox21 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox21); + gtk_container_add (GTK_CONTAINER (frame21), vbox21); + gtk_container_set_border_width (GTK_CONTAINER (vbox21), 6); + + label56 = gtk_label_new (_("These options is only for users in a private network, behind a gateway. If you are not in this situation, then leave this empty.")); + gtk_widget_show (label56); + gtk_box_pack_start (GTK_BOX (vbox21), label56, TRUE, TRUE, 0); + gtk_label_set_line_wrap (GTK_LABEL (label56), TRUE); + gtk_misc_set_padding (GTK_MISC (label56), 0, 12); + + table13 = gtk_table_new (3, 2, FALSE); + gtk_widget_show (table13); + gtk_box_pack_start (GTK_BOX (vbox21), table13, FALSE, FALSE, 0); + + no_nat = gtk_radio_button_new_with_mnemonic (NULL, _("No firewall")); + gtk_widget_show (no_nat); + gtk_table_attach (GTK_TABLE (table13), no_nat, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (no_nat), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (no_nat)); + + use_stun = gtk_radio_button_new_with_mnemonic (NULL, _("Use this STUN server to guess firewall address :")); + gtk_widget_show (use_stun); + gtk_table_attach (GTK_TABLE (table13), use_stun, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (use_stun), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (use_stun)); + + static_nat = gtk_radio_button_new_with_mnemonic (NULL, _("Specify firewall address manually:")); + gtk_widget_show (static_nat); + gtk_table_attach (GTK_TABLE (table13), static_nat, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (static_nat), no_nat_group); + no_nat_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (static_nat)); + + nat_address = gtk_entry_new (); + gtk_widget_show (nat_address); + gtk_table_attach (GTK_TABLE (table13), nat_address, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + stun_server = gtk_entry_new (); + gtk_widget_show (stun_server); + gtk_table_attach (GTK_TABLE (table13), stun_server, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label55 = gtk_label_new (_("NAT traversal options (experimental)")); + gtk_widget_show (label55); + gtk_frame_set_label_widget (GTK_FRAME (frame21), label55); + + frame20 = gtk_frame_new (NULL); + gtk_widget_show (frame20); + gtk_box_pack_start (GTK_BOX (vbox9), frame20, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame20), 5); + + table6 = gtk_table_new (2, 2, FALSE); + gtk_widget_show (table6); + gtk_container_add (GTK_CONTAINER (frame20), table6); + + audio_jittcomp = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (150, 60, 512, 10, 0, 0))); + gtk_widget_show (audio_jittcomp); + gtk_table_attach (GTK_TABLE (table6), audio_jittcomp, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND), 20, 0); + gtk_scale_set_value_pos (GTK_SCALE (audio_jittcomp), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (audio_jittcomp), 0); + + audioport_adj = gtk_adjustment_new (7000, 5000, 65535, 1, 10, 10); + audioport = gtk_spin_button_new (GTK_ADJUSTMENT (audioport_adj), 4, 0); + gtk_widget_show (audioport); + gtk_table_attach (GTK_TABLE (table6), audioport, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND), 20, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (audioport), TRUE); + + label52 = gtk_label_new (_("Number of buffered miliseconds (jitter compensation):")); + gtk_widget_show (label52); + gtk_table_attach (GTK_TABLE (table6), label52, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label52), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label52), TRUE); + + label53 = gtk_label_new (_("RTP port used for audio:")); + gtk_widget_show (label53); + gtk_table_attach (GTK_TABLE (table6), label53, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_label_set_justify (GTK_LABEL (label53), GTK_JUSTIFY_CENTER); + + label54 = gtk_label_new (_("RTP properties")); + gtk_widget_show (label54); + gtk_frame_set_label_widget (GTK_FRAME (frame20), label54); + + frame25 = gtk_frame_new (NULL); + gtk_widget_show (frame25); + gtk_box_pack_start (GTK_BOX (vbox9), frame25, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame25), 5); + + alignment20 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment20); + gtk_container_add (GTK_CONTAINER (frame25), alignment20); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment20), 0, 0, 12, 0); + + vbox28 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox28); + gtk_container_add (GTK_CONTAINER (alignment20), vbox28); + + use_sipinfo = gtk_check_button_new_with_mnemonic (_("Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting")); + gtk_widget_show (use_sipinfo); + gtk_box_pack_start (GTK_BOX (vbox28), use_sipinfo, FALSE, FALSE, 0); + gtk_tooltips_set_tip (tooltips, use_sipinfo, _("RTP-RFC2833 is the recommended way."), NULL); + + label103 = gtk_label_new (_("Other")); + gtk_widget_show (label103); + gtk_frame_set_label_widget (GTK_FRAME (frame25), label103); + gtk_label_set_use_markup (GTK_LABEL (label103), TRUE); + + network = gtk_label_new (_("Network")); + gtk_widget_show (network); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (prop1notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (prop1notebook), 0), network); + gtk_label_set_justify (GTK_LABEL (network), GTK_JUSTIFY_CENTER); + + vbox12 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox12); + gtk_container_add (GTK_CONTAINER (prop1notebook), vbox12); + + vbox20 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox20); + gtk_box_pack_start (GTK_BOX (vbox12), vbox20, FALSE, TRUE, 0); + + frame17 = gtk_frame_new (NULL); + gtk_widget_show (frame17); + gtk_box_pack_start (GTK_BOX (vbox20), frame17, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame17), 10); + + vbox16 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox16); + gtk_container_add (GTK_CONTAINER (frame17), vbox16); + + table4 = gtk_table_new (6, 2, FALSE); + gtk_widget_show (table4); + gtk_box_pack_start (GTK_BOX (vbox16), table4, TRUE, TRUE, 0); + + label10 = gtk_label_new (_("Playback sound device:")); + gtk_widget_show (label10); + gtk_table_attach (GTK_TABLE (table4), label10, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (GTK_EXPAND), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label10), 0, 0.5); + + combo3 = gtk_combo_new (); + g_object_set_data (G_OBJECT (GTK_COMBO (combo3)->popwin), + "GladeParentKey", combo3); + gtk_widget_show (combo3); + gtk_table_attach (GTK_TABLE (table4), combo3, 1, 2, 2, 3, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_combo_set_value_in_list (GTK_COMBO (combo3), TRUE, FALSE); + combo3_items = g_list_append (combo3_items, (gpointer) _("micro")); + combo3_items = g_list_append (combo3_items, (gpointer) _("line")); + combo3_items = g_list_append (combo3_items, (gpointer) ""); + gtk_combo_set_popdown_strings (GTK_COMBO (combo3), combo3_items); + g_list_free (combo3_items); + + rec_source = GTK_COMBO (combo3)->entry; + gtk_widget_show (rec_source); + gtk_editable_set_editable (GTK_EDITABLE (rec_source), FALSE); + + label106 = gtk_label_new (_("Capture sound device:")); + gtk_widget_show (label106); + gtk_table_attach (GTK_TABLE (table4), label106, 0, 1, 1, 2, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label106), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label106), 0, 0.5); + + play_card = gtk_combo_box_new_text (); + gtk_widget_show (play_card); + gtk_table_attach (GTK_TABLE (table4), play_card, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + capt_card = gtk_combo_box_new_text (); + gtk_widget_show (capt_card); + gtk_table_attach (GTK_TABLE (table4), capt_card, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + label11 = gtk_label_new (_("Recording source:")); + gtk_widget_show (label11); + gtk_table_attach (GTK_TABLE (table4), label11, 0, 1, 2, 3, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5); + + ringsnddev_label = gtk_label_new (_("Ring sound device")); + gtk_widget_show (ringsnddev_label); + gtk_table_attach (GTK_TABLE (table4), ringsnddev_label, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (ringsnddev_label), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (ringsnddev_label), 0, 0.5); + + label63 = gtk_label_new (_("Ring sound:")); + gtk_widget_show (label63); + gtk_table_attach (GTK_TABLE (table4), label63, 0, 1, 4, 5, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label63), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label63), 0, 0.5); + + ring_card = gtk_combo_box_new_text (); + gtk_widget_show (ring_card); + gtk_table_attach (GTK_TABLE (table4), ring_card, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + echocancelation = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (echocancelation); + gtk_table_attach (GTK_TABLE (table4), echocancelation, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label115 = gtk_label_new (_("Enable echo-canceler (cancels the echo heard by the remote party)")); + gtk_widget_show (label115); + gtk_table_attach (GTK_TABLE (table4), label115, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_label_set_justify (GTK_LABEL (label115), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label115), 0, 0.5); + + hbox20 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox20); + gtk_table_attach (GTK_TABLE (table4), hbox20, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + + ringfileentry = gtk_file_chooser_button_new (_("Choose file"), GTK_FILE_CHOOSER_ACTION_OPEN); + gtk_widget_show (ringfileentry); + gtk_box_pack_start (GTK_BOX (hbox20), ringfileentry, TRUE, TRUE, 0); + + ringpreview = gtk_button_new (); + gtk_widget_show (ringpreview); + gtk_box_pack_start (GTK_BOX (hbox20), ringpreview, FALSE, FALSE, 10); + + alignment24 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment24); + gtk_container_add (GTK_CONTAINER (ringpreview), alignment24); + + hbox37 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox37); + gtk_container_add (GTK_CONTAINER (alignment24), hbox37); + + image42 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image42); + gtk_box_pack_start (GTK_BOX (hbox37), image42, FALSE, FALSE, 0); + + label118 = gtk_label_new_with_mnemonic (_("Listen")); + gtk_widget_show (label118); + gtk_box_pack_start (GTK_BOX (hbox37), label118, FALSE, FALSE, 0); + + label48 = gtk_label_new (_("Sound properties")); + gtk_widget_show (label48); + gtk_frame_set_label_widget (GTK_FRAME (frame17), label48); + + sound = gtk_label_new (_("Sound device")); + gtk_widget_show (sound); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (prop1notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (prop1notebook), 1), sound); + gtk_label_set_justify (GTK_LABEL (sound), GTK_JUSTIFY_CENTER); + + vbox7 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox7); + gtk_container_add (GTK_CONTAINER (prop1notebook), vbox7); + + frame10 = gtk_frame_new (NULL); + gtk_widget_show (frame10); + gtk_box_pack_start (GTK_BOX (vbox7), frame10, FALSE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame10), 10); + + hbox6 = gtk_hbox_new (FALSE, 67); + gtk_widget_show (hbox6); + gtk_container_add (GTK_CONTAINER (frame10), hbox6); + + label13 = gtk_label_new (_("Run sip user agent on port:")); + gtk_widget_show (label13); + gtk_box_pack_start (GTK_BOX (hbox6), label13, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label13), GTK_JUSTIFY_CENTER); + + sip_port_adj = gtk_adjustment_new (5060, 5000, 65535, 1, 10, 10); + sip_port = gtk_spin_button_new (GTK_ADJUSTMENT (sip_port_adj), 4, 0); + gtk_widget_show (sip_port); + gtk_box_pack_start (GTK_BOX (hbox6), sip_port, TRUE, TRUE, 32); + gtk_tooltips_set_tip (tooltips, sip_port, _("It is strongly recommended to use port 5060."), NULL); + + label43 = gtk_label_new (_("SIP port")); + gtk_widget_show (label43); + gtk_frame_set_label_widget (GTK_FRAME (frame10), label43); + + frame11 = gtk_frame_new (NULL); + gtk_widget_show (frame11); + gtk_box_pack_start (GTK_BOX (vbox7), frame11, FALSE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame11), 10); + + vbox27 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox27); + gtk_container_add (GTK_CONTAINER (frame11), vbox27); + + hbox7 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox7); + gtk_box_pack_start (GTK_BOX (vbox27), hbox7, TRUE, TRUE, 0); + + label26 = gtk_label_new (_("Your sip address:")); + gtk_widget_show (label26); + gtk_box_pack_start (GTK_BOX (hbox7), label26, TRUE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label26), GTK_JUSTIFY_CENTER); + + label27 = gtk_label_new (_("sip:")); + gtk_widget_show (label27); + gtk_box_pack_start (GTK_BOX (hbox7), label27, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label27), GTK_JUSTIFY_RIGHT); + + user_name = gtk_entry_new (); + gtk_widget_show (user_name); + gtk_box_pack_start (GTK_BOX (hbox7), user_name, FALSE, FALSE, 0); + + label28 = gtk_label_new (_("@")); + gtk_widget_show (label28); + gtk_box_pack_start (GTK_BOX (hbox7), label28, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label28), GTK_JUSTIFY_CENTER); + + domain_name = gtk_entry_new (); + gtk_widget_show (domain_name); + gtk_box_pack_start (GTK_BOX (hbox7), domain_name, FALSE, TRUE, 0); + + guess_hostname = gtk_check_button_new_with_mnemonic (_("Automatically guess a valid hostname")); + gtk_widget_show (guess_hostname); + gtk_box_pack_start (GTK_BOX (vbox27), guess_hostname, TRUE, TRUE, 0); + + label44 = gtk_label_new (_("Identity")); + gtk_widget_show (label44); + gtk_frame_set_label_widget (GTK_FRAME (frame11), label44); + + frame1 = gtk_frame_new (NULL); + gtk_widget_show (frame1); + gtk_box_pack_start (GTK_BOX (vbox7), frame1, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame1), 10); + + vbox23 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox23); + gtk_container_add (GTK_CONTAINER (frame1), vbox23); + + scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow4); + gtk_box_pack_start (GTK_BOX (vbox23), scrolledwindow4, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_SHADOW_ETCHED_OUT); + + proxy_list = gtk_tree_view_new (); + gtk_widget_show (proxy_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow4), proxy_list); + gtk_widget_set_size_request (proxy_list, -1, 100); + + hbuttonbox6 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox6); + gtk_box_pack_start (GTK_BOX (vbox23), hbuttonbox6, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox6), 5); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox6), GTK_BUTTONBOX_SPREAD); + + addproxy_button = gtk_button_new (); + gtk_widget_show (addproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), addproxy_button); + GTK_WIDGET_SET_FLAGS (addproxy_button, GTK_CAN_DEFAULT); + + alignment12 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment12); + gtk_container_add (GTK_CONTAINER (addproxy_button), alignment12); + + hbox25 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox25); + gtk_container_add (GTK_CONTAINER (alignment12), hbox25); + + image19 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image19); + gtk_box_pack_start (GTK_BOX (hbox25), image19, FALSE, FALSE, 0); + + label77 = gtk_label_new_with_mnemonic (_("Add proxy/registrar")); + gtk_widget_show (label77); + gtk_box_pack_start (GTK_BOX (hbox25), label77, FALSE, FALSE, 0); + + editproxy_button = gtk_button_new (); + gtk_widget_show (editproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), editproxy_button); + GTK_WIDGET_SET_FLAGS (editproxy_button, GTK_CAN_DEFAULT); + + alignment13 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment13); + gtk_container_add (GTK_CONTAINER (editproxy_button), alignment13); + + hbox26 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox26); + gtk_container_add (GTK_CONTAINER (alignment13), hbox26); + + image20 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image20); + gtk_box_pack_start (GTK_BOX (hbox26), image20, FALSE, FALSE, 0); + + label78 = gtk_label_new_with_mnemonic (_("Edit")); + gtk_widget_show (label78); + gtk_box_pack_start (GTK_BOX (hbox26), label78, FALSE, FALSE, 0); + + removeproxy_button = gtk_button_new (); + gtk_widget_show (removeproxy_button); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), removeproxy_button); + GTK_WIDGET_SET_FLAGS (removeproxy_button, GTK_CAN_DEFAULT); + + alignment14 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment14); + gtk_container_add (GTK_CONTAINER (removeproxy_button), alignment14); + + hbox27 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox27); + gtk_container_add (GTK_CONTAINER (alignment14), hbox27); + + image21 = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image21); + gtk_box_pack_start (GTK_BOX (hbox27), image21, FALSE, FALSE, 0); + + label79 = gtk_label_new_with_mnemonic (_("Remove")); + gtk_widget_show (label79); + gtk_box_pack_start (GTK_BOX (hbox27), label79, FALSE, FALSE, 0); + + label45 = gtk_label_new (_("Remote services")); + gtk_widget_show (label45); + gtk_frame_set_label_widget (GTK_FRAME (frame1), label45); + + frame24 = gtk_frame_new (NULL); + gtk_widget_show (frame24); + gtk_box_pack_start (GTK_BOX (vbox7), frame24, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame24), 10); + + alignment18 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment18); + gtk_container_add (GTK_CONTAINER (frame24), alignment18); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment18), 0, 0, 12, 0); + + clear_auth_info = gtk_button_new (); + gtk_widget_show (clear_auth_info); + gtk_container_add (GTK_CONTAINER (alignment18), clear_auth_info); + + alignment19 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment19); + gtk_container_add (GTK_CONTAINER (clear_auth_info), alignment19); + + hbox34 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox34); + gtk_container_add (GTK_CONTAINER (alignment19), hbox34); + + image27 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image27); + gtk_box_pack_start (GTK_BOX (hbox34), image27, FALSE, FALSE, 0); + + label102 = gtk_label_new_with_mnemonic (_("Clear all stored authentication information (username,password...)")); + gtk_widget_show (label102); + gtk_box_pack_start (GTK_BOX (hbox34), label102, FALSE, FALSE, 0); + + label101 = gtk_label_new (_("Authentication information")); + gtk_widget_show (label101); + gtk_frame_set_label_widget (GTK_FRAME (frame24), label101); + + sip_pref = gtk_label_new (_("SIP")); + gtk_widget_show (sip_pref); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (prop1notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (prop1notebook), 2), sip_pref); + gtk_label_set_justify (GTK_LABEL (sip_pref), GTK_JUSTIFY_CENTER); + + vbox13 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox13); + gtk_container_add (GTK_CONTAINER (prop1notebook), vbox13); + + frame16 = gtk_frame_new (NULL); + gtk_widget_show (frame16); + gtk_box_pack_start (GTK_BOX (vbox13), frame16, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame16), 10); + + hbox9 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox9); + gtk_container_add (GTK_CONTAINER (frame16), hbox9); + + vbox14 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox14); + gtk_box_pack_start (GTK_BOX (hbox9), vbox14, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox14), 9); + + label9 = gtk_label_new (_("List of audio codecs, in order of preference:")); + gtk_widget_show (label9); + gtk_box_pack_start (GTK_BOX (vbox14), label9, FALSE, FALSE, 4); + gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5); + + codec_notebook = gtk_notebook_new (); + gtk_widget_show (codec_notebook); + gtk_box_pack_start (GTK_BOX (vbox14), codec_notebook, TRUE, TRUE, 0); + + scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow2); + gtk_container_add (GTK_CONTAINER (codec_notebook), scrolledwindow2); + GTK_WIDGET_UNSET_FLAGS (scrolledwindow2, GTK_CAN_FOCUS); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_ETCHED_IN); + + au_codec_list = gtk_tree_view_new (); + gtk_widget_show (au_codec_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow2), au_codec_list); + gtk_tree_view_set_reorderable (GTK_TREE_VIEW (au_codec_list), TRUE); + + label116 = gtk_label_new (_("Audio codecs")); + gtk_widget_show (label116); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (codec_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (codec_notebook), 0), label116); + + scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow7); + gtk_container_add (GTK_CONTAINER (codec_notebook), scrolledwindow7); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_SHADOW_IN); + + vid_codec_list = gtk_tree_view_new (); + gtk_widget_show (vid_codec_list); + gtk_container_add (GTK_CONTAINER (scrolledwindow7), vid_codec_list); + + label117 = gtk_label_new (_("Video Codecs")); + gtk_widget_show (label117); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (codec_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (codec_notebook), 1), label117); + + hbuttonbox4 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox4); + gtk_box_pack_start (GTK_BOX (vbox14), hbuttonbox4, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox4), 10); + + aucodec_up = gtk_button_new_from_stock ("gtk-go-up"); + gtk_widget_show (aucodec_up); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_up); + GTK_WIDGET_SET_FLAGS (aucodec_up, GTK_CAN_DEFAULT); + + aucodec_down = gtk_button_new_from_stock ("gtk-go-down"); + gtk_widget_show (aucodec_down); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_down); + GTK_WIDGET_SET_FLAGS (aucodec_down, GTK_CAN_DEFAULT); + + aucodec_enable = gtk_button_new (); + gtk_widget_show (aucodec_enable); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_enable); + GTK_WIDGET_SET_FLAGS (aucodec_enable, GTK_CAN_DEFAULT); + + alignment1 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment1); + gtk_container_add (GTK_CONTAINER (aucodec_enable), alignment1); + + hbox11 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox11); + gtk_container_add (GTK_CONTAINER (alignment1), hbox11); + + image4 = gtk_image_new_from_stock ("gtk-apply", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image4); + gtk_box_pack_start (GTK_BOX (hbox11), image4, FALSE, FALSE, 0); + + label50 = gtk_label_new_with_mnemonic (_("Enable")); + gtk_widget_show (label50); + gtk_box_pack_start (GTK_BOX (hbox11), label50, FALSE, FALSE, 0); + + aucodec_disable = gtk_button_new (); + gtk_widget_show (aucodec_disable); + gtk_container_add (GTK_CONTAINER (hbuttonbox4), aucodec_disable); + GTK_WIDGET_SET_FLAGS (aucodec_disable, GTK_CAN_DEFAULT); + + alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment2); + gtk_container_add (GTK_CONTAINER (aucodec_disable), alignment2); + + hbox12 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox12); + gtk_container_add (GTK_CONTAINER (alignment2), hbox12); + + image5 = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image5); + gtk_box_pack_start (GTK_BOX (hbox12), image5, FALSE, FALSE, 0); + + label51 = gtk_label_new_with_mnemonic (_("Disable")); + gtk_widget_show (label51); + gtk_box_pack_start (GTK_BOX (hbox12), label51, FALSE, FALSE, 0); + + table12 = gtk_table_new (2, 2, TRUE); + gtk_widget_show (table12); + gtk_box_pack_start (GTK_BOX (vbox14), table12, FALSE, TRUE, 0); + + label112 = gtk_label_new (_("Upload bandwidth (kbit/sec):")); + gtk_widget_show (label112); + gtk_table_attach (GTK_TABLE (table12), label112, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label112), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label112), 0, 0.5); + + label111 = gtk_label_new (_("Download bandwidth (kbit/sec):")); + gtk_widget_show (label111); + gtk_table_attach (GTK_TABLE (table12), label111, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label111), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label111), 0, 0.5); + + download_bw_adj = gtk_adjustment_new (0, 0, 100000, 10, 100, 10); + download_bw = gtk_spin_button_new (GTK_ADJUSTMENT (download_bw_adj), 1, 0); + gtk_widget_show (download_bw); + gtk_table_attach (GTK_TABLE (table12), download_bw, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (download_bw), GTK_UPDATE_IF_VALID); + + upload_bw_adj = gtk_adjustment_new (0, 0, 100000, 10, 100, 10); + upload_bw = gtk_spin_button_new (GTK_ADJUSTMENT (upload_bw_adj), 1, 0); + gtk_widget_show (upload_bw); + gtk_table_attach (GTK_TABLE (table12), upload_bw, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + vbox17 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox17); + gtk_box_pack_start (GTK_BOX (hbox9), vbox17, TRUE, FALSE, 0); + + label22 = gtk_label_new (_("Note: Codecs in red are not usable regarding to your connection type to the internet.")); + gtk_widget_show (label22); + gtk_box_pack_start (GTK_BOX (vbox17), label22, FALSE, FALSE, 0); + gtk_label_set_justify (GTK_LABEL (label22), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label22), TRUE); + gtk_misc_set_padding (GTK_MISC (label22), 15, 0); + + frame18 = gtk_frame_new (NULL); + gtk_widget_show (frame18); + gtk_box_pack_start (GTK_BOX (vbox17), frame18, TRUE, TRUE, 5); + gtk_container_set_border_width (GTK_CONTAINER (frame18), 8); + + codec_info = gtk_label_new (_("No information availlable")); + gtk_widget_show (codec_info); + gtk_container_add (GTK_CONTAINER (frame18), codec_info); + gtk_label_set_justify (GTK_LABEL (codec_info), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (codec_info), TRUE); + gtk_misc_set_padding (GTK_MISC (codec_info), 10, 10); + + label47 = gtk_label_new (_("Codec information")); + gtk_widget_show (label47); + gtk_frame_set_label_widget (GTK_FRAME (frame18), label47); + + label46 = gtk_label_new (_("Audio and video codecs")); + gtk_widget_show (label46); + gtk_frame_set_label_widget (GTK_FRAME (frame16), label46); + gtk_misc_set_alignment (GTK_MISC (label46), 0.53, 0.5); + + codecs_pref = gtk_label_new (_("Codecs")); + gtk_widget_show (codecs_pref); + gtk_notebook_set_tab_label (GTK_NOTEBOOK (prop1notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (prop1notebook), 3), codecs_pref); + gtk_label_set_justify (GTK_LABEL (codecs_pref), GTK_JUSTIFY_CENTER); + + hbuttonbox7 = GTK_DIALOG (prop1)->action_area; + gtk_widget_show (hbuttonbox7); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox7), GTK_BUTTONBOX_END); + + prop_help_button = gtk_button_new_from_stock ("gtk-help"); + gtk_widget_show (prop_help_button); + gtk_dialog_add_action_widget (GTK_DIALOG (prop1), prop_help_button, GTK_RESPONSE_HELP); + GTK_WIDGET_SET_FLAGS (prop_help_button, GTK_CAN_DEFAULT); + + prop_apply_button = gtk_button_new_from_stock ("gtk-apply"); + gtk_widget_show (prop_apply_button); + gtk_dialog_add_action_widget (GTK_DIALOG (prop1), prop_apply_button, GTK_RESPONSE_APPLY); + GTK_WIDGET_SET_FLAGS (prop_apply_button, GTK_CAN_DEFAULT); + + prop_close_button = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (prop_close_button); + gtk_dialog_add_action_widget (GTK_DIALOG (prop1), prop_close_button, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (prop_close_button, GTK_CAN_DEFAULT); + + prop_ok_button = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (prop_ok_button); + gtk_dialog_add_action_widget (GTK_DIALOG (prop1), prop_ok_button, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (prop_ok_button, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) prop1, "close", + G_CALLBACK (on_prop1_close), + NULL); + g_signal_connect ((gpointer) prop1, "close", + G_CALLBACK (on_property_box_closed), + NULL); + g_signal_connect ((gpointer) prop1, "response", + G_CALLBACK (on_property_box_response), + NULL); + g_signal_connect ((gpointer) enable_ipv6, "toggled", + G_CALLBACK (on_enable_ipv6_toggled), + NULL); + g_signal_connect ((gpointer) no_nat, "toggled", + G_CALLBACK (on_no_nat_toggled), + NULL); + g_signal_connect ((gpointer) use_stun, "toggled", + G_CALLBACK (on_use_stun_toggled), + NULL); + g_signal_connect ((gpointer) static_nat, "toggled", + G_CALLBACK (on_static_nat_toggled), + NULL); + g_signal_connect ((gpointer) nat_address, "changed", + G_CALLBACK (on_nat_address_changed), + NULL); + g_signal_connect ((gpointer) stun_server, "changed", + G_CALLBACK (on_stun_server_changed), + NULL); + g_signal_connect ((gpointer) audio_jittcomp, "value_changed", + G_CALLBACK (on_audio_jittcomp_value_changed), + NULL); + g_signal_connect ((gpointer) audioport, "changed", + G_CALLBACK (on_audioport_changed), + NULL); + g_signal_connect ((gpointer) use_sipinfo, "toggled", + G_CALLBACK (on_use_sipinfo_toggled), + NULL); + g_signal_connect ((gpointer) rec_source, "changed", + G_CALLBACK (on_source_changed), + NULL); + g_signal_connect ((gpointer) play_card, "changed", + G_CALLBACK (on_play_card_changed), + NULL); + g_signal_connect ((gpointer) capt_card, "changed", + G_CALLBACK (on_capt_card_changed), + NULL); + g_signal_connect ((gpointer) ring_card, "changed", + G_CALLBACK (on_ring_card_changed), + NULL); + g_signal_connect ((gpointer) echocancelation, "toggled", + G_CALLBACK (on_echocancelation_toggled), + NULL); + g_signal_connect ((gpointer) ringpreview, "clicked", + G_CALLBACK (on_ringpreview_clicked), + NULL); + g_signal_connect ((gpointer) sip_port, "changed", + G_CALLBACK (on_sipport_changed), + NULL); + g_signal_connect ((gpointer) user_name, "changed", + G_CALLBACK (on_user_name_changed), + NULL); + g_signal_connect ((gpointer) domain_name, "changed", + G_CALLBACK (on_domain_name_changed), + NULL); + g_signal_connect ((gpointer) guess_hostname, "toggled", + G_CALLBACK (on_guess_hostname_toggled), + NULL); + g_signal_connect ((gpointer) addproxy_button, "clicked", + G_CALLBACK (on_addproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) editproxy_button, "clicked", + G_CALLBACK (on_editproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) removeproxy_button, "clicked", + G_CALLBACK (on_removeproxy_button_clicked), + NULL); + g_signal_connect ((gpointer) clear_auth_info, "clicked", + G_CALLBACK (on_clear_auth_info_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_up, "clicked", + G_CALLBACK (on_aucodec_up_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_down, "clicked", + G_CALLBACK (on_aucodec_down_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_enable, "clicked", + G_CALLBACK (on_aucodec_enable_clicked), + NULL); + g_signal_connect ((gpointer) aucodec_disable, "clicked", + G_CALLBACK (on_aucodec_disable_clicked), + NULL); + g_signal_connect ((gpointer) download_bw, "value_changed", + G_CALLBACK (on_download_bw_value_changed), + NULL); + g_signal_connect ((gpointer) upload_bw, "value_changed", + G_CALLBACK (on_upload_bw_value_changed), + NULL); + g_signal_connect ((gpointer) prop_help_button, "clicked", + G_CALLBACK (on_prop1_help), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (prop1, prop1, "prop1"); + GLADE_HOOKUP_OBJECT_NO_REF (prop1, prop1box, "prop1box"); + GLADE_HOOKUP_OBJECT (prop1, prop1notebook, "prop1notebook"); + GLADE_HOOKUP_OBJECT (prop1, vbox9, "vbox9"); + GLADE_HOOKUP_OBJECT (prop1, frame26, "frame26"); + GLADE_HOOKUP_OBJECT (prop1, alignment21, "alignment21"); + GLADE_HOOKUP_OBJECT (prop1, vbox29, "vbox29"); + GLADE_HOOKUP_OBJECT (prop1, enable_ipv6, "enable_ipv6"); + GLADE_HOOKUP_OBJECT (prop1, label105, "label105"); + GLADE_HOOKUP_OBJECT (prop1, frame21, "frame21"); + GLADE_HOOKUP_OBJECT (prop1, vbox21, "vbox21"); + GLADE_HOOKUP_OBJECT (prop1, label56, "label56"); + GLADE_HOOKUP_OBJECT (prop1, table13, "table13"); + GLADE_HOOKUP_OBJECT (prop1, no_nat, "no_nat"); + GLADE_HOOKUP_OBJECT (prop1, use_stun, "use_stun"); + GLADE_HOOKUP_OBJECT (prop1, static_nat, "static_nat"); + GLADE_HOOKUP_OBJECT (prop1, nat_address, "nat_address"); + GLADE_HOOKUP_OBJECT (prop1, stun_server, "stun_server"); + GLADE_HOOKUP_OBJECT (prop1, label55, "label55"); + GLADE_HOOKUP_OBJECT (prop1, frame20, "frame20"); + GLADE_HOOKUP_OBJECT (prop1, table6, "table6"); + GLADE_HOOKUP_OBJECT (prop1, audio_jittcomp, "audio_jittcomp"); + GLADE_HOOKUP_OBJECT (prop1, audioport, "audioport"); + GLADE_HOOKUP_OBJECT (prop1, label52, "label52"); + GLADE_HOOKUP_OBJECT (prop1, label53, "label53"); + GLADE_HOOKUP_OBJECT (prop1, label54, "label54"); + GLADE_HOOKUP_OBJECT (prop1, frame25, "frame25"); + GLADE_HOOKUP_OBJECT (prop1, alignment20, "alignment20"); + GLADE_HOOKUP_OBJECT (prop1, vbox28, "vbox28"); + GLADE_HOOKUP_OBJECT (prop1, use_sipinfo, "use_sipinfo"); + GLADE_HOOKUP_OBJECT (prop1, label103, "label103"); + GLADE_HOOKUP_OBJECT (prop1, network, "network"); + GLADE_HOOKUP_OBJECT (prop1, vbox12, "vbox12"); + GLADE_HOOKUP_OBJECT (prop1, vbox20, "vbox20"); + GLADE_HOOKUP_OBJECT (prop1, frame17, "frame17"); + GLADE_HOOKUP_OBJECT (prop1, vbox16, "vbox16"); + GLADE_HOOKUP_OBJECT (prop1, table4, "table4"); + GLADE_HOOKUP_OBJECT (prop1, label10, "label10"); + GLADE_HOOKUP_OBJECT (prop1, combo3, "combo3"); + GLADE_HOOKUP_OBJECT (prop1, rec_source, "rec_source"); + GLADE_HOOKUP_OBJECT (prop1, label106, "label106"); + GLADE_HOOKUP_OBJECT (prop1, play_card, "play_card"); + GLADE_HOOKUP_OBJECT (prop1, capt_card, "capt_card"); + GLADE_HOOKUP_OBJECT (prop1, label11, "label11"); + GLADE_HOOKUP_OBJECT (prop1, ringsnddev_label, "ringsnddev_label"); + GLADE_HOOKUP_OBJECT (prop1, label63, "label63"); + GLADE_HOOKUP_OBJECT (prop1, ring_card, "ring_card"); + GLADE_HOOKUP_OBJECT (prop1, echocancelation, "echocancelation"); + GLADE_HOOKUP_OBJECT (prop1, label115, "label115"); + GLADE_HOOKUP_OBJECT (prop1, hbox20, "hbox20"); + GLADE_HOOKUP_OBJECT (prop1, ringfileentry, "ringfileentry"); + GLADE_HOOKUP_OBJECT (prop1, ringpreview, "ringpreview"); + GLADE_HOOKUP_OBJECT (prop1, alignment24, "alignment24"); + GLADE_HOOKUP_OBJECT (prop1, hbox37, "hbox37"); + GLADE_HOOKUP_OBJECT (prop1, image42, "image42"); + GLADE_HOOKUP_OBJECT (prop1, label118, "label118"); + GLADE_HOOKUP_OBJECT (prop1, label48, "label48"); + GLADE_HOOKUP_OBJECT (prop1, sound, "sound"); + GLADE_HOOKUP_OBJECT (prop1, vbox7, "vbox7"); + GLADE_HOOKUP_OBJECT (prop1, frame10, "frame10"); + GLADE_HOOKUP_OBJECT (prop1, hbox6, "hbox6"); + GLADE_HOOKUP_OBJECT (prop1, label13, "label13"); + GLADE_HOOKUP_OBJECT (prop1, sip_port, "sip_port"); + GLADE_HOOKUP_OBJECT (prop1, label43, "label43"); + GLADE_HOOKUP_OBJECT (prop1, frame11, "frame11"); + GLADE_HOOKUP_OBJECT (prop1, vbox27, "vbox27"); + GLADE_HOOKUP_OBJECT (prop1, hbox7, "hbox7"); + GLADE_HOOKUP_OBJECT (prop1, label26, "label26"); + GLADE_HOOKUP_OBJECT (prop1, label27, "label27"); + GLADE_HOOKUP_OBJECT (prop1, user_name, "user_name"); + GLADE_HOOKUP_OBJECT (prop1, label28, "label28"); + GLADE_HOOKUP_OBJECT (prop1, domain_name, "domain_name"); + GLADE_HOOKUP_OBJECT (prop1, guess_hostname, "guess_hostname"); + GLADE_HOOKUP_OBJECT (prop1, label44, "label44"); + GLADE_HOOKUP_OBJECT (prop1, frame1, "frame1"); + GLADE_HOOKUP_OBJECT (prop1, vbox23, "vbox23"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow4, "scrolledwindow4"); + GLADE_HOOKUP_OBJECT (prop1, proxy_list, "proxy_list"); + GLADE_HOOKUP_OBJECT (prop1, hbuttonbox6, "hbuttonbox6"); + GLADE_HOOKUP_OBJECT (prop1, addproxy_button, "addproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment12, "alignment12"); + GLADE_HOOKUP_OBJECT (prop1, hbox25, "hbox25"); + GLADE_HOOKUP_OBJECT (prop1, image19, "image19"); + GLADE_HOOKUP_OBJECT (prop1, label77, "label77"); + GLADE_HOOKUP_OBJECT (prop1, editproxy_button, "editproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment13, "alignment13"); + GLADE_HOOKUP_OBJECT (prop1, hbox26, "hbox26"); + GLADE_HOOKUP_OBJECT (prop1, image20, "image20"); + GLADE_HOOKUP_OBJECT (prop1, label78, "label78"); + GLADE_HOOKUP_OBJECT (prop1, removeproxy_button, "removeproxy_button"); + GLADE_HOOKUP_OBJECT (prop1, alignment14, "alignment14"); + GLADE_HOOKUP_OBJECT (prop1, hbox27, "hbox27"); + GLADE_HOOKUP_OBJECT (prop1, image21, "image21"); + GLADE_HOOKUP_OBJECT (prop1, label79, "label79"); + GLADE_HOOKUP_OBJECT (prop1, label45, "label45"); + GLADE_HOOKUP_OBJECT (prop1, frame24, "frame24"); + GLADE_HOOKUP_OBJECT (prop1, alignment18, "alignment18"); + GLADE_HOOKUP_OBJECT (prop1, clear_auth_info, "clear_auth_info"); + GLADE_HOOKUP_OBJECT (prop1, alignment19, "alignment19"); + GLADE_HOOKUP_OBJECT (prop1, hbox34, "hbox34"); + GLADE_HOOKUP_OBJECT (prop1, image27, "image27"); + GLADE_HOOKUP_OBJECT (prop1, label102, "label102"); + GLADE_HOOKUP_OBJECT (prop1, label101, "label101"); + GLADE_HOOKUP_OBJECT (prop1, sip_pref, "sip_pref"); + GLADE_HOOKUP_OBJECT (prop1, vbox13, "vbox13"); + GLADE_HOOKUP_OBJECT (prop1, frame16, "frame16"); + GLADE_HOOKUP_OBJECT (prop1, hbox9, "hbox9"); + GLADE_HOOKUP_OBJECT (prop1, vbox14, "vbox14"); + GLADE_HOOKUP_OBJECT (prop1, label9, "label9"); + GLADE_HOOKUP_OBJECT (prop1, codec_notebook, "codec_notebook"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow2, "scrolledwindow2"); + GLADE_HOOKUP_OBJECT (prop1, au_codec_list, "au_codec_list"); + GLADE_HOOKUP_OBJECT (prop1, label116, "label116"); + GLADE_HOOKUP_OBJECT (prop1, scrolledwindow7, "scrolledwindow7"); + GLADE_HOOKUP_OBJECT (prop1, vid_codec_list, "vid_codec_list"); + GLADE_HOOKUP_OBJECT (prop1, label117, "label117"); + GLADE_HOOKUP_OBJECT (prop1, hbuttonbox4, "hbuttonbox4"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_up, "aucodec_up"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_down, "aucodec_down"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_enable, "aucodec_enable"); + GLADE_HOOKUP_OBJECT (prop1, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (prop1, hbox11, "hbox11"); + GLADE_HOOKUP_OBJECT (prop1, image4, "image4"); + GLADE_HOOKUP_OBJECT (prop1, label50, "label50"); + GLADE_HOOKUP_OBJECT (prop1, aucodec_disable, "aucodec_disable"); + GLADE_HOOKUP_OBJECT (prop1, alignment2, "alignment2"); + GLADE_HOOKUP_OBJECT (prop1, hbox12, "hbox12"); + GLADE_HOOKUP_OBJECT (prop1, image5, "image5"); + GLADE_HOOKUP_OBJECT (prop1, label51, "label51"); + GLADE_HOOKUP_OBJECT (prop1, table12, "table12"); + GLADE_HOOKUP_OBJECT (prop1, label112, "label112"); + GLADE_HOOKUP_OBJECT (prop1, label111, "label111"); + GLADE_HOOKUP_OBJECT (prop1, download_bw, "download_bw"); + GLADE_HOOKUP_OBJECT (prop1, upload_bw, "upload_bw"); + GLADE_HOOKUP_OBJECT (prop1, vbox17, "vbox17"); + GLADE_HOOKUP_OBJECT (prop1, label22, "label22"); + GLADE_HOOKUP_OBJECT (prop1, frame18, "frame18"); + GLADE_HOOKUP_OBJECT (prop1, codec_info, "codec_info"); + GLADE_HOOKUP_OBJECT (prop1, label47, "label47"); + GLADE_HOOKUP_OBJECT (prop1, label46, "label46"); + GLADE_HOOKUP_OBJECT (prop1, codecs_pref, "codecs_pref"); + GLADE_HOOKUP_OBJECT_NO_REF (prop1, hbuttonbox7, "hbuttonbox7"); + GLADE_HOOKUP_OBJECT (prop1, prop_help_button, "prop_help_button"); + GLADE_HOOKUP_OBJECT (prop1, prop_apply_button, "prop_apply_button"); + GLADE_HOOKUP_OBJECT (prop1, prop_close_button, "prop_close_button"); + GLADE_HOOKUP_OBJECT (prop1, prop_ok_button, "prop_ok_button"); + GLADE_HOOKUP_OBJECT_NO_REF (prop1, tooltips, "tooltips"); + + return prop1; +} + +GtkWidget* +create_address_book (void) +{ + GtkWidget *address_book; + GdkPixbuf *address_book_icon_pixbuf; + GtkWidget *dialog_vbox7; + GtkWidget *vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *viewport1; + GtkWidget *address_list; + GtkWidget *dialog_action_area7; + GtkWidget *hbuttonbox1; + GtkWidget *add_address; + GtkWidget *remove_address; + GtkWidget *modify_address; + GtkWidget *alignment15; + GtkWidget *hbox29; + GtkWidget *image22; + GtkWidget *label93; + GtkWidget *close_addbook; + GtkWidget *select_address; + GtkWidget *alignment7; + GtkWidget *hbox19; + GtkWidget *image14; + GtkWidget *label62; + + address_book = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (address_book), _("Address Book")); + gtk_window_set_default_size (GTK_WINDOW (address_book), -1, 305); + address_book_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (address_book_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (address_book), address_book_icon_pixbuf); + gdk_pixbuf_unref (address_book_icon_pixbuf); + } + + dialog_vbox7 = GTK_DIALOG (address_book)->vbox; + gtk_widget_show (dialog_vbox7); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_box_pack_start (GTK_BOX (dialog_vbox7), vbox1, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 12); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); + GTK_WIDGET_UNSET_FLAGS (scrolledwindow1, GTK_CAN_FOCUS); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN); + + viewport1 = gtk_viewport_new (NULL, NULL); + gtk_widget_show (viewport1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1); + + address_list = gtk_tree_view_new (); + gtk_widget_show (address_list); + gtk_container_add (GTK_CONTAINER (viewport1), address_list); + + dialog_action_area7 = GTK_DIALOG (address_book)->action_area; + gtk_widget_show (dialog_action_area7); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area7), GTK_BUTTONBOX_SPREAD); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_show (hbuttonbox1); + gtk_container_add (GTK_CONTAINER (dialog_action_area7), hbuttonbox1); + gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 11); + + add_address = gtk_button_new_from_stock ("gtk-add"); + gtk_widget_show (add_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), add_address); + GTK_WIDGET_SET_FLAGS (add_address, GTK_CAN_DEFAULT); + gtk_button_set_relief (GTK_BUTTON (add_address), GTK_RELIEF_HALF); + + remove_address = gtk_button_new_from_stock ("gtk-delete"); + gtk_widget_show (remove_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), remove_address); + GTK_WIDGET_SET_FLAGS (remove_address, GTK_CAN_DEFAULT); + gtk_button_set_relief (GTK_BUTTON (remove_address), GTK_RELIEF_HALF); + + modify_address = gtk_button_new (); + gtk_widget_show (modify_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), modify_address); + GTK_WIDGET_SET_FLAGS (modify_address, GTK_CAN_DEFAULT); + + alignment15 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment15); + gtk_container_add (GTK_CONTAINER (modify_address), alignment15); + + hbox29 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox29); + gtk_container_add (GTK_CONTAINER (alignment15), hbox29); + + image22 = gtk_image_new_from_stock ("gtk-justify-center", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image22); + gtk_box_pack_start (GTK_BOX (hbox29), image22, FALSE, FALSE, 0); + + label93 = gtk_label_new_with_mnemonic (_("Edit")); + gtk_widget_show (label93); + gtk_box_pack_start (GTK_BOX (hbox29), label93, FALSE, FALSE, 0); + + close_addbook = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (close_addbook); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), close_addbook); + GTK_WIDGET_SET_FLAGS (close_addbook, GTK_CAN_DEFAULT); + + select_address = gtk_button_new (); + gtk_widget_show (select_address); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), select_address); + GTK_WIDGET_SET_FLAGS (select_address, GTK_CAN_DEFAULT); + + alignment7 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment7); + gtk_container_add (GTK_CONTAINER (select_address), alignment7); + + hbox19 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox19); + gtk_container_add (GTK_CONTAINER (alignment7), hbox19); + + image14 = gtk_image_new_from_stock ("gtk-quit", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image14); + gtk_box_pack_start (GTK_BOX (hbox19), image14, FALSE, FALSE, 0); + + label62 = gtk_label_new_with_mnemonic (_("Select")); + gtk_widget_show (label62); + gtk_box_pack_start (GTK_BOX (hbox19), label62, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) add_address, "clicked", + G_CALLBACK (on_add_address_clicked), + NULL); + g_signal_connect ((gpointer) remove_address, "clicked", + G_CALLBACK (on_remove_address_clicked), + NULL); + g_signal_connect ((gpointer) modify_address, "clicked", + G_CALLBACK (on_modify_address_clicked), + NULL); + g_signal_connect ((gpointer) close_addbook, "clicked", + G_CALLBACK (address_book_close), + NULL); + g_signal_connect ((gpointer) select_address, "clicked", + G_CALLBACK (on_select_address_clicked), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (address_book, address_book, "address_book"); + GLADE_HOOKUP_OBJECT_NO_REF (address_book, dialog_vbox7, "dialog_vbox7"); + GLADE_HOOKUP_OBJECT (address_book, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (address_book, scrolledwindow1, "scrolledwindow1"); + GLADE_HOOKUP_OBJECT (address_book, viewport1, "viewport1"); + GLADE_HOOKUP_OBJECT (address_book, address_list, "address_list"); + GLADE_HOOKUP_OBJECT_NO_REF (address_book, dialog_action_area7, "dialog_action_area7"); + GLADE_HOOKUP_OBJECT (address_book, hbuttonbox1, "hbuttonbox1"); + GLADE_HOOKUP_OBJECT (address_book, add_address, "add_address"); + GLADE_HOOKUP_OBJECT (address_book, remove_address, "remove_address"); + GLADE_HOOKUP_OBJECT (address_book, modify_address, "modify_address"); + GLADE_HOOKUP_OBJECT (address_book, alignment15, "alignment15"); + GLADE_HOOKUP_OBJECT (address_book, hbox29, "hbox29"); + GLADE_HOOKUP_OBJECT (address_book, image22, "image22"); + GLADE_HOOKUP_OBJECT (address_book, label93, "label93"); + GLADE_HOOKUP_OBJECT (address_book, close_addbook, "close_addbook"); + GLADE_HOOKUP_OBJECT (address_book, select_address, "select_address"); + GLADE_HOOKUP_OBJECT (address_book, alignment7, "alignment7"); + GLADE_HOOKUP_OBJECT (address_book, hbox19, "hbox19"); + GLADE_HOOKUP_OBJECT (address_book, image14, "image14"); + GLADE_HOOKUP_OBJECT (address_book, label62, "label62"); + + return address_book; +} + +GtkWidget* +create_altressource (void) +{ + GtkWidget *altressource; + GdkPixbuf *altressource_icon_pixbuf; + GtkWidget *dialog_vbox10; + GtkWidget *vbox19; + GtkWidget *label49; + GtkWidget *alt_href; + GtkWidget *dialog_action_area10; + GtkWidget *closebutton1; + + altressource = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (altressource), _("Information")); + gtk_window_set_resizable (GTK_WINDOW (altressource), FALSE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (altressource), TRUE); + altressource_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (altressource_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (altressource), altressource_icon_pixbuf); + gdk_pixbuf_unref (altressource_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (altressource), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox10 = GTK_DIALOG (altressource)->vbox; + gtk_widget_show (dialog_vbox10); + + vbox19 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox19); + gtk_box_pack_start (GTK_BOX (dialog_vbox10), vbox19, TRUE, TRUE, 0); + + label49 = gtk_label_new (_("User is not reachable at the moment but he invites you to contact him using the following alternate ressource:")); + gtk_widget_show (label49); + gtk_box_pack_start (GTK_BOX (vbox19), label49, TRUE, TRUE, 10); + gtk_label_set_justify (GTK_LABEL (label49), GTK_JUSTIFY_CENTER); + gtk_label_set_line_wrap (GTK_LABEL (label49), TRUE); + gtk_misc_set_padding (GTK_MISC (label49), 25, 5); + + alt_href = gtk_button_new_with_mnemonic (_("None.")); + gtk_widget_show (alt_href); + gtk_box_pack_start (GTK_BOX (vbox19), alt_href, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (alt_href), 12); + gtk_button_set_relief (GTK_BUTTON (alt_href), GTK_RELIEF_NONE); + + dialog_action_area10 = GTK_DIALOG (altressource)->action_area; + gtk_widget_show (dialog_action_area10); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area10), GTK_BUTTONBOX_END); + + closebutton1 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (closebutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (altressource), closebutton1, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT); + + g_signal_connect_swapped ((gpointer) alt_href, "clicked", + G_CALLBACK (on_alt_href_clicked), + GTK_OBJECT (altressource)); + g_signal_connect ((gpointer) alt_href, "realize", + G_CALLBACK (on_alt_href_realize), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (altressource, altressource, "altressource"); + GLADE_HOOKUP_OBJECT_NO_REF (altressource, dialog_vbox10, "dialog_vbox10"); + GLADE_HOOKUP_OBJECT (altressource, vbox19, "vbox19"); + GLADE_HOOKUP_OBJECT (altressource, label49, "label49"); + GLADE_HOOKUP_OBJECT (altressource, alt_href, "alt_href"); + GLADE_HOOKUP_OBJECT_NO_REF (altressource, dialog_action_area10, "dialog_action_area10"); + GLADE_HOOKUP_OBJECT (altressource, closebutton1, "closebutton1"); + + return altressource; +} + +GtkWidget* +create_proxy_config_box (void) +{ + GtkWidget *proxy_config_box; + GdkPixbuf *proxy_config_box_icon_pixbuf; + GtkWidget *dialog_vbox12; + GtkWidget *frame22; + GtkWidget *table8; + GtkWidget *reg_sendregister; + GtkWidget *label82; + GtkWidget *reg_route; + GtkWidget *reg_proxy; + GtkWidget *label83; + GtkWidget *label84; + GtkWidget *reg_identity; + GtkWidget *label85; + GtkObject *reg_expires_adj; + GtkWidget *reg_expires; + GtkWidget *label81; + GtkWidget *label104; + GtkWidget *publish; + GtkWidget *label86; + GtkWidget *dialog_action_area12; + GtkWidget *helpbutton1; + GtkWidget *okbutton2; + + proxy_config_box = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (proxy_config_box), _("Proxy/Registrar configuration box")); + gtk_window_set_modal (GTK_WINDOW (proxy_config_box), TRUE); + gtk_window_set_destroy_with_parent (GTK_WINDOW (proxy_config_box), TRUE); + proxy_config_box_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (proxy_config_box_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (proxy_config_box), proxy_config_box_icon_pixbuf); + gdk_pixbuf_unref (proxy_config_box_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (proxy_config_box), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox12 = GTK_DIALOG (proxy_config_box)->vbox; + gtk_widget_show (dialog_vbox12); + + frame22 = gtk_frame_new (NULL); + gtk_widget_show (frame22); + gtk_box_pack_start (GTK_BOX (dialog_vbox12), frame22, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame22), 8); + + table8 = gtk_table_new (7, 2, FALSE); + gtk_widget_show (table8); + gtk_container_add (GTK_CONTAINER (frame22), table8); + + reg_sendregister = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (reg_sendregister); + gtk_table_attach (GTK_TABLE (table8), reg_sendregister, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (reg_sendregister), TRUE); + + label82 = gtk_label_new (_("Route (optional):")); + gtk_widget_show (label82); + gtk_table_attach (GTK_TABLE (table8), label82, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label82), 0, 0.5); + + reg_route = gtk_entry_new (); + gtk_widget_show (reg_route); + gtk_table_attach (GTK_TABLE (table8), reg_route, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_route), 256); + + reg_proxy = gtk_entry_new (); + gtk_widget_show (reg_proxy); + gtk_table_attach (GTK_TABLE (table8), reg_proxy, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_proxy), 250); + gtk_entry_set_text (GTK_ENTRY (reg_proxy), _("sip:")); + + label83 = gtk_label_new (_("SIP Proxy:")); + gtk_widget_show (label83); + gtk_table_attach (GTK_TABLE (table8), label83, 0, 1, 4, 5, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label83), 0, 0.5); + + label84 = gtk_label_new (_("SIP Identity:")); + gtk_widget_show (label84); + gtk_table_attach (GTK_TABLE (table8), label84, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label84), 0, 0.5); + + reg_identity = gtk_entry_new (); + gtk_widget_show (reg_identity); + gtk_table_attach (GTK_TABLE (table8), reg_identity, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (reg_identity), 256); + gtk_entry_set_text (GTK_ENTRY (reg_identity), _("sip:")); + + label85 = gtk_label_new (_("Registration Period:")); + gtk_widget_show (label85); + gtk_table_attach (GTK_TABLE (table8), label85, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label85), 0, 0.5); + + reg_expires_adj = gtk_adjustment_new (900, 120, 72000, 1, 10, 10); + reg_expires = gtk_spin_button_new (GTK_ADJUSTMENT (reg_expires_adj), 1, 0); + gtk_widget_show (reg_expires); + gtk_table_attach (GTK_TABLE (table8), reg_expires, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (reg_expires), TRUE); + + label81 = gtk_label_new (_("Send registration:")); + gtk_widget_show (label81); + gtk_table_attach (GTK_TABLE (table8), label81, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label81), 0, 0.5); + + label104 = gtk_label_new (_("Publish presence information:")); + gtk_widget_show (label104); + gtk_table_attach (GTK_TABLE (table8), label104, 0, 1, 6, 7, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label104), 0, 0.5); + + publish = gtk_check_button_new_with_mnemonic (""); + gtk_widget_show (publish); + gtk_table_attach (GTK_TABLE (table8), publish, 1, 2, 6, 7, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label86 = gtk_label_new (_("Proxy/Registrar configuration box")); + gtk_widget_show (label86); + gtk_frame_set_label_widget (GTK_FRAME (frame22), label86); + + dialog_action_area12 = GTK_DIALOG (proxy_config_box)->action_area; + gtk_widget_show (dialog_action_area12); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area12), GTK_BUTTONBOX_END); + + helpbutton1 = gtk_button_new_from_stock ("gtk-help"); + gtk_widget_show (helpbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (proxy_config_box), helpbutton1, GTK_RESPONSE_HELP); + GTK_WIDGET_SET_FLAGS (helpbutton1, GTK_CAN_DEFAULT); + + okbutton2 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (proxy_config_box), okbutton2, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) proxy_config_box, "response", + G_CALLBACK (on_proxy_config_box_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, proxy_config_box, "proxy_config_box"); + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, dialog_vbox12, "dialog_vbox12"); + GLADE_HOOKUP_OBJECT (proxy_config_box, frame22, "frame22"); + GLADE_HOOKUP_OBJECT (proxy_config_box, table8, "table8"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_sendregister, "reg_sendregister"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label82, "label82"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_route, "reg_route"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_proxy, "reg_proxy"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label83, "label83"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label84, "label84"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_identity, "reg_identity"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label85, "label85"); + GLADE_HOOKUP_OBJECT (proxy_config_box, reg_expires, "reg_expires"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label81, "label81"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label104, "label104"); + GLADE_HOOKUP_OBJECT (proxy_config_box, publish, "publish"); + GLADE_HOOKUP_OBJECT (proxy_config_box, label86, "label86"); + GLADE_HOOKUP_OBJECT_NO_REF (proxy_config_box, dialog_action_area12, "dialog_action_area12"); + GLADE_HOOKUP_OBJECT (proxy_config_box, helpbutton1, "helpbutton1"); + GLADE_HOOKUP_OBJECT (proxy_config_box, okbutton2, "okbutton2"); + + gtk_widget_grab_focus (proxy_config_box); + return proxy_config_box; +} + +GtkWidget* +create_contact_box (void) +{ + GtkWidget *contact_box; + GdkPixbuf *contact_box_icon_pixbuf; + GtkWidget *dialog_vbox13; + GtkWidget *frame23; + GtkWidget *vbox25; + GtkWidget *table10; + GtkWidget *sipaddr; + GtkWidget *name; + GtkWidget *label89; + GtkWidget *label90; + GtkWidget *label91; + GtkWidget *label92; + GtkWidget *send_subscribe; + GtkWidget *label88; + GtkWidget *dialog_action_area13; + GtkWidget *helpbutton2; + GtkWidget *cancelbutton2; + GtkWidget *okbutton3; + + contact_box = gtk_dialog_new (); + GTK_WIDGET_SET_FLAGS (contact_box, GTK_CAN_FOCUS); + gtk_window_set_title (GTK_WINDOW (contact_box), _("Edit contact information")); + gtk_window_set_destroy_with_parent (GTK_WINDOW (contact_box), TRUE); + contact_box_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (contact_box_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (contact_box), contact_box_icon_pixbuf); + gdk_pixbuf_unref (contact_box_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (contact_box), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox13 = GTK_DIALOG (contact_box)->vbox; + gtk_widget_show (dialog_vbox13); + + frame23 = gtk_frame_new (NULL); + gtk_widget_show (frame23); + gtk_box_pack_start (GTK_BOX (dialog_vbox13), frame23, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame23), 6); + + vbox25 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox25); + gtk_container_add (GTK_CONTAINER (frame23), vbox25); + + table10 = gtk_table_new (4, 2, TRUE); + gtk_widget_show (table10); + gtk_box_pack_start (GTK_BOX (vbox25), table10, TRUE, TRUE, 0); + + sipaddr = gtk_entry_new (); + gtk_widget_show (sipaddr); + gtk_table_attach (GTK_TABLE (table10), sipaddr, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_text (GTK_ENTRY (sipaddr), _("sip:")); + + name = gtk_entry_new (); + gtk_widget_show (name); + gtk_table_attach (GTK_TABLE (table10), name, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label89 = gtk_label_new (_("Name:")); + gtk_widget_show (label89); + gtk_table_attach (GTK_TABLE (table10), label89, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label89), 0, 0.5); + + label90 = gtk_label_new (_("Sip address:")); + gtk_widget_show (label90); + gtk_table_attach (GTK_TABLE (table10), label90, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label90), 0, 0.5); + + label91 = gtk_label_new (_("Proxy to use:")); + gtk_widget_show (label91); + gtk_table_attach (GTK_TABLE (table10), label91, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label91), 0, 0.5); + + label92 = gtk_label_new (_("Subscribe policy:")); + gtk_widget_show (label92); + gtk_table_attach (GTK_TABLE (table10), label92, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label92), 0, 0.5); + + send_subscribe = gtk_check_button_new_with_mnemonic (_("Send subscription (see person's online status)")); + gtk_widget_show (send_subscribe); + gtk_box_pack_start (GTK_BOX (vbox25), send_subscribe, TRUE, TRUE, 0); + + label88 = gtk_label_new (_("Contact information")); + gtk_widget_show (label88); + gtk_frame_set_label_widget (GTK_FRAME (frame23), label88); + + dialog_action_area13 = GTK_DIALOG (contact_box)->action_area; + gtk_widget_show (dialog_action_area13); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area13), GTK_BUTTONBOX_END); + + helpbutton2 = gtk_button_new_from_stock ("gtk-help"); + gtk_widget_show (helpbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), helpbutton2, GTK_RESPONSE_HELP); + GTK_WIDGET_SET_FLAGS (helpbutton2, GTK_CAN_DEFAULT); + + cancelbutton2 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), cancelbutton2, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT); + + okbutton3 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton3); + gtk_dialog_add_action_widget (GTK_DIALOG (contact_box), okbutton3, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton3, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) contact_box, "response", + G_CALLBACK (on_contact_box_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, contact_box, "contact_box"); + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, dialog_vbox13, "dialog_vbox13"); + GLADE_HOOKUP_OBJECT (contact_box, frame23, "frame23"); + GLADE_HOOKUP_OBJECT (contact_box, vbox25, "vbox25"); + GLADE_HOOKUP_OBJECT (contact_box, table10, "table10"); + GLADE_HOOKUP_OBJECT (contact_box, sipaddr, "sipaddr"); + GLADE_HOOKUP_OBJECT (contact_box, name, "name"); + GLADE_HOOKUP_OBJECT (contact_box, label89, "label89"); + GLADE_HOOKUP_OBJECT (contact_box, label90, "label90"); + GLADE_HOOKUP_OBJECT (contact_box, label91, "label91"); + GLADE_HOOKUP_OBJECT (contact_box, label92, "label92"); + GLADE_HOOKUP_OBJECT (contact_box, send_subscribe, "send_subscribe"); + GLADE_HOOKUP_OBJECT (contact_box, label88, "label88"); + GLADE_HOOKUP_OBJECT_NO_REF (contact_box, dialog_action_area13, "dialog_action_area13"); + GLADE_HOOKUP_OBJECT (contact_box, helpbutton2, "helpbutton2"); + GLADE_HOOKUP_OBJECT (contact_box, cancelbutton2, "cancelbutton2"); + GLADE_HOOKUP_OBJECT (contact_box, okbutton3, "okbutton3"); + + return contact_box; +} + +GtkWidget* +create_inc_subscr_dialog (void) +{ + GtkWidget *inc_subscr_dialog; + GdkPixbuf *inc_subscr_dialog_icon_pixbuf; + GtkWidget *dialog_vbox14; + GtkWidget *hbox32; + GtkWidget *image25; + GtkWidget *subscr_label; + GtkWidget *dialog_action_area14; + GtkWidget *button15; + GtkWidget *alignment17; + GtkWidget *hbox31; + GtkWidget *image24; + GtkWidget *label95; + GtkWidget *button16; + GtkWidget *alignment16; + GtkWidget *hbox30; + GtkWidget *image23; + GtkWidget *label94; + + inc_subscr_dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (inc_subscr_dialog), _("New incoming subscription")); + inc_subscr_dialog_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (inc_subscr_dialog_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (inc_subscr_dialog), inc_subscr_dialog_icon_pixbuf); + gdk_pixbuf_unref (inc_subscr_dialog_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (inc_subscr_dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox14 = GTK_DIALOG (inc_subscr_dialog)->vbox; + gtk_widget_show (dialog_vbox14); + + hbox32 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox32); + gtk_box_pack_start (GTK_BOX (dialog_vbox14), hbox32, TRUE, TRUE, 0); + + image25 = gtk_image_new_from_stock ("gtk-dialog-warning", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image25); + gtk_box_pack_start (GTK_BOX (hbox32), image25, FALSE, TRUE, 0); + + subscr_label = gtk_label_new (_("You have received a new subscription...")); + gtk_widget_show (subscr_label); + gtk_box_pack_start (GTK_BOX (hbox32), subscr_label, TRUE, TRUE, 0); + gtk_label_set_line_wrap (GTK_LABEL (subscr_label), TRUE); + gtk_misc_set_padding (GTK_MISC (subscr_label), 14, 9); + + dialog_action_area14 = GTK_DIALOG (inc_subscr_dialog)->action_area; + gtk_widget_show (dialog_action_area14); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area14), GTK_BUTTONBOX_SPREAD); + + button15 = gtk_button_new (); + gtk_widget_show (button15); + gtk_dialog_add_action_widget (GTK_DIALOG (inc_subscr_dialog), button15, GTK_RESPONSE_REJECT); + GTK_WIDGET_SET_FLAGS (button15, GTK_CAN_DEFAULT); + + alignment17 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment17); + gtk_container_add (GTK_CONTAINER (button15), alignment17); + + hbox31 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox31); + gtk_container_add (GTK_CONTAINER (alignment17), hbox31); + + image24 = gtk_image_new_from_stock ("gtk-stop", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image24); + gtk_box_pack_start (GTK_BOX (hbox31), image24, FALSE, FALSE, 0); + + label95 = gtk_label_new_with_mnemonic (_("Refuse")); + gtk_widget_show (label95); + gtk_box_pack_start (GTK_BOX (hbox31), label95, FALSE, FALSE, 0); + + button16 = gtk_button_new (); + gtk_widget_show (button16); + gtk_dialog_add_action_widget (GTK_DIALOG (inc_subscr_dialog), button16, GTK_RESPONSE_ACCEPT); + GTK_WIDGET_SET_FLAGS (button16, GTK_CAN_DEFAULT); + + alignment16 = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_widget_show (alignment16); + gtk_container_add (GTK_CONTAINER (button16), alignment16); + + hbox30 = gtk_hbox_new (FALSE, 2); + gtk_widget_show (hbox30); + gtk_container_add (GTK_CONTAINER (alignment16), hbox30); + + image23 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image23); + gtk_box_pack_start (GTK_BOX (hbox30), image23, FALSE, FALSE, 0); + + label94 = gtk_label_new_with_mnemonic (_("Accept")); + gtk_widget_show (label94); + gtk_box_pack_start (GTK_BOX (hbox30), label94, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) inc_subscr_dialog, "response", + G_CALLBACK (on_inc_subscr_dialog_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, inc_subscr_dialog, "inc_subscr_dialog"); + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, dialog_vbox14, "dialog_vbox14"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox32, "hbox32"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image25, "image25"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, subscr_label, "subscr_label"); + GLADE_HOOKUP_OBJECT_NO_REF (inc_subscr_dialog, dialog_action_area14, "dialog_action_area14"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, button15, "button15"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, alignment17, "alignment17"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox31, "hbox31"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image24, "image24"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, label95, "label95"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, button16, "button16"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, alignment16, "alignment16"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, hbox30, "hbox30"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, image23, "image23"); + GLADE_HOOKUP_OBJECT (inc_subscr_dialog, label94, "label94"); + + return inc_subscr_dialog; +} + +GtkWidget* +create_authentication_dialog (void) +{ + GtkWidget *authentication_dialog; + GdkPixbuf *authentication_dialog_icon_pixbuf; + GtkWidget *dialog_vbox15; + GtkWidget *vbox26; + GtkWidget *hbox33; + GtkWidget *image26; + GtkWidget *question; + GtkWidget *table11; + GtkWidget *realm; + GtkWidget *username; + GtkWidget *passwd; + GtkWidget *userid; + GtkWidget *label100; + GtkWidget *label99; + GtkWidget *label98; + GtkWidget *label97; + GtkWidget *dialog_action_area15; + GtkWidget *cancelbutton3; + GtkWidget *okbutton4; + + authentication_dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (authentication_dialog), _("Authentication requested")); + gtk_window_set_destroy_with_parent (GTK_WINDOW (authentication_dialog), TRUE); + authentication_dialog_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (authentication_dialog_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (authentication_dialog), authentication_dialog_icon_pixbuf); + gdk_pixbuf_unref (authentication_dialog_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (authentication_dialog), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox15 = GTK_DIALOG (authentication_dialog)->vbox; + gtk_widget_show (dialog_vbox15); + + vbox26 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox26); + gtk_box_pack_start (GTK_BOX (dialog_vbox15), vbox26, TRUE, TRUE, 0); + + hbox33 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox33); + gtk_box_pack_start (GTK_BOX (vbox26), hbox33, FALSE, FALSE, 0); + + image26 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image26); + gtk_box_pack_start (GTK_BOX (hbox33), image26, TRUE, TRUE, 0); + gtk_misc_set_padding (GTK_MISC (image26), 16, 0); + + question = gtk_label_new (_("Authentication required for realm")); + gtk_widget_show (question); + gtk_box_pack_start (GTK_BOX (hbox33), question, TRUE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (question), GTK_JUSTIFY_CENTER); + gtk_misc_set_padding (GTK_MISC (question), 29, 14); + + table11 = gtk_table_new (5, 2, FALSE); + gtk_widget_show (table11); + gtk_box_pack_start (GTK_BOX (vbox26), table11, TRUE, TRUE, 0); + + realm = gtk_entry_new (); + gtk_widget_show (realm); + gtk_table_attach (GTK_TABLE (table11), realm, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_editable_set_editable (GTK_EDITABLE (realm), FALSE); + + username = gtk_entry_new (); + gtk_widget_show (username); + gtk_table_attach (GTK_TABLE (table11), username, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + passwd = gtk_entry_new (); + gtk_widget_show (passwd); + gtk_table_attach (GTK_TABLE (table11), passwd, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_visibility (GTK_ENTRY (passwd), FALSE); + + userid = gtk_entry_new (); + gtk_widget_show (userid); + gtk_table_attach (GTK_TABLE (table11), userid, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + label100 = gtk_label_new (_("userid:")); + gtk_widget_show (label100); + gtk_table_attach (GTK_TABLE (table11), label100, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label100), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label100), 0, 0.5); + + label99 = gtk_label_new (_("password:")); + gtk_widget_show (label99); + gtk_table_attach (GTK_TABLE (table11), label99, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label99), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label99), 0, 0.5); + + label98 = gtk_label_new (_("username:")); + gtk_widget_show (label98); + gtk_table_attach (GTK_TABLE (table11), label98, 0, 1, 1, 2, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label98), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label98), 0, 0.5); + + label97 = gtk_label_new (_("realm:")); + gtk_widget_show (label97); + gtk_table_attach (GTK_TABLE (table11), label97, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_EXPAND), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label97), GTK_JUSTIFY_CENTER); + gtk_misc_set_alignment (GTK_MISC (label97), 0, 0.5); + + dialog_action_area15 = GTK_DIALOG (authentication_dialog)->action_area; + gtk_widget_show (dialog_action_area15); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area15), GTK_BUTTONBOX_END); + + cancelbutton3 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton3); + gtk_dialog_add_action_widget (GTK_DIALOG (authentication_dialog), cancelbutton3, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton3, GTK_CAN_DEFAULT); + + okbutton4 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton4); + gtk_dialog_add_action_widget (GTK_DIALOG (authentication_dialog), okbutton4, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton4, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) authentication_dialog, "response", + G_CALLBACK (on_authentication_dialog_response), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, authentication_dialog, "authentication_dialog"); + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, dialog_vbox15, "dialog_vbox15"); + GLADE_HOOKUP_OBJECT (authentication_dialog, vbox26, "vbox26"); + GLADE_HOOKUP_OBJECT (authentication_dialog, hbox33, "hbox33"); + GLADE_HOOKUP_OBJECT (authentication_dialog, image26, "image26"); + GLADE_HOOKUP_OBJECT (authentication_dialog, question, "question"); + GLADE_HOOKUP_OBJECT (authentication_dialog, table11, "table11"); + GLADE_HOOKUP_OBJECT (authentication_dialog, realm, "realm"); + GLADE_HOOKUP_OBJECT (authentication_dialog, username, "username"); + GLADE_HOOKUP_OBJECT (authentication_dialog, passwd, "passwd"); + GLADE_HOOKUP_OBJECT (authentication_dialog, userid, "userid"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label100, "label100"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label99, "label99"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label98, "label98"); + GLADE_HOOKUP_OBJECT (authentication_dialog, label97, "label97"); + GLADE_HOOKUP_OBJECT_NO_REF (authentication_dialog, dialog_action_area15, "dialog_action_area15"); + GLADE_HOOKUP_OBJECT (authentication_dialog, cancelbutton3, "cancelbutton3"); + GLADE_HOOKUP_OBJECT (authentication_dialog, okbutton4, "okbutton4"); + + return authentication_dialog; +} + +GtkWidget* +create_call_logs (void) +{ + GtkWidget *call_logs; + GdkPixbuf *call_logs_icon_pixbuf; + GtkWidget *dialog_vbox16; + GtkWidget *scrolledwindow5; + GtkWidget *logview; + GtkWidget *dialog_action_area16; + GtkWidget *closebutton2; + + call_logs = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (call_logs), _("Linphone - Call history")); + gtk_window_set_default_size (GTK_WINDOW (call_logs), 240, 240); + gtk_window_set_destroy_with_parent (GTK_WINDOW (call_logs), TRUE); + call_logs_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (call_logs_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (call_logs), call_logs_icon_pixbuf); + gdk_pixbuf_unref (call_logs_icon_pixbuf); + } + gtk_window_set_type_hint (GTK_WINDOW (call_logs), GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog_vbox16 = GTK_DIALOG (call_logs)->vbox; + gtk_widget_show (dialog_vbox16); + + scrolledwindow5 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow5); + gtk_box_pack_start (GTK_BOX (dialog_vbox16), scrolledwindow5, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_SHADOW_IN); + + logview = gtk_text_view_new (); + gtk_widget_show (logview); + gtk_container_add (GTK_CONTAINER (scrolledwindow5), logview); + gtk_text_view_set_editable (GTK_TEXT_VIEW (logview), FALSE); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (logview), FALSE); + + dialog_action_area16 = GTK_DIALOG (call_logs)->action_area; + gtk_widget_show (dialog_action_area16); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area16), GTK_BUTTONBOX_END); + + closebutton2 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (closebutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (call_logs), closebutton2, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (closebutton2, GTK_CAN_DEFAULT); + + g_signal_connect ((gpointer) call_logs, "response", + G_CALLBACK (on_call_logs_response), + NULL); + g_signal_connect ((gpointer) call_logs, "destroy", + G_CALLBACK (on_call_logs_destroy), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, call_logs, "call_logs"); + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, dialog_vbox16, "dialog_vbox16"); + GLADE_HOOKUP_OBJECT (call_logs, scrolledwindow5, "scrolledwindow5"); + GLADE_HOOKUP_OBJECT (call_logs, logview, "logview"); + GLADE_HOOKUP_OBJECT_NO_REF (call_logs, dialog_action_area16, "dialog_action_area16"); + GLADE_HOOKUP_OBJECT (call_logs, closebutton2, "closebutton2"); + + return call_logs; +} + +GtkWidget* +create_chatroom (void) +{ + GtkWidget *chatroom; + GdkPixbuf *chatroom_icon_pixbuf; + GtkWidget *vbox30; + GtkWidget *scrolledwindow6; + GtkWidget *chattext; + GtkWidget *hbox35; + GtkWidget *label107; + GtkWidget *chatentry; + GtkWidget *button17; + + chatroom = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (chatroom), _("Chat Room")); + gtk_window_set_default_size (GTK_WINDOW (chatroom), 400, 400); + gtk_window_set_destroy_with_parent (GTK_WINDOW (chatroom), TRUE); + chatroom_icon_pixbuf = create_pixbuf ("linphone2.xpm"); + if (chatroom_icon_pixbuf) + { + gtk_window_set_icon (GTK_WINDOW (chatroom), chatroom_icon_pixbuf); + gdk_pixbuf_unref (chatroom_icon_pixbuf); + } + + vbox30 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox30); + gtk_container_add (GTK_CONTAINER (chatroom), vbox30); + + scrolledwindow6 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow6); + gtk_box_pack_start (GTK_BOX (vbox30), scrolledwindow6, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow6), GTK_SHADOW_IN); + + chattext = gtk_text_view_new (); + gtk_widget_show (chattext); + gtk_container_add (GTK_CONTAINER (scrolledwindow6), chattext); + gtk_text_view_set_editable (GTK_TEXT_VIEW (chattext), FALSE); + + hbox35 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox35); + gtk_box_pack_start (GTK_BOX (vbox30), hbox35, FALSE, TRUE, 0); + + label107 = gtk_label_new (_("Text:")); + gtk_widget_show (label107); + gtk_box_pack_start (GTK_BOX (hbox35), label107, FALSE, FALSE, 0); + + chatentry = gtk_entry_new (); + gtk_widget_show (chatentry); + gtk_box_pack_start (GTK_BOX (hbox35), chatentry, TRUE, TRUE, 0); + + button17 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (button17); + gtk_box_pack_start (GTK_BOX (vbox30), button17, FALSE, FALSE, 0); + + g_signal_connect ((gpointer) chatroom, "destroy", + G_CALLBACK (on_chatroom_destroy), + NULL); + g_signal_connect ((gpointer) chatentry, "activate", + G_CALLBACK (on_chatentry_activate), + NULL); + g_signal_connect ((gpointer) button17, "clicked", + G_CALLBACK (on_chatbox_clicked), + NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (chatroom, chatroom, "chatroom"); + GLADE_HOOKUP_OBJECT (chatroom, vbox30, "vbox30"); + GLADE_HOOKUP_OBJECT (chatroom, scrolledwindow6, "scrolledwindow6"); + GLADE_HOOKUP_OBJECT (chatroom, chattext, "chattext"); + GLADE_HOOKUP_OBJECT (chatroom, hbox35, "hbox35"); + GLADE_HOOKUP_OBJECT (chatroom, label107, "label107"); + GLADE_HOOKUP_OBJECT (chatroom, chatentry, "chatentry"); + GLADE_HOOKUP_OBJECT (chatroom, button17, "button17"); + + gtk_widget_grab_focus (chatentry); + return chatroom; +} + +GtkWidget* +create_aboutdialog1 (void) +{ + GtkWidget *aboutdialog1; + const gchar *authors[] = { + "Simon MORLAT", + "Aymeric Moizard", + "Sharath K Udupa", + NULL + }; + const gchar *documenters[] = { + "Simon MORLAT", + "Philippe Beau", + NULL + }; + gchar *translators = "it: Alberto Zanoni\nde: Jean Jacques Sarton\nfr: Simon Morlat\nes: Jesus Benitez\nja: Yamaguchi Yoshiya\npl: obert Nasiadek \npt_BR: Rafael Caesar Lenzi \nsv: Daniel Nylander "; + GdkPixbuf *aboutdialog1_logo_pixbuf; + + aboutdialog1 = gtk_about_dialog_new (); + gtk_container_set_border_width (GTK_CONTAINER (aboutdialog1), 5); + gtk_window_set_destroy_with_parent (GTK_WINDOW (aboutdialog1), TRUE); + gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (aboutdialog1), VERSION); + gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (aboutdialog1), _("Linphone")); + gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (aboutdialog1), _("C: 2001\nMade in Old Europe")); + gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (aboutdialog1), _("Linphone is a web-phone.\nIt is compatible with SIP and RTP protocols.")); + gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (aboutdialog1), " This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"); + gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (aboutdialog1), "http://www.linphone.org"); + gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (aboutdialog1), authors); + gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (aboutdialog1), documenters); + gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (aboutdialog1), translators); + aboutdialog1_logo_pixbuf = create_pixbuf ("linphone.png"); + gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (aboutdialog1), aboutdialog1_logo_pixbuf); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (aboutdialog1, aboutdialog1, "aboutdialog1"); + + return aboutdialog1; +} + diff --git a/linphone/gtk/interface.h b/linphone/gtk/interface.h new file mode 100644 index 000000000..4556c2706 --- /dev/null +++ b/linphone/gtk/interface.h @@ -0,0 +1,16 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_app1 (void); +GtkWidget* create_about2 (void); +GtkWidget* create_prop1 (void); +GtkWidget* create_address_book (void); +GtkWidget* create_altressource (void); +GtkWidget* create_proxy_config_box (void); +GtkWidget* create_contact_box (void); +GtkWidget* create_inc_subscr_dialog (void); +GtkWidget* create_authentication_dialog (void); +GtkWidget* create_call_logs (void); +GtkWidget* create_chatroom (void); +GtkWidget* create_aboutdialog1 (void); diff --git a/linphone/gtk/linphone.c b/linphone/gtk/linphone.c new file mode 100644 index 000000000..29c212526 --- /dev/null +++ b/linphone/gtk/linphone.c @@ -0,0 +1,482 @@ +/*************************************************************************** + linphone.c - Main code for linphone's gnome + interface + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "linphone.h" +#include "support.h" +#include "interface.h" +#include "callbacks.h" +#include "gui_utils.h" +#include "lpconfig.h" + +#include + + +LinphoneGnomeUI *uiobj=NULL; +#define get_uiobj() (uiobj) +#define get_core() (uiobj->core) +#define get_friend_list() (&uiobj->main_window.friendlist) + +void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core) +{ + memset(ui,0,sizeof(LinphoneGnomeUI)); + ui->core=core; + uiobj=ui; + ui->main_window.shown_once=FALSE; +} + +static void restore_uri_history(GtkEntry *uribar, LpConfig *cfg){ + char key[20]; + int i; + GtkEntryCompletion *gep=gtk_entry_completion_new(); + GtkListStore *model=gtk_list_store_new(1,G_TYPE_STRING); + for (i=0;;i++){ + const char *uri; + snprintf(key,sizeof(key),"uri%i",i); + uri=lp_config_get_string(cfg,"GtkUi",key,NULL); + if (uri!=NULL) { + GtkTreeIter iter; + gtk_list_store_append(model,&iter); + gtk_list_store_set(model,&iter,0,uri,-1); + if (i==0) gtk_entry_set_text(uribar,uri); + } + else break; + } + gtk_entry_completion_set_model(gep,GTK_TREE_MODEL(model)); + gtk_entry_completion_set_text_column(gep,0); + gtk_entry_set_completion(uribar,gep); +} + +void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui){ + char key[20]; + int i=0; + char *uri=NULL; + GtkTreeIter iter; + GtkEntry *uribar=GTK_ENTRY(ui->main_window.addressentry); + GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(uribar)); + LpConfig *cfg=linphone_core_get_config(ui->core); + if (!gtk_tree_model_get_iter_first(model,&iter)) return; + do { + gtk_tree_model_get(model,&iter,0,&uri,-1); + if (uri) { + snprintf(key,sizeof(key),"uri%i",i); + lp_config_set_string(cfg,"GtkUi",key,uri); + g_free(uri); + }else break; + i++; + if (i>5) break; + }while(gtk_tree_model_iter_next(model,&iter)); +} + +void main_window_create(LinphoneGnomeUI *obj) +{ + GtkWidget *child; + GtkWidget *window; + window=create_app1 (); +#ifdef NOTYET + gnome_window_icon_set_from_default(GTK_WINDOW(window)); +#endif + obj->main_window.status_bar=lookup_widget(window,"appbar1"); + obj->main_window.addressentry=lookup_widget(window,"addressentry"); + obj->main_window.optioncontrols=lookup_widget(window,"optioncontrols"); + obj->main_window.dtmfentry=lookup_widget(window,"dtmf_entry"); + obj->main_window.callbutton=lookup_widget(window,"callbutton"); + child=lookup_widget(window,"showmore"); + /* hide the optionnal controls at startup */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child),0); +#ifndef VIDEO_ENABLED + gtk_widget_hide(lookup_widget(child,"video_enabled")); +#else + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(lookup_widget(child,"video_enabled")), + linphone_core_video_enabled(obj->core)); +#endif + presence_box_init(&obj->main_window.presencebox,window,obj->core); + friend_list_init(&obj->main_window.friendlist,obj->core,window); + g_object_set_data(G_OBJECT(window),"ui",(gpointer)obj); + obj->main_window.window=window; +} + +void linphone_gnome_ui_show(LinphoneGnomeUI *ui) +{ + if (ui->main_window.window==NULL){ + main_window_create(ui); + + } + gtk_widget_show(ui->main_window.window); + ui->main_window.shown_once=TRUE; +} + +void linphone_gnome_ui_hide(LinphoneGnomeUI *ui) +{ + if (ui->main_window.window==NULL) return; + gtk_widget_hide(ui->main_window.window); +} + + +void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui) +{ + ui->main_window.window=NULL; +} + +void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message) +{ + GtkWidget *dialog; + + linphone_gnome_ui_show(ui); + if (type==GTK_MESSAGE_QUESTION) + { +#ifdef VINCENT_MAURY_RSVP + /* draw a question box. link to dialog_click callback */ + dialog = gtk_message_dialog_new ( + GTK_WINDOW(ui->main_window.window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + (const gchar*)message); + /* connect the click event to the callback */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (dialog_click), + G_OBJECT (dialog)); + /* actually show the box */ + gtk_widget_show(dialog); +#endif + } + else + { + dialog = gtk_message_dialog_new (GTK_WINDOW(ui->main_window.window), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + GTK_BUTTONS_CLOSE, + (const gchar*)message); + /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ + g_signal_connect_swapped (G_OBJECT (dialog), "response", + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); + gtk_widget_show(dialog); + } +} + +/* these are the LinphoneCore virtual functions */ +void linphone_gnome_display_message(LinphoneCore *lc, const char *message) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_INFO,message); +} + +#ifdef VINCENT_MAURY_RSVP +/* Question box with yes/no answer. */ +void linphone_gnome_display_yes_no(LinphoneCore *lc,const char *message) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + if (strcmp(message,"With QoS")==0) + /* the caller asks for QoS, this function is called because, by default, + * you don't use QoS ! */ + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION, + _("The caller asks for resource reservation. Do you agree ?")); + else + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_QUESTION, + _("The caller doesn't use resource reservation. \ + Do you wish to continue anyway ?")); +} +#endif + +void linphone_gnome_display_warning(LinphoneCore *lc, const char *warning) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_display_something(ui,GTK_MESSAGE_WARNING,warning); +} + +void linphone_gnome_display_status(LinphoneCore *lc, const char *status) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + if (ui->main_window.window==NULL) return; + if (!ui->main_window.shown_once) return; /* avoid a gnome bug*/ + gtk_statusbar_push(GTK_STATUSBAR(ui->main_window.status_bar), + gtk_statusbar_get_context_id(GTK_STATUSBAR(ui->main_window.status_bar),"") + ,status); +} + +void linphone_gnome_inv_recv(LinphoneCore *lc,const char *from) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + gchar *title; + if (ui->main_window.window==NULL) return; + gtk_entry_set_text(GTK_ENTRY(ui->main_window.addressentry),from); + title=g_strdup_printf(_("linphone - receiving call from %s"),from); + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),title); + gdk_window_set_keep_above (ui->main_window.window->window, 1); + g_free(title); +} + +void linphone_gnome_show(LinphoneCore *lc) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + linphone_gnome_ui_show(ui); +} + +void linphone_gnome_display_url(LinphoneCore *lc, const char *message, const char *url) +{ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + alt_ressource_display(ui,url); +} + + + +void linphone_gnome_notify_received(LinphoneCore *lc,LinphoneFriend *fid, const char *from, const char *status, const char *img){ + FriendList *fl=get_friend_list(); + friend_list_set_friend_status(fl,fid,from,status, img); +} + +void linphone_gnome_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ + GtkWidget *d=create_inc_subscr_dialog(); + gchar *text=g_strdup_printf(_("You have received a subscription from %s." + "This means that this person wishes to be notified of your presence information (online, busy, away...).\n" + "Do you agree ?"),url); + gtk_label_set_text(GTK_LABEL(lookup_widget(d,"subscr_label")),text); + g_object_set_data(G_OBJECT(d),"friend_ref",(gpointer)lf); + gtk_widget_show(d); +} + +static gboolean destroy_auth(GtkWidget *w){ + gtk_widget_destroy(w); + return FALSE; +} + +void linphone_gnome_prompt_authentication(LinphoneCore *lc, const gchar *realm, const gchar *username){ + GtkWidget *w=create_authentication_dialog(); + gchar *question=g_strdup_printf(_("Authentication required for realm %s"),realm); + gtk_label_set_text(GTK_LABEL(lookup_widget(w,"question")),question); + g_free(question); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"realm")),realm); + gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"username")),username); + gtk_widget_show(w); + //automatically destroys the window after 30 seconds to avoid multiple windows to be popped up after some hours. + g_timeout_add(30000,(GtkFunction)destroy_auth,w); +} + +void linphone_gnome_bye_recv(LinphoneCore *lc, const char *from){ + LinphoneGnomeUI *ui=(LinphoneGnomeUI*)lc->data; + gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone"); +} + +void stub(){ +} + +void linphone_gnome_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){ + LinphoneGnomeUI *ui=(LinphoneGnomeUI *)linphone_core_get_user_data(lc); + linphone_gnome_update_call_logs(ui); +} + +void linphone_gnome_text_received(LinphoneCore *lc,LinphoneChatRoom *cr, const char *from, const char *msg){ + GtkWidget *gcr=(GtkWidget*)linphone_chat_room_get_user_data(cr); + if (gcr==NULL){ + gcr=chatroom_new(from,cr); + } + gtk_widget_show(gcr); + chatroom_append(gcr,from,msg); +} + +LinphoneCoreVTable linphone_gnome_vtable= +{ + show: linphone_gnome_show, + inv_recv: linphone_gnome_inv_recv, + bye_recv : linphone_gnome_bye_recv, + notify_recv: linphone_gnome_notify_received, + new_unknown_subscriber: linphone_gnome_new_unknown_subscriber, + auth_info_requested: linphone_gnome_prompt_authentication, + display_status : linphone_gnome_display_status, + display_message : linphone_gnome_display_message, + display_warning : linphone_gnome_display_warning, +#ifdef VINCENT_MAURY_RSVP + display_yes_no : linphone_gnome_display_yes_no, +#endif + display_url : linphone_gnome_display_url, + display_question : stub, + call_log_updated : linphone_gnome_call_log_updated, + text_received: linphone_gnome_text_received +}; + +gboolean linphone_gnome_iterate(LinphoneCore *lc) +{ + linphone_core_iterate(lc); + return TRUE; +} + +void proxy_changed(GtkWidget *combo){ + LinphoneProxyConfig *pcfg=proxy_combo_box_get_selected(combo); + linphone_core_set_default_proxy(get_core(),pcfg); +} + +void linphone_refresh_proxy_combo_box(GtkWidget *window){ + LinphoneCore *lc=get_core(); + GtkWidget *combo; + const MSList *elem=linphone_core_get_proxy_config_list(lc); + LinphoneProxyConfig *cfg=NULL; + GtkWidget *hbox=lookup_widget(window,"proxy_hbox"); + + linphone_core_get_default_proxy(lc,&cfg); + + if (elem==NULL){ + gtk_widget_hide(hbox); + return; + } + combo=(GtkWidget*)g_object_get_data(G_OBJECT(hbox),"proxy"); + if (combo!=NULL){ + gtk_widget_destroy(combo); + } + combo=proxy_combo_box_new(cfg); + g_object_set_data(G_OBJECT(hbox),"proxy",(gpointer)combo); + g_signal_connect(G_OBJECT(combo),"changed",G_CALLBACK(proxy_changed),NULL); + gtk_box_pack_start_defaults(GTK_BOX(hbox),combo); + gtk_widget_show(combo); + gtk_widget_show(hbox); + +} + +void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc) +{ + gchar *configfile_name = + g_strdup_printf ("%s/.gnome2/linphone", getenv ("HOME")); + linphone_gnome_ui_init(ui,lc); + linphone_gnome_ui_show(ui); + linphone_core_init(lc,&linphone_gnome_vtable,configfile_name,(gpointer)ui); + g_free(configfile_name); + set_levels(ui,linphone_core_get_rec_level(lc),linphone_core_get_play_level(lc),linphone_core_get_ring_level(lc)); + /* get history of uri bar */ + restore_uri_history(GTK_ENTRY(ui->main_window.addressentry), linphone_core_get_config(lc)); + linphone_refresh_proxy_combo_box(ui->main_window.window); + ui->timeout_id=gtk_timeout_add(20,(GtkFunction)linphone_gnome_iterate,(gpointer)lc); +} + +void linphone_gnome_uninit(LinphoneGnomeUI *ui) +{ + LinphoneCore *lc=ui->core; + linphone_gnome_ui_uninit(ui); + linphone_core_uninit(lc); + gtk_timeout_remove (ui->timeout_id); +} + +GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected){ + GtkWidget *combo; + const MSList *elem; + GtkListStore *store=gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_POINTER); + GtkTreeIter iter; + GtkTreeIter prxiter; + GtkCellRenderer *renderer; + gboolean proxy_found=FALSE; + /* fill the store */ + elem=linphone_core_get_proxy_config_list(get_core()); + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,0,_("None"),1,(gpointer)NULL,-1); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)elem->data; + gtk_list_store_append(store,&iter); + gtk_list_store_set(store,&iter,0,proxy->reg_proxy,1,(gpointer)proxy,-1); + if (selected==proxy) { + prxiter=iter; + proxy_found=TRUE; + } + } + combo=gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, + "text", 0, + NULL); + if (proxy_found){ + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),&prxiter); + }else{ + /*else select "None" */ + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0); + } + return combo; +} + +LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo){ + LinphoneProxyConfig *pcfg=NULL; + GtkTreeIter iter; + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo),&iter)){ + GtkTreeModel *model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_tree_model_get(model,&iter,1,(gpointer)&pcfg,-1); + } + return pcfg; +} + +void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui){ + LinphoneCore *lc=ui->core; + GtkTextView *tv; + GtkTextBuffer *tb; + GtkTextIter begin,end; + GtkTextTag *tag; + MSList *elem; + if (ui->logs==NULL) return; + tv=GTK_TEXT_VIEW(lookup_widget(ui->logs,"logview")); + tb=gtk_text_view_get_buffer(tv); + + gtk_text_buffer_get_bounds(tb,&begin,&end); + gtk_text_buffer_delete(tb,&begin,&end); + gtk_text_buffer_get_end_iter(tb,&end); + for (elem=linphone_core_get_call_logs(lc);elem!=NULL;elem=ms_list_next(elem)){ + LinphoneCallLog *cl=(LinphoneCallLog*)elem->data; + gchar *str=linphone_call_log_to_str(cl); + tag=NULL; + if (cl->status==LinphoneCallMissed){ + tag=gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(tb),"redforeground"); + if (tag==NULL) tag = gtk_text_buffer_create_tag (tb, "redforeground", + "foreground", "red", NULL); + } + gtk_text_buffer_insert_with_tags(tb,&end,str,-1,tag,NULL); + gtk_text_buffer_insert(tb,&end,"\n",-1); + + ms_free(str); + } +} + +void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui){ + if (ui->logs==NULL) { + ui->logs=create_call_logs(); + } + linphone_gnome_update_call_logs(ui); + gtk_widget_show(ui->logs); +} diff --git a/linphone/gtk/linphone.h b/linphone/gtk/linphone.h new file mode 100644 index 000000000..983815529 --- /dev/null +++ b/linphone/gtk/linphone.h @@ -0,0 +1,68 @@ + + +#ifndef LINPHONE_H +#define LINPHONE_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#define _(String) gettext (String) + +#include +#include "lpconfig.h" + +#include "support.h" +#include "propertybox.h" +#include "presence.h" +#include "addressbook.h" +#include "friends.h" + +typedef struct _LinphoneMainWindow +{ + GtkWidget *window; + GtkWidget *status_bar; + GtkWidget *addressentry; + GtkWidget *optioncontrols; + GtkWidget *dtmfentry; + GtkWidget *callbutton; + PresenceBox presencebox; + FriendList friendlist; + gboolean shown_once; +}LinphoneMainWindow; + +typedef struct _LinphoneGnomeUI +{ + LinphoneMainWindow main_window; + LinphonePropertyBox propbox; + GtkWidget *ab; /*the address book */ + GtkWidget *logs; /* the call logs window */ + LinphoneCore *core; + guint timeout_id; +}LinphoneGnomeUI; + + +void linphone_gnome_ui_init(LinphoneGnomeUI *ui,LinphoneCore *core); +void linphone_gnome_ui_show(LinphoneGnomeUI *ui); +void linphone_gnome_ui_hide(LinphoneGnomeUI *ui); +void linphone_gnome_ui_uninit(LinphoneGnomeUI *ui); + +void linphone_gnome_init(LinphoneGnomeUI *ui,LinphoneCore *lc); +void linphone_gnome_uninit(LinphoneGnomeUI *ui); + +extern LinphoneGnomeUI *uiobj; + +GtkWidget *proxy_combo_box_new(LinphoneProxyConfig *selected); +void linphone_refresh_proxy_combo_box(GtkWidget *window); +LinphoneProxyConfig *proxy_combo_box_get_selected(GtkWidget *combo); +void linphone_gnome_show_call_logs_window(LinphoneGnomeUI *ui); +void linphone_gnome_update_call_logs(LinphoneGnomeUI *ui); +void linphone_gnome_ui_display_something(LinphoneGnomeUI *ui,GtkMessageType type,const gchar *message); +void linphone_gnome_save_uri_history(LinphoneGnomeUI *ui); + +GtkWidget *chatroom_new(const gchar *url, LinphoneChatRoom *cr); +void chatroom_append(GtkWidget *gcr, const gchar *from, const gchar *message); +void chatroom_close(GtkWidget *gcr); + +#endif diff --git a/linphone/gtk/main.c b/linphone/gtk/main.c new file mode 100644 index 000000000..646d5540f --- /dev/null +++ b/linphone/gtk/main.c @@ -0,0 +1,74 @@ +/* + * Initial main.c file generated by Glade. Edit as required. + * Glade will not overwrite this file. + */ + + +#include "linphone.h" + +/* +#include "../osipua/src/dbgalloc.h" + +GMemVTable dbgtable={ + smalloc, + srealloc, + sfree, + scalloc, + smalloc, + srealloc +}; +*/ +LinphoneCore core; +LinphoneGnomeUI ui; +static gboolean verbose=0; +GOptionEntry linphone_options[2]={ + { + .long_name="verbose", + .short_name= '\0', + .arg=G_OPTION_ARG_NONE, + .arg_data= (gpointer)&verbose, + .description="log to stdout some debug information while running." + } +}; + +int +main (int argc, char *argv[]) +{ + void *p; + + g_thread_init(NULL); + //g_log_set_fatal_mask("GLib",G_LOG_LEVEL_WARNING); + //g_mem_set_vtable(glib_mem_profiler_table); + //g_mem_set_vtable(&dbgtable); +#ifdef ENABLE_NLS + p=bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + if (p==NULL) perror("bindtextdomain failed"); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); +#else + printf("NLS disabled.\n"); +#endif + +#ifdef NOWOBSOLETE_NOTYET + gnome_program_init ("linphone", LINPHONE_VERSION, LIBGNOMEUI_MODULE, + argc, argv, + GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR, + GNOME_PARAM_POPT_TABLE,&linphone_options,NULL); +#endif + if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"), + linphone_options,NULL,NULL)) + return -1; + add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone"); + add_pixmap_directory("pixmaps"); + + if (verbose) linphone_core_enable_logs(stdout); + else linphone_core_disable_logs(); + linphone_gnome_init(&ui,&core); + linphone_gnome_ui_show(&ui); + gtk_main (); + gdk_threads_leave(); /* it appears that the gdk lock is hold while exiting from gtk_main() */ + linphone_gnome_uninit(&ui); + //g_mem_profile(); + exit(0); + return 0; +} diff --git a/linphone/gtk/presence.c b/linphone/gtk/presence.c new file mode 100644 index 000000000..18042b2c8 --- /dev/null +++ b/linphone/gtk/presence.c @@ -0,0 +1,150 @@ +/*************************************************************************** + presence.c - code for the presence box + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "linphone.h" +#include "callbacks.h" +#include "support.h" + + +void presence_box_init(PresenceBox *p, GtkWidget *main_window,LinphoneCore *lc) +{ + GtkWidget *r; + p->lc=lc; + p->contact_field=lookup_widget(main_window,"contact_field"); + p->minutesaway=lookup_widget(main_window,"minutesaway"); + r=lookup_widget(main_window,"presence_reachable"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(r),TRUE); + r=lookup_widget(main_window,"presence_frame"); +} + +void presence_box_changed(PresenceBox *p) +{ + presence_box_apply(p); +} + +#define get_presence_box() (&(uiobj)->main_window.presencebox) + + +void +on_reachable (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + p->toggled_button=PRESENCE_MODE_REACHABLE; + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + //gtk_widget_set_sensitive(p->contact_field,FALSE); + presence_box_changed(p); +} + + +void +on_busy (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + p->toggled_button=PRESENCE_MODE_BUSY; + //gtk_widget_set_sensitive(p->minutesaway,TRUE); + presence_box_changed(p); +} + + +void +on_minutesaway_changed (GtkEditable *editable,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + presence_box_changed(p); +} + + +void +on_away (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + //gtk_widget_set_sensitive(p->minutesaway,TRUE); + p->toggled_button=PRESENCE_MODE_AWAY; + presence_box_changed(p); +} + + +void +on_do_not_disturb (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,FALSE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_NOT_DISTURB; + presence_box_changed(p); +} + + +void +on_moved_tmply (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,TRUE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_MOVED; + presence_box_changed(p); +} + + +void +on_alt_serv (GtkToggleButton *togglebutton,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + if (!gtk_toggle_button_get_active(togglebutton)) return; + //gtk_widget_set_sensitive(p->contact_field,TRUE); + //gtk_widget_set_sensitive(p->minutesaway,FALSE); + p->toggled_button=PRESENCE_MODE_ALT_SERVICE; + presence_box_changed(p); +} + + +void +on_contact_field_changed (GtkEditable *entry,gpointer user_data) +{ + PresenceBox *p=get_presence_box(); + presence_box_changed(p); +} + +void presence_box_apply(PresenceBox *p) +{ + gchar *tmp,*contact=NULL; + int minutes_away=-1; + g_message("presence_box_apply"); + /* retrieve the minutes away */ + tmp = gtk_editable_get_chars (GTK_EDITABLE(p->minutesaway),0,-1); + if (tmp!=NULL && strlen(tmp)>0) + { + minutes_away = atoi(tmp); + g_free(tmp); + } + /* retrieve the alternate contact url */ + tmp = gtk_editable_get_chars (GTK_EDITABLE(p->contact_field),0,-1); + if (tmp!=NULL && strlen(tmp)>0) + { + contact=tmp; + } + /* set presence mode */ + linphone_core_set_presence_info(p->lc,minutes_away,contact,p->toggled_button); + if (tmp!=NULL) g_free(tmp); +} diff --git a/linphone/gtk/presence.h b/linphone/gtk/presence.h new file mode 100644 index 000000000..cbe8701c7 --- /dev/null +++ b/linphone/gtk/presence.h @@ -0,0 +1,43 @@ +/*************************************************************************** + presence.h - code for the presence box + ------------------- + begin : Mon Dec 17 2001 + copyright : (C) 2001 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PRESENCE_H +#define PRESENCE_H + +enum { PRESENCE_MODE_REACHABLE=LINPHONE_STATUS_ONLINE, + PRESENCE_MODE_BUSY=LINPHONE_STATUS_BUSY, + PRESENCE_MODE_AWAY=LINPHONE_STATUS_AWAY, + PRESENCE_MODE_NOT_DISTURB=LINPHONE_STATUS_NOT_DISTURB, + PRESENCE_MODE_MOVED=LINPHONE_STATUS_MOVED, + PRESENCE_MODE_ALT_SERVICE=LINPHONE_STATUS_ALT_SERVICE + }; + + +typedef struct _PresenceBox +{ + LinphoneCore *lc; + GtkWidget *minutesaway; + GtkWidget *contact_field; + gint toggled_button; /* indicate which button is toggled*/ +} PresenceBox; + + +void presence_box_init(PresenceBox *p, GtkWidget *main_window,LinphoneCore *lc); +void presence_box_changed(PresenceBox *p); +void presence_box_apply(PresenceBox *p); + +#endif diff --git a/linphone/gtk/propertybox.c b/linphone/gtk/propertybox.c new file mode 100644 index 000000000..3a4b472ed --- /dev/null +++ b/linphone/gtk/propertybox.c @@ -0,0 +1,1107 @@ +/*************************************************************************** + propertybox.c - description + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "linphone.h" + +enum{ +#ifdef INET6 + IFACE_INDEX, +#endif + IFACE_NAME, + IFACE_ADDR, + IFACE_NCOLUMNS +}; + +enum { + CODEC_NAME, + CODEC_RATE, + CODEC_BITRATE, + CODEC_STATUS, + CODEC_PRIVDATA, + CODEC_COLOR, + CODEC_NCOLUMNS +}; + +#define get_core() (uiobj->core) +#define get_property_box() (&uiobj->propbox) +#ifdef NOTYET +#define property_box_changed() gnome_property_box_changed(GNOME_PROPERTY_BOX ( (&uiobj->propbox)->prop)) +#else +#define property_box_changed() +#endif +#define get_main_window() (&uiobj->main_window) + +#if !GTK_CHECK_VERSION(2,6,0) +static gchar * _lp_combo_box_get_active_text (GtkComboBox *combobox) +{ + GtkTreeIter iter; + GtkTreeModel *model; + gchar *text = NULL; + model = gtk_combo_box_get_model (combobox); + if (gtk_combo_box_get_active_iter (combobox, &iter) && model) + gtk_tree_model_get (model, &iter, 0, &text, -1); + return text; +} +#endif /* GTK+ < 2.6.0 */ + +void net_section_init(NetSection *sec, GtkWidget *prop) +{ + sec->au_port=lookup_widget(prop,"audioport"); + sec->audio_jittcomp=lookup_widget(prop,"audio_jittcomp"); +#ifdef LINPHONE_DEPRECATED + sec->interfaces=lookup_widget(prop, "interfaces"); +#endif + sec->nat_address=lookup_widget(prop,"nat_address"); + sec->use_sipinfo=lookup_widget(prop,"use_sipinfo"); + sec->enable_ipv6=lookup_widget(prop,"enable_ipv6"); +} + +void codec_list_update(GtkTreeView *listview); + + +void net_selection_changed_cb(GtkTreeSelection *select, gpointer userdata) +{ + property_box_changed(); +} + +void net_section_fill(NetSection *sec,LinphoneCore *lc) +{ + gfloat value; + const gchar *nat_address,*stun_server; + + value=(gfloat)linphone_core_get_audio_jittcomp(lc); + /* put the current value of jitt_comp*/ + gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(sec->audio_jittcomp)),value); + /* display current rtp port */ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(sec->au_port), + (gfloat)linphone_core_get_audio_port(lc)); + + + /* nat setup */ + nat_address=linphone_core_get_nat_address(lc); + + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_NAT_ADDRESS) + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"static_nat")) + ,TRUE); + + if (nat_address!=NULL) { + gtk_entry_set_text(GTK_ENTRY(sec->nat_address),nat_address); + } + stun_server=linphone_core_get_stun_server(lc); + if (stun_server!=NULL) + gtk_entry_set_text( + GTK_ENTRY(lookup_widget(get_property_box()->prop,"stun_server")), + stun_server); + if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_STUN) + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"use_stun")),TRUE); + + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->use_sipinfo), + linphone_core_get_use_info_for_dtmf(lc)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->enable_ipv6), + linphone_core_ipv6_enabled(lc)); +} + +void +on_enable_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); + +} + + + +void +on_nat_address_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_enable_ipv6_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void net_section_apply(NetSection *sec,LinphoneCore *lc) +{ + gboolean use_nat,use_stun; + gchar *name; + + use_nat=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + lookup_widget(get_property_box()->prop,"static_nat"))); + name=gtk_editable_get_chars(GTK_EDITABLE(sec->nat_address),0,-1); + linphone_core_set_nat_address(lc,name); + g_free(name); + + use_stun=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + lookup_widget(get_property_box()->prop,"use_stun") )); + name=gtk_editable_get_chars(GTK_EDITABLE( + lookup_widget(get_property_box()->prop,"stun_server") ),0,-1); + linphone_core_set_stun_server(lc,name); + g_free(name); + if (use_stun) linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_USE_STUN); + else if (use_nat) linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_USE_NAT_ADDRESS); + else linphone_core_set_firewall_policy(lc, + LINPHONE_POLICY_NO_FIREWALL); + + { + /* get the value of jitt_comp*/ + GtkAdjustment *adj= gtk_range_get_adjustment(GTK_RANGE(sec->audio_jittcomp)); + linphone_core_set_audio_jittcomp(lc,(gint)adj->value); + /* get rtp port */ + adj=gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(sec->au_port)); + linphone_core_set_audio_port(lc,(gint)adj->value); + } + linphone_core_enable_ipv6(lc,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sec->enable_ipv6))); +} + + +enum{ + PROXY_CONFIG_IDENTITY, + PROXY_CONFIG_REF, + PROXY_CONFIG_NCOL +}; + +void sip_section_init(SipSection *sec,GtkWidget *prop) +{ + + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select; + sec->port=lookup_widget(prop,"sip_port"); + sec->username=lookup_widget(prop, "user_name"); + sec->hostname=lookup_widget(prop,"domain_name"); + sec->proxy_list=lookup_widget(prop,"proxy_list"); + sec->guess_hostname=lookup_widget(prop,"guess_hostname"); + /* create the proxy list */ + store = gtk_list_store_new (PROXY_CONFIG_NCOL, G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model(GTK_TREE_VIEW(sec->proxy_list),GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Account"), + renderer, + "text", PROXY_CONFIG_IDENTITY, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sec->proxy_list), column); + + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (sec->proxy_list)); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); +} + + +void proxy_list_fill(GtkTreeModel *model, LinphoneCore *lc){ + const MSList *elem; + GtkTreeIter iter; + /* fill the proxy list */ + gtk_list_store_clear(GTK_LIST_STORE(model)); + elem=linphone_core_get_proxy_config_list(lc); + for(;elem!=NULL;elem=ms_list_next(elem)){ + LinphoneProxyConfig *pcfg=(LinphoneProxyConfig*)elem->data; + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,PROXY_CONFIG_IDENTITY,pcfg->reg_identity, + PROXY_CONFIG_REF,pcfg,-1); + } +} + +void sip_section_fill(SipSection *sec, LinphoneCore *lc) +{ + osip_from_t *contact; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->proxy_list)); + + /* set sip port */ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(sec->port), + (gfloat)linphone_core_get_sip_port(lc)); + contact=linphone_core_get_primary_contact_parsed(lc); + g_return_if_fail(contact!=NULL); + /* set sip username */ + gtk_entry_set_text(GTK_ENTRY(sec->username),contact->url->username); + /* set domain name */ + gtk_entry_set_text(GTK_ENTRY(sec->hostname),contact->url->host); + osip_from_free(contact); + proxy_list_fill(model,lc); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sec->guess_hostname), + linphone_core_get_guess_hostname(lc)); +} + +void sip_section_apply(SipSection *sec, LinphoneCore *lc) +{ + GtkAdjustment *adj; + gchar *tmp; + gchar *username,*hostname; + /* get sip port*/ + adj=gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(sec->port)); + + username=gtk_editable_get_chars(GTK_EDITABLE(sec->username),0,-1); + if (username!=NULL && strlen(username)!=0) + { + hostname=gtk_editable_get_chars(GTK_EDITABLE(sec->hostname),0,-1); + if (hostname!=NULL && strlen(hostname)!=0) + { + tmp=g_strdup_printf("sip:%s@%s",username,hostname); + linphone_core_set_primary_contact(lc,tmp); + linphone_core_set_sip_port(lc,(int)gtk_adjustment_get_value(adj)); + g_free(hostname); + g_free(tmp); + } + g_free(username); + } +} + + +void +on_addproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *w=create_proxy_config_box(); + gtk_widget_show(w); +} + + +void +on_editproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *w; + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneProxyConfig * cfg; + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_property_box()->sip.proxy_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,PROXY_CONFIG_REF , &cfg, -1); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + linphone_proxy_config_edit(cfg); + }else return; + w=create_proxy_config_box(); + gtk_widget_show(w); + if (cfg->reg_proxy!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_proxy")),cfg->reg_proxy); + if (cfg->reg_route!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_route")),cfg->reg_route); + if (cfg->reg_identity!=NULL) gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"reg_identity")),cfg->reg_identity); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"reg_sendregister")),cfg->reg_sendregister); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"publish")),cfg->publish); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(w,"reg_expires")),cfg->expires); + g_object_set_data(G_OBJECT(w),"edited_config",(gpointer)cfg); +} + + +void +on_removeproxy_button_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + LinphoneProxyConfig * cfg; + select = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_property_box()->sip.proxy_list)); + if (gtk_tree_selection_get_selected (select, &model, &iter)) + { + gtk_tree_model_get (model, &iter,PROXY_CONFIG_REF , &cfg, -1); + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + linphone_core_remove_proxy_config(get_core(),cfg); + linphone_refresh_proxy_combo_box(get_main_window()->window); + } +} + +void get_proxy_config_box_data(GtkWidget *dialog) +{ + gchar *tmp; + gboolean editing=FALSE; + LinphoneProxyConfig *cfg; + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_proxy")),0,-1); + cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(dialog),"edited_config"); + if (cfg==NULL){ + cfg=linphone_proxy_config_new(); + linphone_proxy_config_set_server_addr(cfg,tmp); + g_free(tmp); + if (cfg==NULL) { + /* set an error message here */ + return; + } + }else{ + linphone_proxy_config_set_server_addr(cfg,tmp); + g_free(tmp); + editing=TRUE; + } + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_route")),0,-1); + linphone_proxy_config_set_route(cfg,tmp); + g_free(tmp); + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_identity")),0,-1); + linphone_proxy_config_set_identity(cfg,tmp); + g_free(tmp); + tmp=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"reg_expires")),0,-1); + { + int exp; + if (tmp!=NULL) + { + exp = atoi(tmp); + if (exp<=0) + exp = 200; /* minimum */ + if (exp>7200) + exp = 7200; /* maximum */ + linphone_proxy_config_expires(cfg,exp); + } + } + g_free(tmp); + linphone_proxy_config_enableregister(cfg,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"reg_sendregister")))); + linphone_proxy_config_enable_publish(cfg,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"publish")))); + if (editing) linphone_proxy_config_done(cfg); + else linphone_core_add_proxy_config(get_core(),cfg); + /* set the last entered/changed proxy as the default one */ + linphone_core_set_default_proxy(get_core(),cfg); + proxy_list_fill(gtk_tree_view_get_model(GTK_TREE_VIEW(get_property_box()->sip.proxy_list)),get_core()); + linphone_refresh_proxy_combo_box(get_main_window()->window); +} + +void +on_proxy_config_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + switch(response_id){ + case GTK_RESPONSE_OK: + get_proxy_config_box_data(GTK_WIDGET(dialog)); + gtk_widget_destroy(GTK_WIDGET(dialog)); + + break; + } +} + + +void codec_section_init(CodecSection *sec, GtkWidget *prop) +{ + sec->au_codec_list=lookup_widget(prop,"au_codec_list"); + sec->vi_codec_list=lookup_widget(prop,"vid_codec_list"); + sec->codec_info=lookup_widget(prop,"codec_info"); +} + +void codec_selection_changed_cb(GtkTreeSelection *selection, gpointer data) +{ + GtkTreeIter iter; + GtkTreeModel *model; + struct _PayloadType *pt=NULL; + LinphonePropertyBox *prop=get_property_box(); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, CODEC_PRIVDATA, &pt, -1); + g_return_if_fail(pt!=NULL); + /* display the codec information */ + gtk_label_set_text(GTK_LABEL(prop->codec.codec_info),payload_type_get_description(pt)); + } +} + +void codec_list_build(GtkTreeView *listview,const MSList *codeclist) +{ + const MSList *elem; + GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_FLOAT, + G_TYPE_STRING, + G_TYPE_POINTER, + G_TYPE_STRING); + GtkTreeIter iter; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *select=gtk_tree_view_get_selection (listview); + for(elem=codeclist; elem!=NULL; elem=elem->next){ + gchar *status; + gint rate; + gfloat bitrate; + gchar *color; + struct _PayloadType *pt=(struct _PayloadType *)elem->data; + if (payload_type_enabled(pt)) status=_("Enabled"); + else status=_("Disabled"); + if (linphone_core_check_payload_type_usability(get_core(),pt)) color="blue"; + else color="red"; + /* get an iterator */ + gtk_list_store_append(store,&iter); + bitrate=payload_type_get_bitrate(pt)/1000.0; + rate=payload_type_get_rate(pt); + gtk_list_store_set(store,&iter, CODEC_NAME,payload_type_get_mime(pt), + CODEC_RATE,rate, + CODEC_BITRATE,bitrate, + CODEC_STATUS,status, + CODEC_PRIVDATA,(gpointer)pt, + CODEC_COLOR,(gpointer)color, + -1); + } + gtk_tree_view_set_model(listview,GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Name"), + renderer, + "text", CODEC_NAME, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Rate (Hz)"), + renderer, + "text", CODEC_RATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Status"), + renderer, + "text", CODEC_STATUS, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + column = gtk_tree_view_column_new_with_attributes (_("Min bitrate (kbit/s)"), + renderer, + "text", CODEC_BITRATE, + "foreground",CODEC_COLOR, + NULL); + gtk_tree_view_append_column (listview, column); + + /* Setup the selection handler */ + select = gtk_tree_view_get_selection (listview); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces)); + g_signal_connect (G_OBJECT (select), "changed", + G_CALLBACK (codec_selection_changed_cb), + NULL); +} + +void codec_section_fill(CodecSection *sec, LinphoneCore *lc, GtkWidget *propbox) +{ + /* display prefered codecs*/ + int value; + const MSList *audio_codecs=linphone_core_get_audio_codecs(lc); + const MSList *video_codecs=linphone_core_get_video_codecs(lc); + codec_list_build(GTK_TREE_VIEW(sec->au_codec_list),audio_codecs); + codec_list_build(GTK_TREE_VIEW(lookup_widget(propbox,"vid_codec_list")),video_codecs); + value=linphone_core_get_download_bandwidth(lc); + if (value!=0) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(propbox,"download_bw")),value); + else + gtk_entry_set_text(GTK_ENTRY(lookup_widget(propbox,"download_bw")),_("Unlimited")); + value=linphone_core_get_upload_bandwidth(lc); + if (value!=0) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(propbox,"upload_bw")),value); + else + gtk_entry_set_text(GTK_ENTRY(lookup_widget(propbox,"upload_bw")),_("Unlimited")); +} + +void codec_section_apply(CodecSection *sec, LinphoneCore *lc) +{ + GtkTreeIter iter; + struct _PayloadType *pt; + MSList *codeclist=NULL; + gchar *status; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->au_codec_list)); + /* retrieve the codec list */ + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_STATUS,&status,CODEC_PRIVDATA, &pt,-1); + g_return_if_fail(pt!=NULL); + if (strcmp(status,_("Enabled"))==0) payload_type_set_enable(pt,1); + else payload_type_set_enable(pt,0); + codeclist=ms_list_append(codeclist,pt); + }while (gtk_tree_model_iter_next(model,&iter)); + linphone_core_set_audio_codecs(lc,codeclist); + model=gtk_tree_view_get_model(GTK_TREE_VIEW(sec->vi_codec_list)); + /* retrieve the codec list */ + codeclist=NULL; + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_STATUS,&status,CODEC_PRIVDATA, &pt,-1); + g_return_if_fail(pt!=NULL); + if (strcmp(status,_("Enabled"))==0) payload_type_set_enable(pt,1); + else payload_type_set_enable(pt,0); + codeclist=ms_list_append(codeclist,pt); + }while (gtk_tree_model_iter_next(model,&iter)); + linphone_core_set_video_codecs(lc,codeclist); +} + +void sound_section_init(SoundSection *sec, GtkWidget *prop) +{ + sec->source_entry=lookup_widget(prop,"rec_source"); + sec->ringfileentry=lookup_widget(prop,"ringfileentry"); +} + + +void +on_play_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char *dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char *dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + linphone_core_set_playback_device(get_core(),dev); + property_box_changed(); + g_free(dev); +} + + +void +on_capt_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char * dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char * dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + linphone_core_set_capture_device(get_core(),dev); + property_box_changed(); + g_free(dev); +} + +void +on_ring_card_changed (GtkComboBox *combobox, + gpointer user_data) +{ +#if GTK_CHECK_VERSION(2,6,0) + char * dev=gtk_combo_box_get_active_text(combobox); +#else /* GTK < 2.6.0 */ + char * dev=_lp_combo_box_get_active_text(combobox); +#endif /* GTK < 2.6.0 */ + if(dev != NULL) + { + linphone_core_set_ringer_device(get_core(),dev); + property_box_changed(); + g_free(dev); + } +} + +static int get_dev_index(const char **devnames, const char *dev){ + int i; + for (i=0;devnames[i]!=NULL;i++){ + if (strcmp(devnames[i],dev)==0) + return i; + } + g_warning("could not find %s in device list.",dev); + return 0; +} + +void sound_section_fill(SoundSection *sec, LinphoneCore *lc) +{ + GtkComboBox *play_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"play_card")); + GtkComboBox *capt_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"capt_card")); + GtkComboBox *ring_card=GTK_COMBO_BOX(lookup_widget(get_property_box()->prop,"ring_card")); + int i; + const char **devnames=linphone_core_get_sound_devices(lc); + /* select used sound drivers*/ + + for (i=0;devnames[i]!=NULL;i++){ + const char *carddesc=devnames[i]; + gtk_combo_box_append_text(play_card,carddesc); + gtk_combo_box_append_text(capt_card,carddesc); + gtk_combo_box_append_text(ring_card,carddesc); + } + /*select used cards */ + gtk_combo_box_set_active(play_card,get_dev_index(devnames,linphone_core_get_playback_device(lc))); + gtk_combo_box_set_active(capt_card,get_dev_index(devnames,linphone_core_get_capture_device(lc))); + gtk_combo_box_set_active(ring_card,get_dev_index(devnames,linphone_core_get_ringer_device(lc))); + /* select audio source*/ + switch(linphone_core_get_sound_source(lc)) + { + case 'm': + gtk_entry_set_text (GTK_ENTRY (sec->source_entry), _("micro")); + break; + case 'l': + gtk_entry_set_text (GTK_ENTRY (sec->source_entry), _("line")); + break; + default: + g_warning("Invalid source !"); + } + { + const gchar *ringfile=linphone_core_get_ring(lc); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(sec->ringfileentry),ringfile); + + } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(get_property_box()->prop,"echocancelation")),linphone_core_echo_cancelation_enabled(lc)); +} + + + + +void sound_section_apply(SoundSection *sec, LinphoneCore *lc) +{ + gchar *tmp; + + /* get audio source*/ + tmp=gtk_editable_get_chars(GTK_EDITABLE(sec->source_entry),0,-1); + if (strcmp(tmp,_("micro"))==0) linphone_core_set_sound_source(lc,'m'); + else if (strcmp(tmp,_("line"))==0) linphone_core_set_sound_source(lc,'l'); + g_free(tmp); + + /* get ring path */ + tmp=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(sec->ringfileentry)); + if(tmp != NULL) + { + linphone_core_set_ring(lc,tmp); + g_free(tmp); + } +} + +void ring_finished(LinphoneCore *lc,gpointer user_data) +{ + GtkWidget *button=(GtkWidget*)user_data; + LinphonePropertyBox *prop=get_property_box(); + if (prop->prop==NULL) return; /* the box has been closed before the end of the preview */ + gtk_widget_set_sensitive(button,1); +} + +void +on_ringpreview_clicked (GtkButton *button, + gpointer user_data) +{ + int err; + gchar *tmp; + LinphonePropertyBox *prop=get_property_box(); + LinphoneCore *lc=get_core(); + /* get ring path */ + tmp=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(prop->sound.ringfileentry)); + err=linphone_core_preview_ring(lc,tmp,ring_finished,(gpointer)button); + if (err==0) gtk_widget_set_sensitive(GTK_WIDGET(button),0); + g_free(tmp); +} + + +void linphone_property_box_fill(LinphonePropertyBox * box, LinphoneCore *lp) +{ + net_section_fill(&box->net,lp); + sip_section_fill(&box->sip,lp); + codec_section_fill(&box->codec,lp,box->prop); + sound_section_fill(&box->sound,lp); + /* set uchanged state to the prop1 box, because gtk_entry_set_text() causes signal "changed" + to be sent */ +#ifdef NOTYET + gnome_property_box_set_state(GNOME_PROPERTY_BOX(box->prop),0); +#else + fprintf(stderr, "not yet implemented\n"); +#endif +} + +void linphone_property_box_init(LinphonePropertyBox *box) +{ + GtkWidget *prop=create_prop1(); + box->prop=prop; + net_section_init(&box->net,prop); + sip_section_init(&box->sip,prop); + codec_section_init(&box->codec,prop); + sound_section_init(&box->sound,prop); + gtk_widget_show(prop); + linphone_property_box_fill(box,get_core()); +} + + + + +void linphone_property_box_apply (gint pagenum) +{ + LinphonePropertyBox *prop=get_property_box(); + LinphoneCore *lc=get_core(); + switch(pagenum) + { + case 0: + net_section_apply(&prop->net,lc); + break; + case 1: + sound_section_apply(&prop->sound,lc); + break; + case 2: + sip_section_apply(&prop->sip,lc); + break; + case 3: + codec_section_apply(&prop->codec,lc); + break; + } +} + + +void +on_audioport_changed (GtkEditable *editable, + gpointer user_data) +{ +#ifdef NOTYET + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); + return; +#endif +} + + +void +on_sipport_changed (GtkEditable *editable, + gpointer user_data) +{ +#ifdef NOTYET + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); + return; +#endif +} + + +void +on_source_changed (GtkEditable *editable, + gpointer user_data) +{ +#ifdef NOTYET + LinphonePropertyBox *prop=get_property_box(); + gnome_property_box_changed(GNOME_PROPERTY_BOX(prop->prop)); +#endif +} + +enum { + CODEC_ACTION_UP, + CODEC_ACTION_DOWN +}; + + +void codec_row_move(GtkTreeView *listview, int action) +{ + GtkTreeIter iter; + GtkTreeIter previter,nextiter,newiter; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreePath *treepath; + struct _PayloadType *codec=NULL; + gchar *name=NULL; + gint rate; + gfloat bitrate; + gchar *status=NULL; + gchar *color=NULL; + + selection=gtk_tree_view_get_selection(listview); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, CODEC_NAME,&name, + CODEC_RATE,&rate, + CODEC_BITRATE,&bitrate, + CODEC_STATUS,&status, + CODEC_PRIVDATA, &codec, + CODEC_COLOR,&color, + -1); + g_return_if_fail(codec!=NULL); + switch(action){ + case CODEC_ACTION_UP: + /* get an iterator on the prev codec */ + treepath=gtk_tree_model_get_path(model,&iter); + if (!gtk_tree_path_prev(treepath)){ + /* codec is the first, no match. */ + return; + } + gtk_tree_model_get_iter(model,&previter,treepath); + gtk_list_store_insert_before(GTK_LIST_STORE(model),&newiter,&previter); + break; + case CODEC_ACTION_DOWN: + /* get an iterator on the next codec */ + nextiter=iter; + if (!gtk_tree_model_iter_next(model,&nextiter)){ + /* codec is the last, no match. */ + return; + } + gtk_list_store_insert_after(GTK_LIST_STORE(model),&newiter,&nextiter); + + break; + } + gtk_list_store_set(GTK_LIST_STORE(model),&newiter, + CODEC_NAME,name, + CODEC_RATE,rate, + CODEC_BITRATE,bitrate, + CODEC_STATUS,status, + CODEC_PRIVDATA, codec, + CODEC_COLOR,color, + -1); + /* remove the selected line */ + gtk_list_store_remove(GTK_LIST_STORE(model),&iter); + gtk_tree_selection_select_iter(selection,&newiter); + g_free(name); + g_free(status); + g_free(color); + } +} + +static void codec_move(int action){ + GtkTreeView *listview; + int page=gtk_notebook_get_current_page(GTK_NOTEBOOK( + lookup_widget(get_property_box()->prop,"codec_notebook"))); + if (page==0) + listview=GTK_TREE_VIEW(get_property_box()->codec.au_codec_list); + else + listview=GTK_TREE_VIEW(lookup_widget(get_property_box()->prop,"vid_codec_list")); + codec_row_move(listview,action); + property_box_changed(); +} + +void +on_aucodec_up_clicked (GtkButton *button, + gpointer user_data) +{ + codec_move(CODEC_ACTION_UP); +} + + +void +on_aucodec_down_clicked (GtkButton *button, + gpointer user_data) +{ + codec_move(CODEC_ACTION_DOWN); +} + +void codec_set_status(GtkTreeView *listview,gboolean status) +{ + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + gchar *statusstring; + selection=gtk_tree_view_get_selection(listview); + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + if (status) statusstring=_("Enabled"); + else statusstring=_("Disabled"); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_STATUS,statusstring,-1); + } +} + +void codec_list_update(GtkTreeView *listview) +{ + GtkTreeModel *model; + GtkTreeIter iter; + PayloadType *pt; + gchar *color; + gfloat bitrate; + model=gtk_tree_view_get_model(listview); + + g_return_if_fail(gtk_tree_model_get_iter_first(model,&iter)); + do{ + gtk_tree_model_get (model, &iter, CODEC_PRIVDATA, &pt,-1); + if (linphone_core_check_payload_type_usability(get_core(),pt)){ + color="blue"; + }else color="red"; + bitrate=payload_type_get_bitrate(pt)/1000.0; + gtk_list_store_set(GTK_LIST_STORE(model),&iter,CODEC_COLOR,color,CODEC_BITRATE,bitrate,-1); + }while (gtk_tree_model_iter_next(model,&iter)); +} + +static void codec_enable(gboolean val){ + GtkTreeView *listview; + int page=gtk_notebook_get_current_page(GTK_NOTEBOOK( + lookup_widget(get_property_box()->prop,"codec_notebook"))); + if (page==0) + listview=GTK_TREE_VIEW(get_property_box()->codec.au_codec_list); + else + listview=GTK_TREE_VIEW(lookup_widget(get_property_box()->prop,"vid_codec_list")); + codec_set_status(listview,val); + property_box_changed(); +} + +void +on_aucodec_enable_clicked (GtkButton *button, + gpointer user_data) +{ + codec_enable(TRUE); +} + + +void +on_aucodec_disable_clicked (GtkButton *button, + gpointer user_data) +{ + codec_enable(FALSE); +} + + +void +on_user_name_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_domain_name_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + + +void +on_reg_passwd_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_obproxy_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_address_of_record_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_audio_jittcomp_value_changed (GtkRange *range, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_ringfileentry_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + +void linphone_property_box_uninit(LinphonePropertyBox *box) +{ + memset(box,0, sizeof(LinphonePropertyBox)); +} + +void +on_property_box_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + int i; + switch(response_id) + { + case GTK_RESPONSE_OK: + for(i = 0; i < 4; i++) + { + linphone_property_box_apply(i); + } + gtk_widget_destroy(GTK_WIDGET(dialog)); + break; + case GTK_RESPONSE_APPLY: + { + GtkNotebook *notebook = GTK_NOTEBOOK(lookup_widget(get_property_box()->prop,"prop1notebook")); + i = gtk_notebook_get_current_page(notebook); + linphone_property_box_apply(i); + } + break; + case GTK_RESPONSE_CLOSE: + case GTK_RESPONSE_CANCEL: + gtk_widget_destroy(GTK_WIDGET(dialog)); + break; + } +} + +gboolean +on_property_box_closed (GtkDialog *gnomedialog, + gpointer user_data) +{ + linphone_property_box_uninit(get_property_box()); + return FALSE; +} + +void +on_use_sipinfo_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + linphone_core_set_use_info_for_dtmf(get_core(),gtk_toggle_button_get_active(togglebutton)); +} + + +void +on_guess_hostname_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + GtkWidget *hostname; + osip_from_t *from; + gboolean val=gtk_toggle_button_get_active(togglebutton); + linphone_core_set_guess_hostname(get_core(),val); + hostname=get_property_box()->sip.hostname; + from=linphone_core_get_primary_contact_parsed(get_core()); + gtk_entry_set_text(GTK_ENTRY(hostname),from->url->host); + gtk_widget_set_sensitive(hostname,!val); + osip_from_free(from); +} + +void +on_download_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + gdouble val=gtk_spin_button_get_value(spinbutton); + if (val==0) gtk_entry_set_text(GTK_ENTRY(spinbutton),_("Unlimited")); + linphone_core_set_download_bandwidth(get_core(),(int)val); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"au_codec_list"))); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"vid_codec_list"))); +} + +void +on_upload_bw_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + gdouble val=gtk_spin_button_get_value(spinbutton); + if (val==0) gtk_entry_set_text(GTK_ENTRY(spinbutton),_("Unlimited")); + linphone_core_set_upload_bandwidth(get_core(),(int)val); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"au_codec_list"))); + codec_list_update(GTK_TREE_VIEW(lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(spinbutton)),"vid_codec_list"))); +} + +void +on_no_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_use_stun_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + + +void +on_static_nat_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + property_box_changed(); +} + +void +on_stun_server_changed (GtkEditable *editable, + gpointer user_data) +{ + property_box_changed(); +} + diff --git a/linphone/gtk/propertybox.h b/linphone/gtk/propertybox.h new file mode 100644 index 000000000..5126a7d2d --- /dev/null +++ b/linphone/gtk/propertybox.h @@ -0,0 +1,96 @@ +/*************************************************************************** + propertybox.h - description + ------------------- + begin : Wed Jan 30 2002 + copyright : (C) 2002 by Simon Morlat + email : simon.morlat@linphone.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "interface.h" + +struct _NetSection +{ + GtkWidget *interfaces; + gint if_sel; + GtkWidget *au_port; + GtkWidget *audio_jittcomp; + GtkWidget *enable_nat; + GtkWidget *nat_label; + GtkWidget *nat_address; + GtkWidget *use_sipinfo; + GtkWidget *enable_ipv6; +}; +typedef struct _NetSection NetSection; + +void net_section_init(NetSection *sec, GtkWidget *prop); +void net_section_apply(NetSection *sec, LinphoneCore *lp); + +struct _SipSection +{ + GtkWidget *port; + GtkWidget *username; + GtkWidget *hostname; + GtkWidget *proxy_list; + GtkWidget *guess_hostname; +}; + +typedef struct _SipSection SipSection; + +void sip_section_enable_registrar(SipSection *sec, LinphoneCore *lp, gboolean state); +void sip_section_fill(SipSection *sec, LinphoneCore *lp); + +void sip_section_init(SipSection *sec, GtkWidget *prop); +void sip_section_apply(SipSection *sec, LinphoneCore *lp); + +struct _CodecSection +{ + GtkWidget *au_codec_list; + GtkWidget *vi_codec_list; + GtkWidget *codec_info; +}; + +typedef struct _CodecSection CodecSection; + +void codec_section_init(CodecSection *sec, GtkWidget *prop); +void codec_section_apply(CodecSection *sec, LinphoneCore *lc); + +struct _SoundSection +{ + GtkWidget *source_entry; + GtkWidget *autokill_button; + GtkWidget *ringfileentry; + GtkWidget *ringpreview; +}; +typedef struct _SoundSection SoundSection; + +void sound_section_init(SoundSection *sec,GtkWidget *prop); +void sound_section_apply(SoundSection *sec, LinphoneCore *lc); + +struct _LinphonePropertyBox +{ + GtkWidget *prop; + NetSection net; + SipSection sip; + CodecSection codec; + SoundSection sound; +}; + +typedef struct _LinphonePropertyBox LinphonePropertyBox; + +void linphone_property_box_init(LinphonePropertyBox *box); +//void linphone_property_box_apply(LinphonePropertyBox * box, LinphoneCore *lc, int page); +void linphone_property_box_apply(int page); +void linphone_property_box_uninit(LinphonePropertyBox *box); diff --git a/linphone/gtk/support.c b/linphone/gtk/support.c new file mode 100644 index 000000000..00aff2982 --- /dev/null +++ b/linphone/gtk/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/linphone/gtk/support.h b/linphone/gtk/support.h new file mode 100644 index 000000000..a32649e53 --- /dev/null +++ b/linphone/gtk/support.h @@ -0,0 +1,69 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (PACKAGE, String) +# define Q_(String) g_strip_context ((String), gettext (String)) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define Q_(String) g_strip_context ((String), (String)) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + diff --git a/linphone/intl/ChangeLog b/linphone/intl/ChangeLog new file mode 100644 index 000000000..65ec50f78 --- /dev/null +++ b/linphone/intl/ChangeLog @@ -0,0 +1,4 @@ +2002-08-06 GNU + + * Version 0.11.5 released. + diff --git a/linphone/intl/Makefile.in b/linphone/intl/Makefile.in new file mode 100644 index 000000000..0486dc93a --- /dev/null +++ b/linphone/intl/Makefile.in @@ -0,0 +1,337 @@ +# Makefile for directory with message catalog handling in GNU NLS Utilities. +# Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +transform = @program_transform_name@ +libdir = @libdir@ +includedir = @includedir@ +datadir = @datadir@ +localedir = $(datadir)/locale +gettextsrcdir = $(datadir)/gettext/intl +aliaspath = $(localedir) +subdir = intl + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(top_builddir)/$(MKINSTALLDIRS)" ;; esac` + +l = @INTL_LIBTOOL_SUFFIX_PREFIX@ + +AR = ar +CC = @CC@ +LIBTOOL = @LIBTOOL@ +RANLIB = @RANLIB@ +YACC = @INTLBISON@ -y -d +YFLAGS = --name-prefix=__gettext + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ +-DLIBDIR=\"$(libdir)\" -DIN_LIBINTL @DEFS@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +HEADERS = $(COMHDRS) libgnuintl.h loadinfo.h +COMHDRS = gmo.h gettextP.h hash-string.h plural-exp.h eval-plural.h os2compat.h +SOURCES = $(COMSRCS) intl-compat.c +COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ +finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ +explodename.c dcigettext.c dcngettext.c dngettext.c ngettext.c plural.y \ +plural-exp.c localcharset.c localename.c osdep.c os2compat.c +OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ +finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ +explodename.$lo dcigettext.$lo dcngettext.$lo dngettext.$lo ngettext.$lo \ +plural.$lo plural-exp.$lo localcharset.$lo localename.$lo osdep.$lo +GETTOBJS = intl-compat.$lo +DISTFILES.common = Makefile.in \ +config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) +DISTFILES.generated = plural.c +DISTFILES.normal = VERSION +DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc +DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \ +COPYING.LIB-2 gettext.h libgettext.h plural-eval.c + +# Libtool's library version information for libintl. +# Before making a gettext release, the gettext maintainer must change this +# according to the libtool documentation, section "Library interface versions". +# Maintainers of other packages that include the intl directory must *not* +# change these values. +LTV_CURRENT=4 +LTV_REVISION=0 +LTV_AGE=2 + +.SUFFIXES: +.SUFFIXES: .c .y .o .lo .sin .sed +.c.o: + $(COMPILE) $< +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) $< + +.y.c: + $(YACC) $(YFLAGS) --output $@ $< + rm -f $*.h + +.sin.sed: + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@ + mv t-$@ $@ + +INCLUDES = -I.. -I. -I$(top_srcdir)/intl + +all: all-@USE_INCLUDED_LIBINTL@ +all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed +all-no: all-no-@BUILD_INCLUDED_LIBINTL@ +all-no-yes: libgnuintl.$la +all-no-no: + +libintl.a libgnuintl.a: $(OBJECTS) + rm -f $@ + $(AR) cru $@ $(OBJECTS) + $(RANLIB) $@ + +libintl.la libgnuintl.la: $(OBJECTS) + $(LIBTOOL) --mode=link \ + $(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ + $(OBJECTS) @LTLIBICONV@ -lc \ + -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ + -rpath $(libdir) \ + -no-undefined + +libintl.h: libgnuintl.h + cp $(srcdir)/libgnuintl.h libintl.h + +charset.alias: config.charset + $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + mv t-$@ $@ + +check: all + +# This installation goal is only used in GNU gettext. Packages which +# only use the library should use install instead. + +# We must not install the libintl.h/libintl.a files if we are on a +# system which has the GNU gettext() function in its C library or in a +# separate library. +# If you want to use the one which comes with this version of the +# package, you have to use `configure --with-included-gettext'. +install: install-exec install-data +install-exec: all + if test "$(PACKAGE)" = "gettext" \ + && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + $(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=install \ + $(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ + temp=$(DESTDIR)$(libdir)/t-charset.alias; \ + dest=$(DESTDIR)$(libdir)/charset.alias; \ + if test -f $(DESTDIR)$(libdir)/charset.alias; then \ + orig=$(DESTDIR)$(libdir)/charset.alias; \ + sed -f ref-add.sed $$orig > $$temp; \ + $(INSTALL_DATA) $$temp $$dest; \ + rm -f $$temp; \ + else \ + if test @GLIBC21@ = no; then \ + orig=charset.alias; \ + sed -f ref-add.sed $$orig > $$temp; \ + $(INSTALL_DATA) $$temp $$dest; \ + rm -f $$temp; \ + fi; \ + fi; \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + test -f $(DESTDIR)$(localedir)/locale.alias \ + && orig=$(DESTDIR)$(localedir)/locale.alias \ + || orig=$(srcdir)/locale.alias; \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-add.sed $$orig > $$temp; \ + $(INSTALL_DATA) $$temp $$dest; \ + rm -f $$temp; \ + else \ + : ; \ + fi +install-data: all + if test "$(PACKAGE)" = "gettext"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + $(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ + $(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ + dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \ + for file in $$dists; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \ + dists="$(DISTFILES.generated)"; \ + for file in $$dists; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + $(INSTALL_DATA) $$dir/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + dists="$(DISTFILES.obsolete)"; \ + for file in $$dists; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +install-strip: install + +installdirs: + if test "$(PACKAGE)" = "gettext" \ + && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + if test "$(PACKAGE)" = "gettext" \ + && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ + rm -f $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=uninstall \ + rm -f $(DESTDIR)$(libdir)/libintl.$la; \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + if test -f $(DESTDIR)$(libdir)/charset.alias; then \ + temp=$(DESTDIR)$(libdir)/t-charset.alias; \ + dest=$(DESTDIR)$(libdir)/charset.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + if test -f $(DESTDIR)$(localedir)/locale.alias; then \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext"; then \ + for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +info dvi: + +$(OBJECTS): ../config.h libgnuintl.h +bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: gettextP.h gmo.h loadinfo.h +dcigettext.$lo: hash-string.h +explodename.$lo l10nflist.$lo: loadinfo.h +dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: plural-exp.h +dcigettext.$lo: eval-plural.h + +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) + +id: ID + +ID: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) + + +mostlyclean: + rm -f *.a *.la *.o *.lo core core.* + rm -f libintl.h charset.alias ref-add.sed ref-del.sed + rm -f -r .libs _libs + +clean: mostlyclean + +distclean: clean + rm -f Makefile ID TAGS + if test "$(PACKAGE)" = gettext; then \ + rm -f ChangeLog.inst $(DISTFILES.normal); \ + else \ + : ; \ + fi + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + +# GNU gettext needs not contain the file `VERSION' but contains some +# other files which should not be distributed in other packages. +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: Makefile + if test "$(PACKAGE)" = gettext; then \ + additional="$(DISTFILES.gettext)"; \ + else \ + additional="$(DISTFILES.normal)"; \ + fi; \ + $(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ + for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + cp -p $$dir/$$file $(distdir); \ + done + +Makefile: Makefile.in ../config.status + cd .. \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/linphone/intl/VERSION b/linphone/intl/VERSION new file mode 100644 index 000000000..acc8052f3 --- /dev/null +++ b/linphone/intl/VERSION @@ -0,0 +1 @@ +GNU gettext library from gettext-0.11.5 diff --git a/linphone/intl/bindtextdom.c b/linphone/intl/bindtextdom.c new file mode 100644 index 000000000..d582ce11d --- /dev/null +++ b/linphone/intl/bindtextdom.c @@ -0,0 +1,369 @@ +/* Implementation of the bindtextdomain(3) function + Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif +#include "gettextP.h" + +#ifdef _LIBC +/* We have to handle multi-threaded applications. */ +# include +#else +/* Provide dummy implementation if this is outside glibc. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +#endif + +/* The internal variables in the standalone libintl.a must have different + names than the internal variables in GNU libc, otherwise programs + using libintl.a cannot be linked statically. */ +#if !defined _LIBC +# define _nl_default_dirname libintl_nl_default_dirname +# define _nl_domain_bindings libintl_nl_domain_bindings +#endif + +/* Some compilers, like SunOS4 cc, don't have offsetof in . */ +#ifndef offsetof +# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) +#endif + +/* @@ end of prolog @@ */ + +/* Contains the default location of the message catalogs. */ +extern const char _nl_default_dirname[]; + +/* List with bindings of specific domains. */ +extern struct binding *_nl_domain_bindings; + +/* Lock variable to protect the global data in the gettext implementation. */ +__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define BINDTEXTDOMAIN __bindtextdomain +# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define BINDTEXTDOMAIN libintl_bindtextdomain +# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset +#endif + +/* Prototypes for local functions. */ +static void set_binding_values PARAMS ((const char *domainname, + const char **dirnamep, + const char **codesetp)); + +/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP + to be used for the DOMAINNAME message catalog. + If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not + modified, only the current value is returned. + If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither + modified nor returned. */ +static void +set_binding_values (domainname, dirnamep, codesetp) + const char *domainname; + const char **dirnamep; + const char **codesetp; +{ + struct binding *binding; + int modified; + + /* Some sanity checks. */ + if (domainname == NULL || domainname[0] == '\0') + { + if (dirnamep) + *dirnamep = NULL; + if (codesetp) + *codesetp = NULL; + return; + } + + __libc_rwlock_wrlock (_nl_state_lock); + + modified = 0; + + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (binding != NULL) + { + if (dirnamep) + { + const char *dirname = *dirnamep; + + if (dirname == NULL) + /* The current binding has be to returned. */ + *dirnamep = binding->dirname; + else + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + char *result = binding->dirname; + if (strcmp (dirname, result) != 0) + { + if (strcmp (dirname, _nl_default_dirname) == 0) + result = (char *) _nl_default_dirname; + else + { +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (dirname); +#else + size_t len = strlen (dirname) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result != NULL, 1)) + memcpy (result, dirname, len); +#endif + } + + if (__builtin_expect (result != NULL, 1)) + { + if (binding->dirname != _nl_default_dirname) + free (binding->dirname); + + binding->dirname = result; + modified = 1; + } + } + *dirnamep = result; + } + } + + if (codesetp) + { + const char *codeset = *codesetp; + + if (codeset == NULL) + /* The current binding has be to returned. */ + *codesetp = binding->codeset; + else + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + char *result = binding->codeset; + if (result == NULL || strcmp (codeset, result) != 0) + { +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (codeset); +#else + size_t len = strlen (codeset) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result != NULL, 1)) + memcpy (result, codeset, len); +#endif + + if (__builtin_expect (result != NULL, 1)) + { + if (binding->codeset != NULL) + free (binding->codeset); + + binding->codeset = result; + binding->codeset_cntr++; + modified = 1; + } + } + *codesetp = result; + } + } + } + else if ((dirnamep == NULL || *dirnamep == NULL) + && (codesetp == NULL || *codesetp == NULL)) + { + /* Simply return the default values. */ + if (dirnamep) + *dirnamep = _nl_default_dirname; + if (codesetp) + *codesetp = NULL; + } + else + { + /* We have to create a new binding. */ + size_t len = strlen (domainname) + 1; + struct binding *new_binding = + (struct binding *) malloc (offsetof (struct binding, domainname) + len); + + if (__builtin_expect (new_binding == NULL, 0)) + goto failed; + + memcpy (new_binding->domainname, domainname, len); + + if (dirnamep) + { + const char *dirname = *dirnamep; + + if (dirname == NULL) + /* The default value. */ + dirname = _nl_default_dirname; + else + { + if (strcmp (dirname, _nl_default_dirname) == 0) + dirname = _nl_default_dirname; + else + { + char *result; +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (dirname); + if (__builtin_expect (result == NULL, 0)) + goto failed_dirname; +#else + size_t len = strlen (dirname) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result == NULL, 0)) + goto failed_dirname; + memcpy (result, dirname, len); +#endif + dirname = result; + } + } + *dirnamep = dirname; + new_binding->dirname = (char *) dirname; + } + else + /* The default value. */ + new_binding->dirname = (char *) _nl_default_dirname; + + new_binding->codeset_cntr = 0; + + if (codesetp) + { + const char *codeset = *codesetp; + + if (codeset != NULL) + { + char *result; + +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (codeset); + if (__builtin_expect (result == NULL, 0)) + goto failed_codeset; +#else + size_t len = strlen (codeset) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result == NULL, 0)) + goto failed_codeset; + memcpy (result, codeset, len); +#endif + codeset = result; + new_binding->codeset_cntr++; + } + *codesetp = codeset; + new_binding->codeset = (char *) codeset; + } + else + new_binding->codeset = NULL; + + /* Now enqueue it. */ + if (_nl_domain_bindings == NULL + || strcmp (domainname, _nl_domain_bindings->domainname) < 0) + { + new_binding->next = _nl_domain_bindings; + _nl_domain_bindings = new_binding; + } + else + { + binding = _nl_domain_bindings; + while (binding->next != NULL + && strcmp (domainname, binding->next->domainname) > 0) + binding = binding->next; + + new_binding->next = binding->next; + binding->next = new_binding; + } + + modified = 1; + + /* Here we deal with memory allocation failures. */ + if (0) + { + failed_codeset: + if (new_binding->dirname != _nl_default_dirname) + free (new_binding->dirname); + failed_dirname: + free (new_binding); + failed: + if (dirnamep) + *dirnamep = NULL; + if (codesetp) + *codesetp = NULL; + } + } + + /* If we modified any binding, we flush the caches. */ + if (modified) + ++_nl_msg_cat_cntr; + + __libc_rwlock_unlock (_nl_state_lock); +} + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +char * +BINDTEXTDOMAIN (domainname, dirname) + const char *domainname; + const char *dirname; +{ + set_binding_values (domainname, &dirname, NULL); + return (char *) dirname; +} + +/* Specify the character encoding in which the messages from the + DOMAINNAME message catalog will be returned. */ +char * +BIND_TEXTDOMAIN_CODESET (domainname, codeset) + const char *domainname; + const char *codeset; +{ + set_binding_values (domainname, NULL, &codeset); + return (char *) codeset; +} + +#ifdef _LIBC +/* Aliases for function names in GNU C Library. */ +weak_alias (__bindtextdomain, bindtextdomain); +weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset); +#endif diff --git a/linphone/intl/cat-compat.c b/linphone/intl/cat-compat.c new file mode 100644 index 000000000..867d901b8 --- /dev/null +++ b/linphone/intl/cat-compat.c @@ -0,0 +1,262 @@ +/* Compatibility code for gettext-using-catgets interface. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef STDC_HEADERS +# include +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# endif +#endif + +#ifdef HAVE_NL_TYPES_H +# include +#endif + +#include "libgettext.h" + +/* @@ end of prolog @@ */ + +/* XPG3 defines the result of `setlocale (category, NULL)' as: + ``Directs `setlocale()' to query `category' and return the current + setting of `local'.'' + However it does not specify the exact format. And even worse: POSIX + defines this not at all. So we can use this feature only on selected + system (e.g. those using GNU C Library). */ +#ifdef _LIBC +# define HAVE_LOCALE_NULL +#endif + +/* The catalog descriptor. */ +static nl_catd catalog = (nl_catd) -1; + +/* Name of the default catalog. */ +static const char default_catalog_name[] = "messages"; + +/* Name of currently used catalog. */ +static const char *catalog_name = default_catalog_name; + +/* Get ID for given string. If not found return -1. */ +static int msg_to_cat_id PARAMS ((const char *msg)); + +/* Substitution for systems lacking this function in their C library. */ +#if !_LIBC && !HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +#endif + + +/* Set currently used domain/catalog. */ +char * +textdomain (domainname) + const char *domainname; +{ + nl_catd new_catalog; + char *new_name; + size_t new_name_len; + char *lang; + +#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ + && defined HAVE_LOCALE_NULL + lang = setlocale (LC_MESSAGES, NULL); +#else + lang = getenv ("LC_ALL"); + if (lang == NULL || lang[0] == '\0') + { + lang = getenv ("LC_MESSAGES"); + if (lang == NULL || lang[0] == '\0') + lang = getenv ("LANG"); + } +#endif + if (lang == NULL || lang[0] == '\0') + lang = "C"; + + /* See whether name of currently used domain is asked. */ + if (domainname == NULL) + return (char *) catalog_name; + + if (domainname[0] == '\0') + domainname = default_catalog_name; + + /* Compute length of added path element. */ + new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) + + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 + + sizeof (".cat"); + + new_name = (char *) malloc (new_name_len); + if (new_name == NULL) + return NULL; + + strcpy (new_name, PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + /* NLSPATH search didn't work, try absolute path */ + sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, + PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + free (new_name); + return (char *) catalog_name; + } + } + + /* Close old catalog. */ + if (catalog != (nl_catd) -1) + catclose (catalog); + if (catalog_name != default_catalog_name) + free ((char *) catalog_name); + + catalog = new_catalog; + catalog_name = new_name; + + return (char *) catalog_name; +} + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ +#if HAVE_SETENV || HAVE_PUTENV + char *old_val, *new_val, *cp; + size_t new_val_len; + + /* This does not make much sense here but to be compatible do it. */ + if (domainname == NULL) + return NULL; + + /* Compute length of added path element. If we use setenv we don't need + the first byts for NLSPATH=, but why complicate the code for this + peanuts. */ + new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + + old_val = getenv ("NLSPATH"); + if (old_val == NULL || old_val[0] == '\0') + { + old_val = NULL; + new_val_len += 1 + sizeof (LOCALEDIR) - 1 + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + } + else + new_val_len += strlen (old_val); + + new_val = (char *) malloc (new_val_len); + if (new_val == NULL) + return NULL; + +# if HAVE_SETENV + cp = new_val; +# else + cp = stpcpy (new_val, "NLSPATH="); +# endif + + cp = stpcpy (cp, dirname); + cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); + + if (old_val == NULL) + { +# if __STDC__ + stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); +# else + + cp = stpcpy (cp, LOCALEDIR); + stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); +# endif + } + else + stpcpy (cp, old_val); + +# if HAVE_SETENV + setenv ("NLSPATH", new_val, 1); + free (new_val); +# else + putenv (new_val); + /* Do *not* free the environment entry we just entered. It is used + from now on. */ +# endif + +#endif + + return (char *) domainname; +} + +#undef gettext +char * +gettext (msg) + const char *msg; +{ + int msgid; + + if (msg == NULL || catalog == (nl_catd) -1) + return (char *) msg; + + /* Get the message from the catalog. We always use set number 1. + The message ID is computed by the function `msg_to_cat_id' + which works on the table generated by `po-to-tbl'. */ + msgid = msg_to_cat_id (msg); + if (msgid == -1) + return (char *) msg; + + return catgets (catalog, 1, msgid, (char *) msg); +} + +/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries + for the one equal to msg. If it is found return the ID. In case when + the string is not found return -1. */ +static int +msg_to_cat_id (msg) + const char *msg; +{ + int cnt; + + for (cnt = 0; cnt < _msg_tbl_length; ++cnt) + if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) + return _msg_tbl[cnt]._msg_number; + + return -1; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/linphone/intl/dcgettext.c b/linphone/intl/dcgettext.c new file mode 100644 index 000000000..ca6a1c82d --- /dev/null +++ b/linphone/intl/dcgettext.c @@ -0,0 +1,59 @@ +/* Implementation of the dcgettext(3) function. + Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCGETTEXT __dcgettext +# define DCIGETTEXT __dcigettext +#else +# define DCGETTEXT libintl_dcgettext +# define DCIGETTEXT libintl_dcigettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +char * +DCGETTEXT (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +INTDEF(__dcgettext) +weak_alias (__dcgettext, dcgettext); +#endif diff --git a/linphone/intl/dgettext.c b/linphone/intl/dgettext.c new file mode 100644 index 000000000..cf5b4037f --- /dev/null +++ b/linphone/intl/dgettext.c @@ -0,0 +1,59 @@ +/* Implementation of the dgettext(3) function. + Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DGETTEXT __dgettext +# define DCGETTEXT INTUSE(__dcgettext) +#else +# define DGETTEXT libintl_dgettext +# define DCGETTEXT libintl_dcgettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog of the current + LC_MESSAGES locale. */ +char * +DGETTEXT (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return DCGETTEXT (domainname, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dgettext, dgettext); +#endif diff --git a/linphone/intl/explodename.c b/linphone/intl/explodename.c new file mode 100644 index 000000000..2985064c9 --- /dev/null +++ b/linphone/intl/explodename.c @@ -0,0 +1,192 @@ +/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +char * +_nl_find_language (name) + const char *name; +{ + while (name[0] != '\0' && name[0] != '_' && name[0] != '@' + && name[0] != '+' && name[0] != ',') + ++name; + + return (char *) name; +} + + +int +_nl_explode_name (name, language, modifier, territory, codeset, + normalized_codeset, special, sponsor, revision) + char *name; + const char **language; + const char **modifier; + const char **territory; + const char **codeset; + const char **normalized_codeset; + const char **special; + const char **sponsor; + const char **revision; +{ + enum { undecided, xpg, cen } syntax; + char *cp; + int mask; + + *modifier = NULL; + *territory = NULL; + *codeset = NULL; + *normalized_codeset = NULL; + *special = NULL; + *sponsor = NULL; + *revision = NULL; + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = 0; + syntax = undecided; + *language = cp = name; + cp = _nl_find_language (*language); + + if (*language == cp) + /* This does not make sense: language has to be specified. Use + this entry as it is without exploding. Perhaps it is an alias. */ + cp = strchr (*language, '\0'); + else if (cp[0] == '_') + { + /* Next is the territory. */ + cp[0] = '\0'; + *territory = ++cp; + + while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' + && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= TERRITORY; + + if (cp[0] == '.') + { + /* Next is the codeset. */ + syntax = xpg; + cp[0] = '\0'; + *codeset = ++cp; + + while (cp[0] != '\0' && cp[0] != '@') + ++cp; + + mask |= XPG_CODESET; + + if (*codeset != cp && (*codeset)[0] != '\0') + { + *normalized_codeset = _nl_normalize_codeset (*codeset, + cp - *codeset); + if (strcmp (*codeset, *normalized_codeset) == 0) + free ((char *) *normalized_codeset); + else + mask |= XPG_NORM_CODESET; + } + } + } + + if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) + { + /* Next is the modifier. */ + syntax = cp[0] == '@' ? xpg : cen; + cp[0] = '\0'; + *modifier = ++cp; + + while (syntax == cen && cp[0] != '\0' && cp[0] != '+' + && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= XPG_MODIFIER | CEN_AUDIENCE; + } + + if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) + { + syntax = cen; + + if (cp[0] == '+') + { + /* Next is special application (CEN syntax). */ + cp[0] = '\0'; + *special = ++cp; + + while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= CEN_SPECIAL; + } + + if (cp[0] == ',') + { + /* Next is sponsor (CEN syntax). */ + cp[0] = '\0'; + *sponsor = ++cp; + + while (cp[0] != '\0' && cp[0] != '_') + ++cp; + + mask |= CEN_SPONSOR; + } + + if (cp[0] == '_') + { + /* Next is revision (CEN syntax). */ + cp[0] = '\0'; + *revision = ++cp; + + mask |= CEN_REVISION; + } + } + + /* For CEN syntax values it might be important to have the + separator character in the file name, not for XPG syntax. */ + if (syntax == xpg) + { + if (*territory != NULL && (*territory)[0] == '\0') + mask &= ~TERRITORY; + + if (*codeset != NULL && (*codeset)[0] == '\0') + mask &= ~XPG_CODESET; + + if (*modifier != NULL && (*modifier)[0] == '\0') + mask &= ~XPG_MODIFIER; + } + + return mask; +} diff --git a/linphone/intl/finddomain.c b/linphone/intl/finddomain.c new file mode 100644 index 000000000..2f103d556 --- /dev/null +++ b/linphone/intl/finddomain.c @@ -0,0 +1,198 @@ +/* Handle list of needed message catalogs + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ +/* List of already loaded domains. */ +static struct loaded_l10nfile *_nl_loaded_domains; + + +/* Return a data structure describing the message catalog described by + the DOMAINNAME and CATEGORY parameters with respect to the currently + established bindings. */ +struct loaded_l10nfile * +internal_function +_nl_find_domain (dirname, locale, domainname, domainbinding) + const char *dirname; + char *locale; + const char *domainname; + struct binding *domainbinding; +{ + struct loaded_l10nfile *retval; + const char *language; + const char *modifier; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *special; + const char *sponsor; + const char *revision; + const char *alias_value; + int mask; + + /* LOCALE can consist of up to four recognized parts for the XPG syntax: + + language[_territory[.codeset]][@modifier] + + and six parts for the CEN syntax: + + language[_territory][+audience][+special][,[sponsor][_revision]] + + Beside the first part all of them are allowed to be missing. If + the full specified locale is not found, the less specific one are + looked for. The various parts will be stripped off according to + the following order: + (1) revision + (2) sponsor + (3) special + (4) codeset + (5) normalized codeset + (6) territory + (7) audience/modifier + */ + + /* If we have already tested for this locale entry there has to + be one data set in the list of loaded domains. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, 0, locale, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, domainname, 0); + if (retval != NULL) + { + /* We know something about this locale. */ + int cnt; + + if (retval->decided == 0) + _nl_load_domain (retval, domainbinding); + + if (retval->data != NULL) + return retval; + + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt], domainbinding); + + if (retval->successor[cnt]->data != NULL) + break; + } + return cnt >= 0 ? retval : NULL; + /* NOTREACHED */ + } + + /* See whether the locale value is an alias. If yes its value + *overwrites* the alias name. No test for the original value is + done. */ + alias_value = _nl_expand_alias (locale); + if (alias_value != NULL) + { +#if defined _LIBC || defined HAVE_STRDUP + locale = strdup (alias_value); + if (locale == NULL) + return NULL; +#else + size_t len = strlen (alias_value) + 1; + locale = (char *) malloc (len); + if (locale == NULL) + return NULL; + + memcpy (locale, alias_value, len); +#endif + } + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = _nl_explode_name (locale, &language, &modifier, &territory, + &codeset, &normalized_codeset, &special, + &sponsor, &revision); + + /* Create all possible locale entries which might be interested in + generalization. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, mask, language, territory, + codeset, normalized_codeset, modifier, special, + sponsor, revision, domainname, 1); + if (retval == NULL) + /* This means we are out of core. */ + return NULL; + + if (retval->decided == 0) + _nl_load_domain (retval, domainbinding); + if (retval->data == NULL) + { + int cnt; + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt], domainbinding); + if (retval->successor[cnt]->data != NULL) + break; + } + } + + /* The room for an alias was dynamically allocated. Free it now. */ + if (alias_value != NULL) + free (locale); + + /* The space for normalized_codeset is dynamically allocated. Free it. */ + if (mask & XPG_NORM_CODESET) + free ((void *) normalized_codeset); + + return retval; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + struct loaded_l10nfile *runp = _nl_loaded_domains; + + while (runp != NULL) + { + struct loaded_l10nfile *here = runp; + if (runp->data != NULL) + _nl_unload_domain ((struct loaded_domain *) runp->data); + runp = runp->next; + free ((char *) here->filename); + free (here); + } +} + +text_set_element (__libc_subfreeres, free_mem); +#endif diff --git a/linphone/intl/gettext.c b/linphone/intl/gettext.c new file mode 100644 index 000000000..43d689f55 --- /dev/null +++ b/linphone/intl/gettext.c @@ -0,0 +1,64 @@ +/* Implementation of gettext(3) function. + Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define __need_NULL +# include +#else +# include /* Just for NULL. */ +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define GETTEXT __gettext +# define DCGETTEXT INTUSE(__dcgettext) +#else +# define GETTEXT libintl_gettext +# define DCGETTEXT libintl_dcgettext +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +char * +GETTEXT (msgid) + const char *msgid; +{ + return DCGETTEXT (NULL, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__gettext, gettext); +#endif diff --git a/linphone/intl/gettext.h b/linphone/intl/gettext.h new file mode 100644 index 000000000..6f5d76055 --- /dev/null +++ b/linphone/intl/gettext.h @@ -0,0 +1,102 @@ +/* Description of GNU message catalog format: general file layout. + Copyright (C) 1995, 1997, 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _GETTEXT_H +#define _GETTEXT_H 1 + +#if HAVE_LIMITS_H || _LIBC +# include +#endif + +/* @@ end of prolog @@ */ + +/* The magic number of the GNU message catalog format. */ +#define _MAGIC 0x950412de +#define _MAGIC_SWAPPED 0xde120495 + +/* Revision number of the currently used .mo (binary) file format. */ +#define MO_REVISION_NUMBER 0 + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work + when cross-compiling. */ + +#if __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS +typedef unsigned nls_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS +typedef unsigned short nls_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS +typedef unsigned long nls_uint32; +# else + /* The following line is intended to throw an error. Using #error is + not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + + +/* Header for binary .mo file format. */ +struct mo_file_header +{ + /* The magic number. */ + nls_uint32 magic; + /* The revision number of the file format. */ + nls_uint32 revision; + /* The number of strings pairs. */ + nls_uint32 nstrings; + /* Offset of table with start offsets of original strings. */ + nls_uint32 orig_tab_offset; + /* Offset of table with start offsets of translation strings. */ + nls_uint32 trans_tab_offset; + /* Size of hashing table. */ + nls_uint32 hash_tab_size; + /* Offset of first hashing entry. */ + nls_uint32 hash_tab_offset; +}; + +struct string_desc +{ + /* Length of addressed string. */ + nls_uint32 length; + /* Offset of string in file. */ + nls_uint32 offset; +}; + +/* @@ begin of epilog @@ */ + +#endif /* gettext.h */ diff --git a/linphone/intl/gettextP.h b/linphone/intl/gettextP.h new file mode 100644 index 000000000..f085c59bb --- /dev/null +++ b/linphone/intl/gettextP.h @@ -0,0 +1,242 @@ +/* Header describing internals of libintl library. + Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _GETTEXTP_H +#define _GETTEXTP_H + +#include /* Get size_t. */ + +#ifdef _LIBC +# include "../iconv/gconv_int.h" +#else +# if HAVE_ICONV +# include +# endif +#endif + +#include "loadinfo.h" + +#include "gmo.h" /* Get nls_uint32. */ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +#ifndef W +# define W(flag, data) ((flag) ? SWAP (data) : (data)) +#endif + + +#ifdef _LIBC +# include +# define SWAP(i) bswap_32 (i) +#else +static inline nls_uint32 +SWAP (i) + nls_uint32 i; +{ + return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); +} +#endif + + +/* In-memory representation of system dependent string. */ +struct sysdep_string_desc +{ + /* Length of addressed string, including the trailing NUL. */ + size_t length; + /* Pointer to addressed string. */ + const char *pointer; +}; + +/* The representation of an opened message catalog. */ +struct loaded_domain +{ + /* Pointer to memory containing the .mo file. */ + const char *data; + /* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed. */ + int use_mmap; + /* Size of mmap()ed memory. */ + size_t mmap_size; + /* 1 if the .mo file uses a different endianness than this machine. */ + int must_swap; + /* Pointer to additional malloc()ed memory. */ + void *malloced; + + /* Number of static strings pairs. */ + nls_uint32 nstrings; + /* Pointer to descriptors of original strings in the file. */ + const struct string_desc *orig_tab; + /* Pointer to descriptors of translated strings in the file. */ + const struct string_desc *trans_tab; + + /* Number of system dependent strings pairs. */ + nls_uint32 n_sysdep_strings; + /* Pointer to descriptors of original sysdep strings. */ + const struct sysdep_string_desc *orig_sysdep_tab; + /* Pointer to descriptors of translated sysdep strings. */ + const struct sysdep_string_desc *trans_sysdep_tab; + + /* Size of hash table. */ + nls_uint32 hash_size; + /* Pointer to hash table. */ + const nls_uint32 *hash_tab; + /* 1 if the hash table uses a different endianness than this machine. */ + int must_swap_hash_tab; + + int codeset_cntr; +#ifdef _LIBC + __gconv_t conv; +#else +# if HAVE_ICONV + iconv_t conv; +# endif +#endif + char **conv_tab; + + struct expression *plural; + unsigned long int nplurals; +}; + +/* We want to allocate a string at the end of the struct. But ISO C + doesn't allow zero sized arrays. */ +#ifdef __GNUC__ +# define ZERO 0 +#else +# define ZERO 1 +#endif + +/* A set of settings bound to a message domain. Used to store settings + from bindtextdomain() and bind_textdomain_codeset(). */ +struct binding +{ + struct binding *next; + char *dirname; + int codeset_cntr; /* Incremented each time codeset changes. */ + char *codeset; + char domainname[ZERO]; +}; + +/* A counter which is incremented each time some previous translations + become invalid. + This variable is part of the external ABI of the GNU libintl. */ +extern int _nl_msg_cat_cntr; + +#ifndef _LIBC +const char *_nl_locale_name PARAMS ((int category, const char *categoryname)); +#endif + +struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, + char *__locale, + const char *__domainname, + struct binding *__domainbinding)) + internal_function; +void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain, + struct binding *__domainbinding)) + internal_function; +void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) + internal_function; +const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file, + struct loaded_domain *__domain, + struct binding *__domainbinding)) + internal_function; +void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain)) + internal_function; + +char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file, + struct binding *domainbinding, + const char *msgid, size_t *lengthp)) + internal_function; + +#ifdef _LIBC +extern char *__gettext PARAMS ((const char *__msgid)); +extern char *__dgettext PARAMS ((const char *__domainname, + const char *__msgid)); +extern char *__dcgettext PARAMS ((const char *__domainname, + const char *__msgid, int __category)); +extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, + unsigned long int __n)); +extern char *__dngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int n)); +extern char *__dcngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category)); +extern char *__dcigettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +extern char *__textdomain PARAMS ((const char *__domainname)); +extern char *__bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, + const char *__codeset)); +#else +extern char *libintl_gettext PARAMS ((const char *__msgid)); +extern char *libintl_dgettext PARAMS ((const char *__domainname, + const char *__msgid)); +extern char *libintl_dcgettext PARAMS ((const char *__domainname, + const char *__msgid, int __category)); +extern char *libintl_ngettext PARAMS ((const char *__msgid1, + const char *__msgid2, + unsigned long int __n)); +extern char *libintl_dngettext PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + unsigned long int __n)); +extern char *libintl_dcngettext PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + unsigned long int __n, + int __category)); +extern char *libintl_dcigettext PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +extern char *libintl_textdomain PARAMS ((const char *__domainname)); +extern char *libintl_bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *libintl_bind_textdomain_codeset PARAMS ((const char *__domainname, + const char *__codeset)); +#endif + +/* @@ begin of epilog @@ */ + +#endif /* gettextP.h */ diff --git a/linphone/intl/hash-string.h b/linphone/intl/hash-string.h new file mode 100644 index 000000000..b267a8778 --- /dev/null +++ b/linphone/intl/hash-string.h @@ -0,0 +1,59 @@ +/* Description of GNU message catalog format: string hashing function. + Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + +/* We assume to have `unsigned long int' value with at least 32 bits. */ +#define HASHWORDBITS 32 + + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static unsigned long int hash_string PARAMS ((const char *__str_param)); + +static inline unsigned long int +hash_string (str_param) + const char *str_param; +{ + unsigned long int hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (unsigned long int) *str++; + g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} diff --git a/linphone/intl/intl-compat.c b/linphone/intl/intl-compat.c new file mode 100644 index 000000000..da890159f --- /dev/null +++ b/linphone/intl/intl-compat.c @@ -0,0 +1,131 @@ +/* intl-compat.c - Stub functions to call gettext functions from GNU gettext + Library. + Copyright (C) 1995, 2000-2002 Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define _INTL_REDIRECT_MACROS +#include "libgnuintl.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +/* This file redirects the gettext functions (without prefix) to those + defined in the included GNU libintl library (with "libintl_" prefix). + It is compiled into libintl in order to make the AM_GNU_GETTEXT test + of gettext <= 0.11.2 work with the libintl library >= 0.11.3 which + has the redirections primarily in the include file. */ + + +#undef gettext +#undef dgettext +#undef dcgettext +#undef ngettext +#undef dngettext +#undef dcngettext +#undef textdomain +#undef bindtextdomain +#undef bind_textdomain_codeset + + +char * +gettext (msgid) + const char *msgid; +{ + return libintl_gettext (msgid); +} + + +char * +dgettext (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return libintl_dgettext (domainname, msgid); +} + + +char * +dcgettext (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return libintl_dcgettext (domainname, msgid, category); +} + + +char * +ngettext (msgid1, msgid2, n) + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return libintl_ngettext (msgid1, msgid2, n); +} + + +char * +dngettext (domainname, msgid1, msgid2, n) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return libintl_dngettext (domainname, msgid1, msgid2, n); +} + + +char * +dcngettext (domainname, msgid1, msgid2, n, category) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; + int category; +{ + return libintl_dcngettext (domainname, msgid1, msgid2, n, category); +} + + +char * +textdomain (domainname) + const char *domainname; +{ + return libintl_textdomain (domainname); +} + + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ + return libintl_bindtextdomain (domainname, dirname); +} + + +char * +bind_textdomain_codeset (domainname, codeset) + const char *domainname; + const char *codeset; +{ + return libintl_bind_textdomain_codeset (domainname, codeset); +} diff --git a/linphone/intl/l10nflist.c b/linphone/intl/l10nflist.c new file mode 100644 index 000000000..ec8713f8e --- /dev/null +++ b/linphone/intl/l10nflist.c @@ -0,0 +1,453 @@ +/* Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Tell glibc's to provide a prototype for stpcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if defined _LIBC || defined HAVE_ARGZ_H +# include +#endif +#include +#include +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# ifndef stpcpy +# define stpcpy(dest, src) __stpcpy(dest, src) +# endif +#else +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, + it may be concatenated to a directory pathname. + */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) +#endif + +/* Define function which are usually not available. */ + +#if !defined _LIBC && !defined HAVE___ARGZ_COUNT +/* Returns the number of strings in ARGZ. */ +static size_t argz_count__ PARAMS ((const char *argz, size_t len)); + +static size_t +argz_count__ (argz, len) + const char *argz; + size_t len; +{ + size_t count = 0; + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len + 1; + len -= part_len + 1; + count++; + } + return count; +} +# undef __argz_count +# define __argz_count(argz, len) argz_count__ (argz, len) +#else +# ifdef _LIBC +# define __argz_count(argz, len) INTUSE(__argz_count) (argz, len) +# endif +#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ + +#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ +static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); + +static void +argz_stringify__ (argz, len, sep) + char *argz; + size_t len; + int sep; +{ + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len; + len -= part_len + 1; + if (len > 0) + *argz++ = sep; + } +} +# undef __argz_stringify +# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) +#else +# ifdef _LIBC +# define __argz_stringify(argz, len, sep) \ + INTUSE(__argz_stringify) (argz, len, sep) +# endif +#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ + +#if !defined _LIBC && !defined HAVE___ARGZ_NEXT +static char *argz_next__ PARAMS ((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next__ (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + if (entry) + { + if (entry < argz + argz_len) + entry = strchr (entry, '\0') + 1; + + return entry >= argz + argz_len ? NULL : (char *) entry; + } + else + if (argz_len > 0) + return argz; + else + return 0; +} +# undef __argz_next +# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) +#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ + + +/* Return number of bits set in X. */ +static int pop PARAMS ((int x)); + +static inline int +pop (x) + int x; +{ + /* We assume that no more than 16 bits are used. */ + x = ((x & ~0x5555) >> 1) + (x & 0x5555); + x = ((x & ~0x3333) >> 2) + (x & 0x3333); + x = ((x >> 4) + x) & 0x0f0f; + x = ((x >> 8) + x) & 0xff; + + return x; +} + + +struct loaded_l10nfile * +_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, + territory, codeset, normalized_codeset, modifier, special, + sponsor, revision, filename, do_allocate) + struct loaded_l10nfile **l10nfile_list; + const char *dirlist; + size_t dirlist_len; + int mask; + const char *language; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *modifier; + const char *special; + const char *sponsor; + const char *revision; + const char *filename; + int do_allocate; +{ + char *abs_filename; + struct loaded_l10nfile **lastp; + struct loaded_l10nfile *retval; + char *cp; + size_t dirlist_count; + size_t entries; + int cnt; + + /* If LANGUAGE contains an absolute directory specification, we ignore + DIRLIST. */ + if (IS_ABSOLUTE_PATH (language)) + dirlist_len = 0; + + /* Allocate room for the full file name. */ + abs_filename = (char *) malloc (dirlist_len + + strlen (language) + + ((mask & TERRITORY) != 0 + ? strlen (territory) + 1 : 0) + + ((mask & XPG_CODESET) != 0 + ? strlen (codeset) + 1 : 0) + + ((mask & XPG_NORM_CODESET) != 0 + ? strlen (normalized_codeset) + 1 : 0) + + (((mask & XPG_MODIFIER) != 0 + || (mask & CEN_AUDIENCE) != 0) + ? strlen (modifier) + 1 : 0) + + ((mask & CEN_SPECIAL) != 0 + ? strlen (special) + 1 : 0) + + (((mask & CEN_SPONSOR) != 0 + || (mask & CEN_REVISION) != 0) + ? (1 + ((mask & CEN_SPONSOR) != 0 + ? strlen (sponsor) : 0) + + ((mask & CEN_REVISION) != 0 + ? strlen (revision) + 1 : 0)) : 0) + + 1 + strlen (filename) + 1); + + if (abs_filename == NULL) + return NULL; + + /* Construct file name. */ + cp = abs_filename; + if (dirlist_len > 0) + { + memcpy (cp, dirlist, dirlist_len); + __argz_stringify (cp, dirlist_len, PATH_SEPARATOR); + cp += dirlist_len; + cp[-1] = '/'; + } + + cp = stpcpy (cp, language); + + if ((mask & TERRITORY) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, territory); + } + if ((mask & XPG_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, codeset); + } + if ((mask & XPG_NORM_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, normalized_codeset); + } + if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) + { + /* This component can be part of both syntaces but has different + leading characters. For CEN we use `+', else `@'. */ + *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; + cp = stpcpy (cp, modifier); + } + if ((mask & CEN_SPECIAL) != 0) + { + *cp++ = '+'; + cp = stpcpy (cp, special); + } + if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) + { + *cp++ = ','; + if ((mask & CEN_SPONSOR) != 0) + cp = stpcpy (cp, sponsor); + if ((mask & CEN_REVISION) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, revision); + } + } + + *cp++ = '/'; + stpcpy (cp, filename); + + /* Look in list of already loaded domains whether it is already + available. */ + lastp = l10nfile_list; + for (retval = *l10nfile_list; retval != NULL; retval = retval->next) + if (retval->filename != NULL) + { + int compare = strcmp (retval->filename, abs_filename); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It's not in the list. */ + retval = NULL; + break; + } + + lastp = &retval->next; + } + + if (retval != NULL || do_allocate == 0) + { + free (abs_filename); + return retval; + } + + dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1); + + /* Allocate a new loaded_l10nfile. */ + retval = + (struct loaded_l10nfile *) + malloc (sizeof (*retval) + + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0)) + * sizeof (struct loaded_l10nfile *))); + if (retval == NULL) + return NULL; + + retval->filename = abs_filename; + + /* We set retval->data to NULL here; it is filled in later. + Setting retval->decided to 1 here means that retval does not + correspond to a real file (dirlist_count > 1) or is not worth + looking up (if an unnormalized codeset was specified). */ + retval->decided = (dirlist_count > 1 + || ((mask & XPG_CODESET) != 0 + && (mask & XPG_NORM_CODESET) != 0)); + retval->data = NULL; + + retval->next = *lastp; + *lastp = retval; + + entries = 0; + /* Recurse to fill the inheritance list of RETVAL. + If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL + entry does not correspond to a real file; retval->filename contains + colons. In this case we loop across all elements of DIRLIST and + across all bit patterns dominated by MASK. + If the DIRLIST is a single directory or entirely redundant (i.e. + DIRLIST_COUNT == 1), we loop across all bit patterns dominated by + MASK, excluding MASK itself. + In either case, we loop down from MASK to 0. This has the effect + that the extra bits in the locale name are dropped in this order: + first the modifier, then the territory, then the codeset, then the + normalized_codeset. */ + for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt) + if ((cnt & ~mask) == 0 + && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) + && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) + { + if (dirlist_count > 1) + { + /* Iterate over all elements of the DIRLIST. */ + char *dir = NULL; + + while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) + != NULL) + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, + cnt, language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + else + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, + cnt, language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + retval->successor[entries] = NULL; + + return retval; +} + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. The return value is dynamically allocated and has to be + freed by the caller. */ +const char * +_nl_normalize_codeset (codeset, name_len) + const char *codeset; + size_t name_len; +{ + int len = 0; + int only_digit = 1; + char *retval; + char *wp; + size_t cnt; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalnum ((unsigned char) codeset[cnt])) + { + ++len; + + if (isalpha ((unsigned char) codeset[cnt])) + only_digit = 0; + } + + retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); + + if (retval != NULL) + { + if (only_digit) + wp = stpcpy (retval, "iso"); + else + wp = retval; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalpha ((unsigned char) codeset[cnt])) + *wp++ = tolower ((unsigned char) codeset[cnt]); + else if (isdigit ((unsigned char) codeset[cnt])) + *wp++ = codeset[cnt]; + + *wp = '\0'; + } + + return (const char *) retval; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/linphone/intl/libgettext.h b/linphone/intl/libgettext.h new file mode 100644 index 000000000..c5be54a80 --- /dev/null +++ b/linphone/intl/libgettext.h @@ -0,0 +1,49 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +# define gettext(Msgid) (Msgid) +# define dgettext(Domainname, Msgid) (Msgid) +# define dcgettext(Domainname, Msgid, Category) (Msgid) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (char *) (Msgid1) : (char *) (Msgid2)) +# define textdomain(Domainname) ((char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((char *) (Codeset)) + +#endif + +/* For automatical extraction of messages sometimes no real + translation is needed. Instead the string itself is the result. */ +#define gettext_noop(Str) (Str) + +#endif /* _LIBGETTEXT_H */ diff --git a/linphone/intl/linux-msg.sed b/linphone/intl/linux-msg.sed new file mode 100644 index 000000000..5918e720a --- /dev/null +++ b/linphone/intl/linux-msg.sed @@ -0,0 +1,100 @@ +# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# Mitch's old catalog format does not allow comments. +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { + s/msgid[ ]*"// +# +# This does not work now with the new format. +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/# \1/ +# Clear substitution flag. + tb +# Append the next line. + :b + N +# Look whether second part is continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that D includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/linphone/intl/loadinfo.h b/linphone/intl/loadinfo.h new file mode 100644 index 000000000..1d3ba6162 --- /dev/null +++ b/linphone/intl/loadinfo.h @@ -0,0 +1,156 @@ +/* Copyright (C) 1996-1999, 2000-2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LOADINFO_H +#define _LOADINFO_H 1 + +/* Declarations of locale dependent catalog lookup functions. + Implemented in + + localealias.c Possibly replace a locale name by another. + explodename.c Split a locale name into its various fields. + l10nflist.c Generate a list of filenames of possible message catalogs. + finddomain.c Find and open the relevant message catalogs. + + The main function _nl_find_domain() in finddomain.c is declared + in gettextP.h. + */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +/* Separator in PATH like lists of pathnames. */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define PATH_SEPARATOR ';' +#else + /* Unix */ +# define PATH_SEPARATOR ':' +#endif + +/* Encoding of locale name parts. */ +#define CEN_REVISION 1 +#define CEN_SPONSOR 2 +#define CEN_SPECIAL 4 +#define XPG_NORM_CODESET 8 +#define XPG_CODESET 16 +#define TERRITORY 32 +#define CEN_AUDIENCE 64 +#define XPG_MODIFIER 128 + +#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) +#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) + + +struct loaded_l10nfile +{ + const char *filename; + int decided; + + const void *data; + + struct loaded_l10nfile *next; + struct loaded_l10nfile *successor[1]; +}; + + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. The return value is dynamically allocated and has to be + freed by the caller. */ +extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, + size_t name_len)); + +/* Lookup a locale dependent file. + *L10NFILE_LIST denotes a pool of lookup results of locale dependent + files of the same kind, sorted in decreasing order of ->filename. + DIRLIST and DIRLIST_LEN are an argz list of directories in which to + look, containing at least one directory (i.e. DIRLIST_LEN > 0). + MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER, + SPECIAL, SPONSOR, REVISION are the pieces of the locale name, as + produced by _nl_explode_name(). FILENAME is the filename suffix. + The return value is the lookup result, either found in *L10NFILE_LIST, + or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL. + If the return value is non-NULL, it is added to *L10NFILE_LIST, and + its ->next field denotes the chaining inside *L10NFILE_LIST, and + furthermore its ->successor[] field contains a list of other lookup + results from which this lookup result inherits. */ +extern struct loaded_l10nfile * +_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, int mask, + const char *language, const char *territory, + const char *codeset, + const char *normalized_codeset, + const char *modifier, const char *special, + const char *sponsor, const char *revision, + const char *filename, int do_allocate)); + +/* Lookup the real locale name for a locale alias NAME, or NULL if + NAME is not a locale alias (but possibly a real locale name). + The return value is statically allocated and must not be freed. */ +extern const char *_nl_expand_alias PARAMS ((const char *name)); + +/* Split a locale name NAME into its pieces: language, modifier, + territory, codeset, special, sponsor, revision. + NAME gets destructively modified: NUL bytes are inserted here and + there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY, + *CODESET, *SPECIAL, *SPONSOR, *REVISION gets assigned either a + pointer into the old NAME string, or NULL. *NORMALIZED_CODESET + gets assigned the expanded *CODESET, if it is different from *CODESET; + this one is dynamically allocated and has to be freed by the caller. + The return value is a bitmask, where each bit corresponds to one + filled-in value: + XPG_MODIFIER, CEN_AUDIENCE for *MODIFIER, + TERRITORY for *TERRITORY, + XPG_CODESET for *CODESET, + XPG_NORM_CODESET for *NORMALIZED_CODESET, + CEN_SPECIAL for *SPECIAL, + CEN_SPONSOR for *SPONSOR, + CEN_REVISION for *REVISION. + */ +extern int _nl_explode_name PARAMS ((char *name, const char **language, + const char **modifier, + const char **territory, + const char **codeset, + const char **normalized_codeset, + const char **special, + const char **sponsor, + const char **revision)); + +/* Split a locale name NAME into a leading language part and all the + rest. Return a pointer to the first character after the language, + i.e. to the first byte of the rest. */ +extern char *_nl_find_language PARAMS ((const char *name)); + +#endif /* loadinfo.h */ diff --git a/linphone/intl/loadmsgcat.c b/linphone/intl/loadmsgcat.c new file mode 100644 index 000000000..516f5211b --- /dev/null +++ b/linphone/intl/loadmsgcat.c @@ -0,0 +1,1316 @@ +/* Load needed message catalogs. + Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Tell glibc's to provide a prototype for mempcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#include +#include + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#ifdef _LIBC +# include +# include +#endif + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || (defined _LIBC && defined _POSIX_MAPPED_FILES) +# include +# undef HAVE_MMAP +# define HAVE_MMAP 1 +#else +# undef HAVE_MMAP +#endif + +#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC +# include +#endif +#if defined HAVE_INTTYPES_H || defined _LIBC +# include +#endif + +#include "gmo.h" +#include "gettextP.h" +#include "hash-string.h" +#include "plural-exp.h" + +#ifdef _LIBC +# include "../locale/localeinfo.h" +#endif + +/* Provide fallback values for macros that ought to be defined in . + Note that our fallback values need not be literal strings, because we don't + use them with preprocessor string concatenation. */ +#if !defined PRId8 || PRI_MACROS_BROKEN +# undef PRId8 +# define PRId8 "d" +#endif +#if !defined PRIi8 || PRI_MACROS_BROKEN +# undef PRIi8 +# define PRIi8 "i" +#endif +#if !defined PRIo8 || PRI_MACROS_BROKEN +# undef PRIo8 +# define PRIo8 "o" +#endif +#if !defined PRIu8 || PRI_MACROS_BROKEN +# undef PRIu8 +# define PRIu8 "u" +#endif +#if !defined PRIx8 || PRI_MACROS_BROKEN +# undef PRIx8 +# define PRIx8 "x" +#endif +#if !defined PRIX8 || PRI_MACROS_BROKEN +# undef PRIX8 +# define PRIX8 "X" +#endif +#if !defined PRId16 || PRI_MACROS_BROKEN +# undef PRId16 +# define PRId16 "d" +#endif +#if !defined PRIi16 || PRI_MACROS_BROKEN +# undef PRIi16 +# define PRIi16 "i" +#endif +#if !defined PRIo16 || PRI_MACROS_BROKEN +# undef PRIo16 +# define PRIo16 "o" +#endif +#if !defined PRIu16 || PRI_MACROS_BROKEN +# undef PRIu16 +# define PRIu16 "u" +#endif +#if !defined PRIx16 || PRI_MACROS_BROKEN +# undef PRIx16 +# define PRIx16 "x" +#endif +#if !defined PRIX16 || PRI_MACROS_BROKEN +# undef PRIX16 +# define PRIX16 "X" +#endif +#if !defined PRId32 || PRI_MACROS_BROKEN +# undef PRId32 +# define PRId32 "d" +#endif +#if !defined PRIi32 || PRI_MACROS_BROKEN +# undef PRIi32 +# define PRIi32 "i" +#endif +#if !defined PRIo32 || PRI_MACROS_BROKEN +# undef PRIo32 +# define PRIo32 "o" +#endif +#if !defined PRIu32 || PRI_MACROS_BROKEN +# undef PRIu32 +# define PRIu32 "u" +#endif +#if !defined PRIx32 || PRI_MACROS_BROKEN +# undef PRIx32 +# define PRIx32 "x" +#endif +#if !defined PRIX32 || PRI_MACROS_BROKEN +# undef PRIX32 +# define PRIX32 "X" +#endif +#if !defined PRId64 || PRI_MACROS_BROKEN +# undef PRId64 +# define PRId64 (sizeof (long) == 8 ? "ld" : "lld") +#endif +#if !defined PRIi64 || PRI_MACROS_BROKEN +# undef PRIi64 +# define PRIi64 (sizeof (long) == 8 ? "li" : "lli") +#endif +#if !defined PRIo64 || PRI_MACROS_BROKEN +# undef PRIo64 +# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo") +#endif +#if !defined PRIu64 || PRI_MACROS_BROKEN +# undef PRIu64 +# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu") +#endif +#if !defined PRIx64 || PRI_MACROS_BROKEN +# undef PRIx64 +# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx") +#endif +#if !defined PRIX64 || PRI_MACROS_BROKEN +# undef PRIX64 +# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX") +#endif +#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN +# undef PRIdLEAST8 +# define PRIdLEAST8 "d" +#endif +#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN +# undef PRIiLEAST8 +# define PRIiLEAST8 "i" +#endif +#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN +# undef PRIoLEAST8 +# define PRIoLEAST8 "o" +#endif +#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN +# undef PRIuLEAST8 +# define PRIuLEAST8 "u" +#endif +#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN +# undef PRIxLEAST8 +# define PRIxLEAST8 "x" +#endif +#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN +# undef PRIXLEAST8 +# define PRIXLEAST8 "X" +#endif +#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN +# undef PRIdLEAST16 +# define PRIdLEAST16 "d" +#endif +#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN +# undef PRIiLEAST16 +# define PRIiLEAST16 "i" +#endif +#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN +# undef PRIoLEAST16 +# define PRIoLEAST16 "o" +#endif +#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN +# undef PRIuLEAST16 +# define PRIuLEAST16 "u" +#endif +#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN +# undef PRIxLEAST16 +# define PRIxLEAST16 "x" +#endif +#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN +# undef PRIXLEAST16 +# define PRIXLEAST16 "X" +#endif +#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN +# undef PRIdLEAST32 +# define PRIdLEAST32 "d" +#endif +#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN +# undef PRIiLEAST32 +# define PRIiLEAST32 "i" +#endif +#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN +# undef PRIoLEAST32 +# define PRIoLEAST32 "o" +#endif +#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN +# undef PRIuLEAST32 +# define PRIuLEAST32 "u" +#endif +#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN +# undef PRIxLEAST32 +# define PRIxLEAST32 "x" +#endif +#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN +# undef PRIXLEAST32 +# define PRIXLEAST32 "X" +#endif +#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN +# undef PRIdLEAST64 +# define PRIdLEAST64 PRId64 +#endif +#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN +# undef PRIiLEAST64 +# define PRIiLEAST64 PRIi64 +#endif +#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN +# undef PRIoLEAST64 +# define PRIoLEAST64 PRIo64 +#endif +#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN +# undef PRIuLEAST64 +# define PRIuLEAST64 PRIu64 +#endif +#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN +# undef PRIxLEAST64 +# define PRIxLEAST64 PRIx64 +#endif +#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN +# undef PRIXLEAST64 +# define PRIXLEAST64 PRIX64 +#endif +#if !defined PRIdFAST8 || PRI_MACROS_BROKEN +# undef PRIdFAST8 +# define PRIdFAST8 "d" +#endif +#if !defined PRIiFAST8 || PRI_MACROS_BROKEN +# undef PRIiFAST8 +# define PRIiFAST8 "i" +#endif +#if !defined PRIoFAST8 || PRI_MACROS_BROKEN +# undef PRIoFAST8 +# define PRIoFAST8 "o" +#endif +#if !defined PRIuFAST8 || PRI_MACROS_BROKEN +# undef PRIuFAST8 +# define PRIuFAST8 "u" +#endif +#if !defined PRIxFAST8 || PRI_MACROS_BROKEN +# undef PRIxFAST8 +# define PRIxFAST8 "x" +#endif +#if !defined PRIXFAST8 || PRI_MACROS_BROKEN +# undef PRIXFAST8 +# define PRIXFAST8 "X" +#endif +#if !defined PRIdFAST16 || PRI_MACROS_BROKEN +# undef PRIdFAST16 +# define PRIdFAST16 "d" +#endif +#if !defined PRIiFAST16 || PRI_MACROS_BROKEN +# undef PRIiFAST16 +# define PRIiFAST16 "i" +#endif +#if !defined PRIoFAST16 || PRI_MACROS_BROKEN +# undef PRIoFAST16 +# define PRIoFAST16 "o" +#endif +#if !defined PRIuFAST16 || PRI_MACROS_BROKEN +# undef PRIuFAST16 +# define PRIuFAST16 "u" +#endif +#if !defined PRIxFAST16 || PRI_MACROS_BROKEN +# undef PRIxFAST16 +# define PRIxFAST16 "x" +#endif +#if !defined PRIXFAST16 || PRI_MACROS_BROKEN +# undef PRIXFAST16 +# define PRIXFAST16 "X" +#endif +#if !defined PRIdFAST32 || PRI_MACROS_BROKEN +# undef PRIdFAST32 +# define PRIdFAST32 "d" +#endif +#if !defined PRIiFAST32 || PRI_MACROS_BROKEN +# undef PRIiFAST32 +# define PRIiFAST32 "i" +#endif +#if !defined PRIoFAST32 || PRI_MACROS_BROKEN +# undef PRIoFAST32 +# define PRIoFAST32 "o" +#endif +#if !defined PRIuFAST32 || PRI_MACROS_BROKEN +# undef PRIuFAST32 +# define PRIuFAST32 "u" +#endif +#if !defined PRIxFAST32 || PRI_MACROS_BROKEN +# undef PRIxFAST32 +# define PRIxFAST32 "x" +#endif +#if !defined PRIXFAST32 || PRI_MACROS_BROKEN +# undef PRIXFAST32 +# define PRIXFAST32 "X" +#endif +#if !defined PRIdFAST64 || PRI_MACROS_BROKEN +# undef PRIdFAST64 +# define PRIdFAST64 PRId64 +#endif +#if !defined PRIiFAST64 || PRI_MACROS_BROKEN +# undef PRIiFAST64 +# define PRIiFAST64 PRIi64 +#endif +#if !defined PRIoFAST64 || PRI_MACROS_BROKEN +# undef PRIoFAST64 +# define PRIoFAST64 PRIo64 +#endif +#if !defined PRIuFAST64 || PRI_MACROS_BROKEN +# undef PRIuFAST64 +# define PRIuFAST64 PRIu64 +#endif +#if !defined PRIxFAST64 || PRI_MACROS_BROKEN +# undef PRIxFAST64 +# define PRIxFAST64 PRIx64 +#endif +#if !defined PRIXFAST64 || PRI_MACROS_BROKEN +# undef PRIXFAST64 +# define PRIXFAST64 PRIX64 +#endif +#if !defined PRIdMAX || PRI_MACROS_BROKEN +# undef PRIdMAX +# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") +#endif +#if !defined PRIiMAX || PRI_MACROS_BROKEN +# undef PRIiMAX +# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli") +#endif +#if !defined PRIoMAX || PRI_MACROS_BROKEN +# undef PRIoMAX +# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") +#endif +#if !defined PRIuMAX || PRI_MACROS_BROKEN +# undef PRIuMAX +# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") +#endif +#if !defined PRIxMAX || PRI_MACROS_BROKEN +# undef PRIxMAX +# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") +#endif +#if !defined PRIXMAX || PRI_MACROS_BROKEN +# undef PRIXMAX +# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX") +#endif +#if !defined PRIdPTR || PRI_MACROS_BROKEN +# undef PRIdPTR +# define PRIdPTR \ + (sizeof (void *) == sizeof (long) ? "ld" : \ + sizeof (void *) == sizeof (int) ? "d" : \ + "lld") +#endif +#if !defined PRIiPTR || PRI_MACROS_BROKEN +# undef PRIiPTR +# define PRIiPTR \ + (sizeof (void *) == sizeof (long) ? "li" : \ + sizeof (void *) == sizeof (int) ? "i" : \ + "lli") +#endif +#if !defined PRIoPTR || PRI_MACROS_BROKEN +# undef PRIoPTR +# define PRIoPTR \ + (sizeof (void *) == sizeof (long) ? "lo" : \ + sizeof (void *) == sizeof (int) ? "o" : \ + "llo") +#endif +#if !defined PRIuPTR || PRI_MACROS_BROKEN +# undef PRIuPTR +# define PRIuPTR \ + (sizeof (void *) == sizeof (long) ? "lu" : \ + sizeof (void *) == sizeof (int) ? "u" : \ + "llu") +#endif +#if !defined PRIxPTR || PRI_MACROS_BROKEN +# undef PRIxPTR +# define PRIxPTR \ + (sizeof (void *) == sizeof (long) ? "lx" : \ + sizeof (void *) == sizeof (int) ? "x" : \ + "llx") +#endif +#if !defined PRIXPTR || PRI_MACROS_BROKEN +# undef PRIXPTR +# define PRIXPTR \ + (sizeof (void *) == sizeof (long) ? "lX" : \ + sizeof (void *) == sizeof (int) ? "X" : \ + "llX") +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ISO C functions. This is required by the standard + because some ISO C functions will require linking with this object + file and the name space must not be polluted. */ +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap +#endif + +/* For those losing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +# define freea(p) /* nothing */ +#else +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif + +/* For systems that distinguish between text and binary I/O. + O_BINARY is usually declared in . */ +#if !defined O_BINARY && defined _O_BINARY + /* For MSC-compatible compilers. */ +# define O_BINARY _O_BINARY +# define O_TEXT _O_TEXT +#endif +#ifdef __BEOS__ + /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ +# undef O_BINARY +# undef O_TEXT +#endif +/* On reasonable systems, binary I/O is the default. */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif + + +/* Prototypes for local functions. Needed to ensure compiler checking of + function argument counts despite of K&R C function definition syntax. */ +static const char *get_sysdep_segment_value PARAMS ((const char *name)); + + +/* We need a sign, whether a new catalog was loaded, which can be associated + with all translations. This is important if the translations are + cached by one of GCC's features. */ +int _nl_msg_cat_cntr; + + +/* Expand a system dependent string segment. Return NULL if unsupported. */ +static const char * +get_sysdep_segment_value (name) + const char *name; +{ + /* Test for an ISO C 99 section 7.8.1 format string directive. + Syntax: + P R I { d | i | o | u | x | X } + { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ + /* We don't use a table of 14 times 6 'const char *' strings here, because + data relocations cost startup time. */ + if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I') + { + if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u' + || name[3] == 'x' || name[3] == 'X') + { + if (name[4] == '8' && name[5] == '\0') + { + if (name[3] == 'd') + return PRId8; + if (name[3] == 'i') + return PRIi8; + if (name[3] == 'o') + return PRIo8; + if (name[3] == 'u') + return PRIu8; + if (name[3] == 'x') + return PRIx8; + if (name[3] == 'X') + return PRIX8; + abort (); + } + if (name[4] == '1' && name[5] == '6' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId16; + if (name[3] == 'i') + return PRIi16; + if (name[3] == 'o') + return PRIo16; + if (name[3] == 'u') + return PRIu16; + if (name[3] == 'x') + return PRIx16; + if (name[3] == 'X') + return PRIX16; + abort (); + } + if (name[4] == '3' && name[5] == '2' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId32; + if (name[3] == 'i') + return PRIi32; + if (name[3] == 'o') + return PRIo32; + if (name[3] == 'u') + return PRIu32; + if (name[3] == 'x') + return PRIx32; + if (name[3] == 'X') + return PRIX32; + abort (); + } + if (name[4] == '6' && name[5] == '4' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId64; + if (name[3] == 'i') + return PRIi64; + if (name[3] == 'o') + return PRIo64; + if (name[3] == 'u') + return PRIu64; + if (name[3] == 'x') + return PRIx64; + if (name[3] == 'X') + return PRIX64; + abort (); + } + if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A' + && name[7] == 'S' && name[8] == 'T') + { + if (name[9] == '8' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST8; + if (name[3] == 'i') + return PRIiLEAST8; + if (name[3] == 'o') + return PRIoLEAST8; + if (name[3] == 'u') + return PRIuLEAST8; + if (name[3] == 'x') + return PRIxLEAST8; + if (name[3] == 'X') + return PRIXLEAST8; + abort (); + } + if (name[9] == '1' && name[10] == '6' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST16; + if (name[3] == 'i') + return PRIiLEAST16; + if (name[3] == 'o') + return PRIoLEAST16; + if (name[3] == 'u') + return PRIuLEAST16; + if (name[3] == 'x') + return PRIxLEAST16; + if (name[3] == 'X') + return PRIXLEAST16; + abort (); + } + if (name[9] == '3' && name[10] == '2' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST32; + if (name[3] == 'i') + return PRIiLEAST32; + if (name[3] == 'o') + return PRIoLEAST32; + if (name[3] == 'u') + return PRIuLEAST32; + if (name[3] == 'x') + return PRIxLEAST32; + if (name[3] == 'X') + return PRIXLEAST32; + abort (); + } + if (name[9] == '6' && name[10] == '4' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST64; + if (name[3] == 'i') + return PRIiLEAST64; + if (name[3] == 'o') + return PRIoLEAST64; + if (name[3] == 'u') + return PRIuLEAST64; + if (name[3] == 'x') + return PRIxLEAST64; + if (name[3] == 'X') + return PRIXLEAST64; + abort (); + } + } + if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S' + && name[7] == 'T') + { + if (name[8] == '8' && name[9] == '\0') + { + if (name[3] == 'd') + return PRIdFAST8; + if (name[3] == 'i') + return PRIiFAST8; + if (name[3] == 'o') + return PRIoFAST8; + if (name[3] == 'u') + return PRIuFAST8; + if (name[3] == 'x') + return PRIxFAST8; + if (name[3] == 'X') + return PRIXFAST8; + abort (); + } + if (name[8] == '1' && name[9] == '6' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST16; + if (name[3] == 'i') + return PRIiFAST16; + if (name[3] == 'o') + return PRIoFAST16; + if (name[3] == 'u') + return PRIuFAST16; + if (name[3] == 'x') + return PRIxFAST16; + if (name[3] == 'X') + return PRIXFAST16; + abort (); + } + if (name[8] == '3' && name[9] == '2' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST32; + if (name[3] == 'i') + return PRIiFAST32; + if (name[3] == 'o') + return PRIoFAST32; + if (name[3] == 'u') + return PRIuFAST32; + if (name[3] == 'x') + return PRIxFAST32; + if (name[3] == 'X') + return PRIXFAST32; + abort (); + } + if (name[8] == '6' && name[9] == '4' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST64; + if (name[3] == 'i') + return PRIiFAST64; + if (name[3] == 'o') + return PRIoFAST64; + if (name[3] == 'u') + return PRIuFAST64; + if (name[3] == 'x') + return PRIxFAST64; + if (name[3] == 'X') + return PRIXFAST64; + abort (); + } + } + if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X' + && name[7] == '\0') + { + if (name[3] == 'd') + return PRIdMAX; + if (name[3] == 'i') + return PRIiMAX; + if (name[3] == 'o') + return PRIoMAX; + if (name[3] == 'u') + return PRIuMAX; + if (name[3] == 'x') + return PRIxMAX; + if (name[3] == 'X') + return PRIXMAX; + abort (); + } + if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R' + && name[7] == '\0') + { + if (name[3] == 'd') + return PRIdPTR; + if (name[3] == 'i') + return PRIiPTR; + if (name[3] == 'o') + return PRIoPTR; + if (name[3] == 'u') + return PRIuPTR; + if (name[3] == 'x') + return PRIxPTR; + if (name[3] == 'X') + return PRIXPTR; + abort (); + } + } + } + /* Other system dependent strings are not valid. */ + return NULL; +} + +/* Initialize the codeset dependent parts of an opened message catalog. + Return the header entry. */ +const char * +internal_function +_nl_init_domain_conv (domain_file, domain, domainbinding) + struct loaded_l10nfile *domain_file; + struct loaded_domain *domain; + struct binding *domainbinding; +{ + /* Find out about the character set the file is encoded with. + This can be found (in textual form) in the entry "". If this + entry does not exist or if this does not contain the `charset=' + information, we will assume the charset matches the one the + current locale and we don't have to perform any conversion. */ + char *nullentry; + size_t nullentrylen; + + /* Preinitialize fields, to avoid recursion during _nl_find_msg. */ + domain->codeset_cntr = + (domainbinding != NULL ? domainbinding->codeset_cntr : 0); +#ifdef _LIBC + domain->conv = (__gconv_t) -1; +#else +# if HAVE_ICONV + domain->conv = (iconv_t) -1; +# endif +#endif + domain->conv_tab = NULL; + + /* Get the header entry. */ + nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen); + + if (nullentry != NULL) + { +#if defined _LIBC || HAVE_ICONV + const char *charsetstr; + + charsetstr = strstr (nullentry, "charset="); + if (charsetstr != NULL) + { + size_t len; + char *charset; + const char *outcharset; + + charsetstr += strlen ("charset="); + len = strcspn (charsetstr, " \t\n"); + + charset = (char *) alloca (len + 1); +# if defined _LIBC || HAVE_MEMPCPY + *((char *) mempcpy (charset, charsetstr, len)) = '\0'; +# else + memcpy (charset, charsetstr, len); + charset[len] = '\0'; +# endif + + /* The output charset should normally be determined by the + locale. But sometimes the locale is not used or not correctly + set up, so we provide a possibility for the user to override + this. Moreover, the value specified through + bind_textdomain_codeset overrides both. */ + if (domainbinding != NULL && domainbinding->codeset != NULL) + outcharset = domainbinding->codeset; + else + { + outcharset = getenv ("OUTPUT_CHARSET"); + if (outcharset == NULL || outcharset[0] == '\0') + { +# ifdef _LIBC + outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string; +# else +# if HAVE_ICONV + extern const char *locale_charset PARAMS ((void)); + outcharset = locale_charset (); +# endif +# endif + } + } + +# ifdef _LIBC + /* We always want to use transliteration. */ + outcharset = norm_add_slashes (outcharset, "TRANSLIT"); + charset = norm_add_slashes (charset, NULL); + if (__gconv_open (outcharset, charset, &domain->conv, + GCONV_AVOID_NOCONV) + != __GCONV_OK) + domain->conv = (__gconv_t) -1; +# else +# if HAVE_ICONV + /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, + we want to use transliteration. */ +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ + || _LIBICONV_VERSION >= 0x0105 + if (strchr (outcharset, '/') == NULL) + { + char *tmp; + + len = strlen (outcharset); + tmp = (char *) alloca (len + 10 + 1); + memcpy (tmp, outcharset, len); + memcpy (tmp + len, "//TRANSLIT", 10 + 1); + outcharset = tmp; + + domain->conv = iconv_open (outcharset, charset); + + freea (outcharset); + } + else +# endif + domain->conv = iconv_open (outcharset, charset); +# endif +# endif + + freea (charset); + } +#endif /* _LIBC || HAVE_ICONV */ + } + + return nullentry; +} + +/* Frees the codeset dependent parts of an opened message catalog. */ +void +internal_function +_nl_free_domain_conv (domain) + struct loaded_domain *domain; +{ + if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1) + free (domain->conv_tab); + +#ifdef _LIBC + if (domain->conv != (__gconv_t) -1) + __gconv_close (domain->conv); +#else +# if HAVE_ICONV + if (domain->conv != (iconv_t) -1) + iconv_close (domain->conv); +# endif +#endif +} + +/* Load the message catalogs specified by FILENAME. If it is no valid + message catalog do nothing. */ +void +internal_function +_nl_load_domain (domain_file, domainbinding) + struct loaded_l10nfile *domain_file; + struct binding *domainbinding; +{ + int fd; + size_t size; +#ifdef _LIBC + struct stat64 st; +#else + struct stat st; +#endif + struct mo_file_header *data = (struct mo_file_header *) -1; + int use_mmap = 0; + struct loaded_domain *domain; + int revision; + const char *nullentry; + + domain_file->decided = 1; + domain_file->data = NULL; + + /* Note that it would be useless to store domainbinding in domain_file + because domainbinding might be == NULL now but != NULL later (after + a call to bind_textdomain_codeset). */ + + /* If the record does not represent a valid locale the FILENAME + might be NULL. This can happen when according to the given + specification the locale file name is different for XPG and CEN + syntax. */ + if (domain_file->filename == NULL) + return; + + /* Try to open the addressed file. */ + fd = open (domain_file->filename, O_RDONLY | O_BINARY); + if (fd == -1) + return; + + /* We must know about the size of the file. */ + if ( +#ifdef _LIBC + __builtin_expect (fstat64 (fd, &st) != 0, 0) +#else + __builtin_expect (fstat (fd, &st) != 0, 0) +#endif + || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) + || __builtin_expect (size < sizeof (struct mo_file_header), 0)) + { + /* Something went wrong. */ + close (fd); + return; + } + +#ifdef HAVE_MMAP + /* Now we are ready to load the file. If mmap() is available we try + this first. If not available or it failed we try to load it. */ + data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, + MAP_PRIVATE, fd, 0); + + if (__builtin_expect (data != (struct mo_file_header *) -1, 1)) + { + /* mmap() call was successful. */ + close (fd); + use_mmap = 1; + } +#endif + + /* If the data is not yet available (i.e. mmap'ed) we try to load + it manually. */ + if (data == (struct mo_file_header *) -1) + { + size_t to_read; + char *read_ptr; + + data = (struct mo_file_header *) malloc (size); + if (data == NULL) + return; + + to_read = size; + read_ptr = (char *) data; + do + { + long int nb = (long int) read (fd, read_ptr, to_read); + if (nb <= 0) + { +#ifdef EINTR + if (nb == -1 && errno == EINTR) + continue; +#endif + close (fd); + return; + } + read_ptr += nb; + to_read -= nb; + } + while (to_read > 0); + + close (fd); + } + + /* Using the magic number we can test whether it really is a message + catalog file. */ + if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED, + 0)) + { + /* The magic number is wrong: not a message catalog file. */ +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + return; + } + + domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); + if (domain == NULL) + return; + domain_file->data = domain; + + domain->data = (char *) data; + domain->use_mmap = use_mmap; + domain->mmap_size = size; + domain->must_swap = data->magic != _MAGIC; + domain->malloced = NULL; + + /* Fill in the information about the available tables. */ + revision = W (domain->must_swap, data->revision); + /* We support only the major revision 0. */ + switch (revision >> 16) + { + case 0: + domain->nstrings = W (domain->must_swap, data->nstrings); + domain->orig_tab = (const struct string_desc *) + ((char *) data + W (domain->must_swap, data->orig_tab_offset)); + domain->trans_tab = (const struct string_desc *) + ((char *) data + W (domain->must_swap, data->trans_tab_offset)); + domain->hash_size = W (domain->must_swap, data->hash_tab_size); + domain->hash_tab = + (domain->hash_size > 2 + ? (const nls_uint32 *) + ((char *) data + W (domain->must_swap, data->hash_tab_offset)) + : NULL); + domain->must_swap_hash_tab = domain->must_swap; + + /* Now dispatch on the minor revision. */ + switch (revision & 0xffff) + { + case 0: + domain->n_sysdep_strings = 0; + domain->orig_sysdep_tab = NULL; + domain->trans_sysdep_tab = NULL; + break; + case 1: + default: + { + nls_uint32 n_sysdep_strings; + + if (domain->hash_tab == NULL) + /* This is invalid. These minor revisions need a hash table. */ + goto invalid; + + n_sysdep_strings = + W (domain->must_swap, data->n_sysdep_strings); + if (n_sysdep_strings > 0) + { + nls_uint32 n_sysdep_segments; + const struct sysdep_segment *sysdep_segments; + const char **sysdep_segment_values; + const nls_uint32 *orig_sysdep_tab; + const nls_uint32 *trans_sysdep_tab; + size_t memneed; + char *mem; + struct sysdep_string_desc *inmem_orig_sysdep_tab; + struct sysdep_string_desc *inmem_trans_sysdep_tab; + nls_uint32 *inmem_hash_tab; + unsigned int i; + + /* Get the values of the system dependent segments. */ + n_sysdep_segments = + W (domain->must_swap, data->n_sysdep_segments); + sysdep_segments = (const struct sysdep_segment *) + ((char *) data + + W (domain->must_swap, data->sysdep_segments_offset)); + sysdep_segment_values = + alloca (n_sysdep_segments * sizeof (const char *)); + for (i = 0; i < n_sysdep_segments; i++) + { + const char *name = + (char *) data + + W (domain->must_swap, sysdep_segments[i].offset); + nls_uint32 namelen = + W (domain->must_swap, sysdep_segments[i].length); + + if (!(namelen > 0 && name[namelen - 1] == '\0')) + { + freea (sysdep_segment_values); + goto invalid; + } + + sysdep_segment_values[i] = get_sysdep_segment_value (name); + } + + orig_sysdep_tab = (const nls_uint32 *) + ((char *) data + + W (domain->must_swap, data->orig_sysdep_tab_offset)); + trans_sysdep_tab = (const nls_uint32 *) + ((char *) data + + W (domain->must_swap, data->trans_sysdep_tab_offset)); + + /* Compute the amount of additional memory needed for the + system dependent strings and the augmented hash table. */ + memneed = 2 * n_sysdep_strings + * sizeof (struct sysdep_string_desc) + + domain->hash_size * sizeof (nls_uint32); + for (i = 0; i < 2 * n_sysdep_strings; i++) + { + const struct sysdep_string *sysdep_string = + (const struct sysdep_string *) + ((char *) data + + W (domain->must_swap, + i < n_sysdep_strings + ? orig_sysdep_tab[i] + : trans_sysdep_tab[i - n_sysdep_strings])); + size_t need = 0; + const struct segment_pair *p = sysdep_string->segments; + + if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END) + for (p = sysdep_string->segments;; p++) + { + nls_uint32 sysdepref; + + need += W (domain->must_swap, p->segsize); + + sysdepref = W (domain->must_swap, p->sysdepref); + if (sysdepref == SEGMENTS_END) + break; + + if (sysdepref >= n_sysdep_segments) + { + /* Invalid. */ + freea (sysdep_segment_values); + goto invalid; + } + + need += strlen (sysdep_segment_values[sysdepref]); + } + + memneed += need; + } + + /* Allocate additional memory. */ + mem = (char *) malloc (memneed); + if (mem == NULL) + goto invalid; + + domain->malloced = mem; + inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem; + mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); + inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem; + mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); + inmem_hash_tab = (nls_uint32 *) mem; + mem += domain->hash_size * sizeof (nls_uint32); + + /* Compute the system dependent strings. */ + for (i = 0; i < 2 * n_sysdep_strings; i++) + { + const struct sysdep_string *sysdep_string = + (const struct sysdep_string *) + ((char *) data + + W (domain->must_swap, + i < n_sysdep_strings + ? orig_sysdep_tab[i] + : trans_sysdep_tab[i - n_sysdep_strings])); + const char *static_segments = + (char *) data + + W (domain->must_swap, sysdep_string->offset); + const struct segment_pair *p = sysdep_string->segments; + + /* Concatenate the segments, and fill + inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and + inmem_trans_sysdep_tab[i-n_sysdep_strings] (for + i >= n_sysdep_strings). */ + + if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END) + { + /* Only one static segment. */ + inmem_orig_sysdep_tab[i].length = + W (domain->must_swap, p->segsize); + inmem_orig_sysdep_tab[i].pointer = static_segments; + } + else + { + inmem_orig_sysdep_tab[i].pointer = mem; + + for (p = sysdep_string->segments;; p++) + { + nls_uint32 segsize = + W (domain->must_swap, p->segsize); + nls_uint32 sysdepref = + W (domain->must_swap, p->sysdepref); + size_t n; + + if (segsize > 0) + { + memcpy (mem, static_segments, segsize); + mem += segsize; + static_segments += segsize; + } + + if (sysdepref == SEGMENTS_END) + break; + + n = strlen (sysdep_segment_values[sysdepref]); + memcpy (mem, sysdep_segment_values[sysdepref], n); + mem += n; + } + + inmem_orig_sysdep_tab[i].length = + mem - inmem_orig_sysdep_tab[i].pointer; + } + } + + /* Compute the augmented hash table. */ + for (i = 0; i < domain->hash_size; i++) + inmem_hash_tab[i] = + W (domain->must_swap_hash_tab, domain->hash_tab[i]); + for (i = 0; i < n_sysdep_strings; i++) + { + const char *msgid = inmem_orig_sysdep_tab[i].pointer; + nls_uint32 hash_val = hash_string (msgid); + nls_uint32 idx = hash_val % domain->hash_size; + nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); + + for (;;) + { + if (inmem_hash_tab[idx] == 0) + { + /* Hash table entry is empty. Use it. */ + inmem_hash_tab[idx] = 1 + domain->nstrings + i; + break; + } + + if (idx >= domain->hash_size - incr) + idx -= domain->hash_size - incr; + else + idx += incr; + } + } + + freea (sysdep_segment_values); + + domain->n_sysdep_strings = n_sysdep_strings; + domain->orig_sysdep_tab = inmem_orig_sysdep_tab; + domain->trans_sysdep_tab = inmem_trans_sysdep_tab; + + domain->hash_tab = inmem_hash_tab; + domain->must_swap_hash_tab = 0; + } + else + { + domain->n_sysdep_strings = 0; + domain->orig_sysdep_tab = NULL; + domain->trans_sysdep_tab = NULL; + } + } + break; + } + break; + default: + /* This is an invalid revision. */ + invalid: + /* This is an invalid .mo file. */ + if (domain->malloced) + free (domain->malloced); +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + free (domain); + domain_file->data = NULL; + return; + } + + /* Now initialize the character set converter from the character set + the file is encoded with (found in the header entry) to the domain's + specified character set or the locale's character set. */ + nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding); + + /* Also look for a plural specification. */ + EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); +} + + +#ifdef _LIBC +void +internal_function +_nl_unload_domain (domain) + struct loaded_domain *domain; +{ + if (domain->plural != &__gettext_germanic_plural) + __gettext_free_exp (domain->plural); + + _nl_free_domain_conv (domain); + + if (domain->malloced) + free (domain->malloced); + +# ifdef _POSIX_MAPPED_FILES + if (domain->use_mmap) + munmap ((caddr_t) domain->data, domain->mmap_size); + else +# endif /* _POSIX_MAPPED_FILES */ + free ((void *) domain->data); + + free (domain); +} +#endif diff --git a/linphone/intl/localealias.c b/linphone/intl/localealias.c new file mode 100644 index 000000000..456e41e37 --- /dev/null +++ b/linphone/intl/localealias.c @@ -0,0 +1,419 @@ +/* Handle aliases for locale names. + Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Tell glibc's to provide a prototype for mempcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#if defined _LIBC || defined HAVE___FSETLOCKING +# include +#endif +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#include +#include + +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define strcasecmp __strcasecmp + +# ifndef mempcpy +# define mempcpy __mempcpy +# endif +# define HAVE_MEMPCPY 1 +# define HAVE___FSETLOCKING 1 + +/* We need locking here since we can be called from different places. */ +# include + +__libc_lock_define_initialized (static, lock); +#endif + +#ifndef internal_function +# define internal_function +#endif + +/* Some optimizations for glibc. */ +#ifdef _LIBC +# define FEOF(fp) feof_unlocked (fp) +# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp) +#else +# define FEOF(fp) feof (fp) +# define FGETS(buf, n, fp) fgets (buf, n, fp) +#endif + +/* For those losing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +# define freea(p) /* nothing */ +#else +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif + +#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED +# undef fgets +# define fgets(buf, len, s) fgets_unlocked (buf, len, s) +#endif +#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED +# undef feof +# define feof(s) feof_unlocked (s) +#endif + + +struct alias_map +{ + const char *alias; + const char *value; +}; + + +static char *string_space; +static size_t string_space_act; +static size_t string_space_max; +static struct alias_map *map; +static size_t nmap; +static size_t maxmap; + + +/* Prototypes for local functions. */ +static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) + internal_function; +static int extend_alias_table PARAMS ((void)); +static int alias_compare PARAMS ((const struct alias_map *map1, + const struct alias_map *map2)); + + +const char * +_nl_expand_alias (name) + const char *name; +{ + static const char *locale_alias_path; + struct alias_map *retval; + const char *result = NULL; + size_t added; + +#ifdef _LIBC + __libc_lock_lock (lock); +#endif + + if (locale_alias_path == NULL) + locale_alias_path = LOCALE_ALIAS_PATH; + + do + { + struct alias_map item; + + item.alias = name; + + if (nmap > 0) + retval = (struct alias_map *) bsearch (&item, map, nmap, + sizeof (struct alias_map), + (int (*) PARAMS ((const void *, + const void *)) + ) alias_compare); + else + retval = NULL; + + /* We really found an alias. Return the value. */ + if (retval != NULL) + { + result = retval->value; + break; + } + + /* Perhaps we can find another alias file. */ + added = 0; + while (added == 0 && locale_alias_path[0] != '\0') + { + const char *start; + + while (locale_alias_path[0] == PATH_SEPARATOR) + ++locale_alias_path; + start = locale_alias_path; + + while (locale_alias_path[0] != '\0' + && locale_alias_path[0] != PATH_SEPARATOR) + ++locale_alias_path; + + if (start < locale_alias_path) + added = read_alias_file (start, locale_alias_path - start); + } + } + while (added != 0); + +#ifdef _LIBC + __libc_lock_unlock (lock); +#endif + + return result; +} + + +static size_t +internal_function +read_alias_file (fname, fname_len) + const char *fname; + int fname_len; +{ + FILE *fp; + char *full_fname; + size_t added; + static const char aliasfile[] = "/locale.alias"; + + full_fname = (char *) alloca (fname_len + sizeof aliasfile); +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (full_fname, fname, fname_len), + aliasfile, sizeof aliasfile); +#else + memcpy (full_fname, fname, fname_len); + memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); +#endif + + fp = fopen (full_fname, "r"); + freea (full_fname); + if (fp == NULL) + return 0; + +#ifdef HAVE___FSETLOCKING + /* No threads present. */ + __fsetlocking (fp, FSETLOCKING_BYCALLER); +#endif + + added = 0; + while (!FEOF (fp)) + { + /* It is a reasonable approach to use a fix buffer here because + a) we are only interested in the first two fields + b) these fields must be usable as file names and so must not + be that long + */ + char buf[BUFSIZ]; + char *alias; + char *value; + char *cp; + + if (FGETS (buf, sizeof buf, fp) == NULL) + /* EOF reached. */ + break; + + /* Possibly not the whole line fits into the buffer. Ignore + the rest of the line. */ + if (strchr (buf, '\n') == NULL) + { + char altbuf[BUFSIZ]; + do + if (FGETS (altbuf, sizeof altbuf, fp) == NULL) + /* Make sure the inner loop will be left. The outer loop + will exit at the `feof' test. */ + break; + while (strchr (altbuf, '\n') == NULL); + } + + cp = buf; + /* Ignore leading white space. */ + while (isspace ((unsigned char) cp[0])) + ++cp; + + /* A leading '#' signals a comment line. */ + if (cp[0] != '\0' && cp[0] != '#') + { + alias = cp++; + while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) + ++cp; + /* Terminate alias name. */ + if (cp[0] != '\0') + *cp++ = '\0'; + + /* Now look for the beginning of the value. */ + while (isspace ((unsigned char) cp[0])) + ++cp; + + if (cp[0] != '\0') + { + size_t alias_len; + size_t value_len; + + value = cp++; + while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) + ++cp; + /* Terminate value. */ + if (cp[0] == '\n') + { + /* This has to be done to make the following test + for the end of line possible. We are looking for + the terminating '\n' which do not overwrite here. */ + *cp++ = '\0'; + *cp = '\n'; + } + else if (cp[0] != '\0') + *cp++ = '\0'; + + if (nmap >= maxmap) + if (__builtin_expect (extend_alias_table (), 0)) + return added; + + alias_len = strlen (alias) + 1; + value_len = strlen (value) + 1; + + if (string_space_act + alias_len + value_len > string_space_max) + { + /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); + char *new_pool = (char *) realloc (string_space, new_size); + if (new_pool == NULL) + return added; + + if (__builtin_expect (string_space != new_pool, 0)) + { + size_t i; + + for (i = 0; i < nmap; i++) + { + map[i].alias += new_pool - string_space; + map[i].value += new_pool - string_space; + } + } + + string_space = new_pool; + string_space_max = new_size; + } + + map[nmap].alias = memcpy (&string_space[string_space_act], + alias, alias_len); + string_space_act += alias_len; + + map[nmap].value = memcpy (&string_space[string_space_act], + value, value_len); + string_space_act += value_len; + + ++nmap; + ++added; + } + } + } + + /* Should we test for ferror()? I think we have to silently ignore + errors. --drepper */ + fclose (fp); + + if (added > 0) + qsort (map, nmap, sizeof (struct alias_map), + (int (*) PARAMS ((const void *, const void *))) alias_compare); + + return added; +} + + +static int +extend_alias_table () +{ + size_t new_size; + struct alias_map *new_map; + + new_size = maxmap == 0 ? 100 : 2 * maxmap; + new_map = (struct alias_map *) realloc (map, (new_size + * sizeof (struct alias_map))); + if (new_map == NULL) + /* Simply don't extend: we don't have any more core. */ + return -1; + + map = new_map; + maxmap = new_size; + return 0; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + if (string_space != NULL) + free (string_space); + if (map != NULL) + free (map); +} +text_set_element (__libc_subfreeres, free_mem); +#endif + + +static int +alias_compare (map1, map2) + const struct alias_map *map1; + const struct alias_map *map2; +{ +#if defined _LIBC || defined HAVE_STRCASECMP + return strcasecmp (map1->alias, map2->alias); +#else + const unsigned char *p1 = (const unsigned char *) map1->alias; + const unsigned char *p2 = (const unsigned char *) map2->alias; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + /* I know this seems to be odd but the tolower() function in + some systems libc cannot handle nonalpha characters. */ + c1 = isupper (*p1) ? tolower (*p1) : *p1; + c2 = isupper (*p2) ? tolower (*p2) : *p2; + if (c1 == '\0') + break; + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +#endif +} diff --git a/linphone/intl/po2tbl.sed.in b/linphone/intl/po2tbl.sed.in new file mode 100644 index 000000000..b3bcca4d7 --- /dev/null +++ b/linphone/intl/po2tbl.sed.in @@ -0,0 +1,102 @@ +# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +1 { + i\ +/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ +\ +#if HAVE_CONFIG_H\ +# include \ +#endif\ +\ +#include "libgettext.h"\ +\ +const struct _msg_ent _msg_tbl[] = { + h + s/.*/0/ + x +} +# +# Write msgid entries in C array form. +# +/^msgid/ { + s/msgid[ ]*\(".*"\)/ {\1/ + tb +# Append the next line + :b + N +# Look whether second part is continuation line. + s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ +# Yes, then branch. + ta +# Because we assume that the input file correctly formed the line +# just read cannot be again be a msgid line. So it's safe to ignore +# it. + s/\(.*\)\n.*/\1/ + bc +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ +# Some buggy seds do not clear the `successful substitution since last ``t''' +# flag on `N', so we do a `t' here to clear it. + tb +# Not reached + :c + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)\n\([0-9]*\)/\1, \2},/ + s/\(.*\)"$/\1/ + p +} +# +# Last line. +# +$ { + i\ +};\ + + g + s/0*\(.*\)/int _msg_tbl_length = \1;/p +} +d diff --git a/linphone/intl/textdomain.c b/linphone/intl/textdomain.c new file mode 100644 index 000000000..f259c696d --- /dev/null +++ b/linphone/intl/textdomain.c @@ -0,0 +1,142 @@ +/* Implementation of the textdomain(3) function. + Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif +#include "gettextP.h" + +#ifdef _LIBC +/* We have to handle multi-threaded applications. */ +# include +#else +/* Provide dummy implementation if this is outside glibc. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +#endif + +/* The internal variables in the standalone libintl.a must have different + names than the internal variables in GNU libc, otherwise programs + using libintl.a cannot be linked statically. */ +#if !defined _LIBC +# define _nl_default_default_domain libintl_nl_default_default_domain +# define _nl_current_default_domain libintl_nl_current_default_domain +#endif + +/* @@ end of prolog @@ */ + +/* Name of the default text domain. */ +extern const char _nl_default_default_domain[] attribute_hidden; + +/* Default text domain in which entries for gettext(3) are to be found. */ +extern const char *_nl_current_default_domain attribute_hidden; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define TEXTDOMAIN __textdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define TEXTDOMAIN libintl_textdomain +#endif + +/* Lock variable to protect the global data in the gettext implementation. */ +__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +char * +TEXTDOMAIN (domainname) + const char *domainname; +{ + char *new_domain; + char *old_domain; + + /* A NULL pointer requests the current setting. */ + if (domainname == NULL) + return (char *) _nl_current_default_domain; + + __libc_rwlock_wrlock (_nl_state_lock); + + old_domain = (char *) _nl_current_default_domain; + + /* If domain name is the null string set to default domain "messages". */ + if (domainname[0] == '\0' + || strcmp (domainname, _nl_default_default_domain) == 0) + { + _nl_current_default_domain = _nl_default_default_domain; + new_domain = (char *) _nl_current_default_domain; + } + else if (strcmp (domainname, old_domain) == 0) + /* This can happen and people will use it to signal that some + environment variable changed. */ + new_domain = old_domain; + else + { + /* If the following malloc fails `_nl_current_default_domain' + will be NULL. This value will be returned and so signals we + are out of core. */ +#if defined _LIBC || defined HAVE_STRDUP + new_domain = strdup (domainname); +#else + size_t len = strlen (domainname) + 1; + new_domain = (char *) malloc (len); + if (new_domain != NULL) + memcpy (new_domain, domainname, len); +#endif + + if (new_domain != NULL) + _nl_current_default_domain = new_domain; + } + + /* We use this possibility to signal a change of the loaded catalogs + since this is most likely the case and there is no other easy we + to do it. Do it only when the call was successful. */ + if (new_domain != NULL) + { + ++_nl_msg_cat_cntr; + + if (old_domain != new_domain && old_domain != _nl_default_default_domain) + free (old_domain); + } + + __libc_rwlock_unlock (_nl_state_lock); + + return new_domain; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__textdomain, textdomain); +#endif diff --git a/linphone/intl/xopen-msg.sed b/linphone/intl/xopen-msg.sed new file mode 100644 index 000000000..b19c0bbd0 --- /dev/null +++ b/linphone/intl/xopen-msg.sed @@ -0,0 +1,104 @@ +# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# We copy all comments into the .msg file. Perhaps they can help. +# +/^#/ s/^#[ ]*/$ /p +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { +# Does not work now +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/ + p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/\1/ + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x +# Bring the line in the format ` ' + G + s/^[^\n]*$/& / + s/\(.*\)\n\([0-9]*\)/\2 \1/ +# Clear flag from last substitution. + tb +# Append the next line. + :b + N +# Look whether second part is a continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that `D' includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use the sed command `D' here + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/linphone/intltool-extract.in b/linphone/intltool-extract.in new file mode 100644 index 000000000..256a959a1 --- /dev/null +++ b/linphone/intltool-extract.in @@ -0,0 +1,325 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Extractor +# +# Copyright (C) 2000-2001 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Darin Adler +# + +## Release information +my $PROGRAM = "intltool-extract"; +my $PACKAGE = "intltool"; +my $VERSION = "0.22"; + +## Loaded modules +use strict; +use File::Basename; +use Getopt::Long; + +## Scalars used by the option stuff +my $TYPE_ARG = "0"; +my $LOCAL_ARG = "0"; +my $HELP_ARG = "0"; +my $VERSION_ARG = "0"; +my $UPDATE_ARG = "0"; +my $QUIET_ARG = "0"; + +my $FILE; +my $OUTFILE; + +my $gettext_type = ""; +my $input; +my %messages = (); + +## Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +## Always print first +$| = 1; + +## Handle options +GetOptions ( + "type=s" => \$TYPE_ARG, + "local|l" => \$LOCAL_ARG, + "help|h" => \$HELP_ARG, + "version|v" => \$VERSION_ARG, + "update" => \$UPDATE_ARG, + "quiet|q" => \$QUIET_ARG, + ) or &error; + +&split_on_argument; + + +## Check for options. +## This section will check for the different options. + +sub split_on_argument { + + if ($VERSION_ARG) { + &version; + + } elsif ($HELP_ARG) { + &help; + + } elsif ($LOCAL_ARG) { + &place_local; + &extract; + + } elsif ($UPDATE_ARG) { + &place_normal; + &extract; + + } elsif (@ARGV > 0) { + &place_normal; + &message; + &extract; + + } else { + &help; + + } +} + +sub place_normal { + $FILE = $ARGV[0]; + $OUTFILE = "$FILE.h"; +} + +sub place_local { + $OUTFILE = fileparse($FILE, ()); + if (!-e "tmp/") { + system("mkdir tmp/"); + } + $OUTFILE = "./tmp/$OUTFILE.h" +} + +sub determine_type { + if ($TYPE_ARG =~ /^gettext\/(.*)/) { + $gettext_type=$1 + } +} + +## Sub for printing release information +sub version{ + print "${PROGRAM} (${PACKAGE}) $VERSION\n"; + print "Copyright (C) 2000 Free Software Foundation, Inc.\n"; + print "Written by Kenneth Christiansen, 2000.\n\n"; + print "This is free software; see the source for copying conditions. There is NO\n"; + print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"; + exit; +} + +## Sub for printing usage information +sub help{ + print "Usage: ${PROGRAM} [FILENAME] [OPTIONS] ...\n"; + print "Generates a header file from an xml source file.\n\nGrabs all strings "; + print "between <_translatable_node> and it's end tag,\nwhere tag are all allowed "; + print "xml tags. Read the docs for more info.\n\n"; + print " -v, --version shows the version\n"; + print " -h, --help shows this help page\n"; + print " -q, --quiet quiet mode\n"; + print "\nReport bugs to .\n"; + exit; +} + +## Sub for printing error messages +sub error{ + print "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + +sub message { + print "Generating C format header file for translation.\n"; +} + +sub extract { + &determine_type; + + &convert ($FILE); + + open OUT, ">$OUTFILE"; + &msg_write; + close OUT; + + print "Wrote $OUTFILE\n" unless $QUIET_ARG; +} + +sub convert($) { + + ## Reading the file + { + local (*IN); + local $/; #slurp mode + open (IN, "<$FILE") || die "can't open $FILE: $!"; + $input = ; + } + + &type_ini if $gettext_type eq "ini"; + &type_keys if $gettext_type eq "keys"; + &type_xml if $gettext_type eq "xml"; + &type_glade if $gettext_type eq "glade"; + &type_scheme if $gettext_type eq "scheme"; + &type_schemas if $gettext_type eq "schemas"; +} + +sub entity_decode_minimal +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + + return $_; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/<//g; + + return $_; +} + +sub escape_char +{ + return '\"' if $_ eq '"'; + return '\n' if $_ eq "\n"; + return '\\' if $_ eq '\\'; + + return $_; +} + +sub escape +{ + my ($string) = @_; + return join "", map &escape_char, split //, $string; +} + +sub type_ini { + ### For generic translatable desktop files ### + while ($input =~ /^_.*=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_keys { + ### For generic translatable mime/keys files ### + while ($input =~ /^\s*_\w+=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_xml { + ### For generic translatable XML files ### + + while ($input =~ /\s_$w+=\"([^"]+)\"/sg) { # " + $messages{entity_decode_minimal($1)} = []; + } + + while ($input =~ /<_($w+)>(.+?)<\/_\1>/sg) { + $_ = $2; + s/\s+/ /g; + s/^ //; + s/ $//; + $messages{entity_decode_minimal($_)} = []; + } +} + +sub type_schemas { + ### For schemas XML files ### + + # FIXME: We should handle escaped < (less than) + while ($input =~ /<(short|long)>([^<]+)<\/\1>/sg) { + $_ = $2; + s/\s+/ /g; + s/^ //; + s/ $//; + $messages{entity_decode_minimal($_)} = []; + } +} + +sub type_glade { + ### For translatable Glade XML files ### + + my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message"; + + while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) { + # Glade sometimes uses tags that normally mark translatable things for + # little bits of non-translatable content. We work around this by not + # translating strings that only includes something like label4 or window1. + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/; + } + + while ($input =~ /(..[^<]*)<\/items>/sg) { + for my $item (split (/\n/, $1)) { + $messages{entity_decode($item)} = []; + } + } + + ## handle new glade files + while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"[^>]*>([^<]+)<\/\1>/sg) { + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/; + } + while ($input =~ /]*)"\s+description="([^>]+)"\/>/sg) { + $messages{entity_decode_minimal($2)} = []; + } +} + +sub type_scheme { + while ($input =~ /_\(?"((?:[^"\\]+|\\.)*)"\)?/sg) { + $messages{$1} = []; + } +} + +sub msg_write { + for my $message (sort keys %messages) { + print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/; + + my @lines = split (/\n/, $message); + for (my $n = 0; $n < @lines; $n++) { + if ($n == 0) { + print OUT "char *s = N_(\""; + } else { + print OUT " \""; + } + + print OUT escape($lines[$n]); + + if ($n < @lines - 1) { + print OUT "\\n\"\n"; + } else { + print OUT "\");\n"; + } + } + } +} + diff --git a/linphone/intltool-merge.in b/linphone/intltool-merge.in new file mode 100644 index 000000000..fd35cfdef --- /dev/null +++ b/linphone/intltool-merge.in @@ -0,0 +1,657 @@ +#!@INTLTOOL_PERL@ -w + +# +# The Intltool Message Merger +# +# Copyright (C) 2000, 2002 Free Software Foundation. +# Copyright (C) 2000, 2001 Eazel, Inc +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Maciej Stachowiak +# Kenneth Christiansen +# Darin Adler +# +# Proper XML UTF-8'ification written by Cyrille Chepelov +# + +## Release information +my $PROGRAM = "intltool-merge"; +my $PACKAGE = "intltool"; +my $VERSION = "0.22"; + +## Loaded modules +use strict; +use Getopt::Long; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $BA_STYLE_ARG = 0; +my $XML_STYLE_ARG = 0; +my $KEYS_STYLE_ARG = 0; +my $DESKTOP_STYLE_ARG = 0; +my $SCHEMAS_STYLE_ARG = 0; +my $QUIET_ARG = 0; +my $PASS_THROUGH_ARG = 0; +my $UTF8_ARG = 0; +my $cache_file; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "quiet|q" => \$QUIET_ARG, + "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility + "ba-style|b" => \$BA_STYLE_ARG, + "xml-style|x" => \$XML_STYLE_ARG, + "keys-style|k" => \$KEYS_STYLE_ARG, + "desktop-style|d" => \$DESKTOP_STYLE_ARG, + "schemas-style|s" => \$SCHEMAS_STYLE_ARG, + "pass-through|p" => \$PASS_THROUGH_ARG, + "utf8|u" => \$UTF8_ARG, + "cache|c=s" => \$cache_file + ) or &error; + +my $PO_DIR; +my $FILE; +my $OUTFILE; + +my %po_files_by_lang = (); +my %translations = (); + +# Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +# XML quoted string contents +my $q = "[^\\\"]*"; + +## Check for options. + +if ($VERSION_ARG) { + &print_version; +} elsif ($HELP_ARG) { + &print_help; +} elsif ($BA_STYLE_ARG && @ARGV > 2) { + &preparation; + &print_message; + &ba_merge_translations; + &finalize; +} elsif ($XML_STYLE_ARG && @ARGV > 2) { + &utf8_sanity_check; + &preparation; + &print_message; + &xml_merge_translations; + &finalize; +} elsif ($KEYS_STYLE_ARG && @ARGV > 2) { + &utf8_sanity_check; + &preparation; + &print_message; + &keys_merge_translations; + &finalize; +} elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) { + &preparation; + &print_message; + &desktop_merge_translations; + &finalize; +} elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) { + &preparation; + &print_message; + &schemas_merge_translations; + &finalize; +} else { + &print_help; +} + +exit; + +## Sub for printing release information +sub print_version +{ + print "${PROGRAM} (${PACKAGE}) ${VERSION}\n"; + print "Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.\n\n"; + print "Copyright (C) 2000-2002 Free Software Foundation, Inc.\n"; + print "Copyright (C) 2000-2001 Eazel, Inc.\n"; + print "This is free software; see the source for copying conditions. There is NO\n"; + print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"; + exit; +} + +## Sub for printing usage information +sub print_help +{ + print "Usage: ${PROGRAM} [OPTIONS] PO_DIRECTORY FILENAME OUTPUT_FILE\n"; + print "Generates an output file that includes translated versions of some attributes,\n"; + print "from an untranslated source and a po directory that includes translations.\n\n"; + print " -b, --ba-style includes translations in the bonobo-activation style\n"; + print " -d, --desktop-style includes translations in the desktop style\n"; + print " -k, --keys-style includes translations in the keys style\n"; + print " -s, --schemas-style includes translations in the schemas style\n"; + print " -x, --xml-style includes translations in the standard xml style\n"; + print " -u, --utf8 convert all strings to UTF-8 before merging\n"; + print " -p, --pass-through use strings as found in .po files, without\n"; + print " conversion (STRONGLY unrecommended with -x)\n"; + print " -q, --quiet suppress most messages\n"; + print " --help display this help and exit\n"; + print " --version output version information and exit\n"; + print "\nReport bugs to bugzilla.gnome.org, module intltool, or contact us through \n"; + print ".\n"; + exit; +} + + +## Sub for printing error messages +sub print_error +{ + print "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + + +sub print_message +{ + print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; +} + + +sub preparation +{ + $PO_DIR = $ARGV[0]; + $FILE = $ARGV[1]; + $OUTFILE = $ARGV[2]; + + &gather_po_files; + &get_translation_database; +} + +# General-purpose code for looking up translations in .po files + +sub po_file2lang +{ + my ($tmp) = @_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub gather_po_files +{ + for my $po_file (glob "$PO_DIR/*.po") { + $po_files_by_lang{po_file2lang($po_file)} = $po_file; + } +} + +sub get_po_encoding +{ + my ($in_po_file) = @_; + my $encoding = ""; + + open IN_PO_FILE, $in_po_file or die; + while () { + ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" + if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) { + $encoding = $1; + last; + } + } + close IN_PO_FILE; + + if (!$encoding) { + print "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n"; + $encoding = "ISO-8859-1"; + } + return $encoding +} + +sub utf8_sanity_check +{ + if (!$UTF8_ARG) { + if (!$PASS_THROUGH_ARG) { + $PASS_THROUGH_ARG="1"; + } + } +} + +sub get_translation_database +{ + if ($cache_file) { + &get_cached_translation_database; + } else { + &create_translation_database; + } +} + +sub get_newest_po_age +{ + my $newest_age; + + foreach my $file (values %po_files_by_lang) { + my $file_age = -M $file; + $newest_age = $file_age if !$newest_age || $file_age < $newest_age; + } + + return $newest_age; +} + +sub create_cache +{ + print "Generating and caching the translation database\n" unless $QUIET_ARG; + + &create_translation_database; + + open CACHE, ">$cache_file" || die; + print CACHE join "\x01", %translations; + close CACHE; +} + +sub load_cache +{ + print "Found cached translation database\n" unless $QUIET_ARG; + + my $contents; + open CACHE, "<$cache_file" || die; + { + local $/; + $contents = ; + } + close CACHE; + %translations = split "\x01", $contents; +} + +sub get_cached_translation_database +{ + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) { + if ($cache_file_age <= &get_newest_po_age) { + &load_cache; + return; + } + print "Found too-old cached translation database\n" unless $QUIET_ARG; + } + + &create_cache; +} + +sub create_translation_database +{ + for my $lang (keys %po_files_by_lang) { + my $po_file = $po_files_by_lang{$lang}; + + if ($UTF8_ARG) { + my $encoding = get_po_encoding ($po_file); + if (lc $encoding eq "utf-8") { + open PO_FILE, "<$po_file"; + } else { + my $iconv = $ENV{"INTLTOOL_ICONV"} || "iconv"; + open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; + } + } else { + open PO_FILE, "<$po_file"; + } + + my $nextfuzzy = 0; + my $inmsgid = 0; + my $inmsgstr = 0; + my $msgid = ""; + my $msgstr = ""; + while () { + $nextfuzzy = 1 if /^#, fuzzy/; + if (/^msgid "((\\.|[^\\])*)"/ ) { + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + $msgid = ""; + $msgstr = ""; + + if ($nextfuzzy) { + $inmsgid = 0; + } else { + $msgid = unescape_po_string($1); + $inmsgid = 1; + } + $inmsgstr = 0; + $nextfuzzy = 0; + } + if (/^msgstr "((\\.|[^\\])*)"/) { + $msgstr = unescape_po_string($1); + $inmsgstr = 1; + $inmsgid = 0; + } + if (/^"((\\.|[^\\])*)"/) { + $msgid .= unescape_po_string($1) if $inmsgid; + $msgstr .= unescape_po_string($1) if $inmsgstr; + } + } + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + } +} + +sub finalize +{ +} + +sub unescape_one_sequence +{ + my ($sequence) = @_; + + return "\\" if $sequence eq "\\\\"; + return "\"" if $sequence eq "\\\""; + + # gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal), + # \xXX (hex) and has a comment saying they want to handle \u and \U. + + return $sequence; +} + +sub unescape_po_string +{ + my ($string) = @_; + + $string =~ s/(\\.)/unescape_one_sequence($1)/eg; + + return $string; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + + return $_; +} + +sub entity_encode +{ + my ($pre_encoded) = @_; + + my @list_of_chars = unpack ('C*', $pre_encoded); + + if ($PASS_THROUGH_ARG) { + return join ('', map (&entity_encode_int_even_high_bit, @list_of_chars)); + } else { + return join ('', map (&entity_encode_int_minimalist, @list_of_chars)); + } +} + +sub entity_encode_int_minimalist +{ + return """ if $_ == 34; + return "&" if $_ == 38; + return "'" if $_ == 39; + return chr $_; +} + +sub entity_encode_int_even_high_bit +{ + if ($_ > 127 || $_ == 34 || $_ == 38 || $_ == 39) { + # the ($_ > 127) should probably be removed + return "&#" . $_ . ";"; + } else { + return chr $_; + } +} + +sub entity_encoded_translation +{ + my ($lang, $string) = @_; + + my $translation = $translations{$lang, $string}; + return $string if !$translation; + return entity_encode ($translation); +} + +## XML (bonobo-activation specific) merge code + +sub ba_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; + + while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) { + print OUTPUT $1; + + my $node = $2 . "\n"; + + my @strings = (); + $_ = $node; + while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { + push @strings, entity_decode($3); + } + print OUTPUT; + + my %langs; + for my $string (@strings) { + for my $lang (keys %po_files_by_lang) { + $langs{$lang} = 1 if $translations{$lang, $string}; + } + } + + for my $lang (sort keys %langs) { + $_ = $node; + s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; + s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; + print OUTPUT; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + + +## XML (non-bonobo-activation) merge code + +sub xml_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + # Support for <_foo>blah style translations. + while ($source =~ s|^(.*?)([ \t]*)<\s*_($w+)\s*>(.*?)<\s*/_\3\s*>([ \t]*\n)?||s) { + print OUTPUT $1; + + my $spaces = $2; + my $tag = $3; + my $string = $4; + + print OUTPUT "$spaces<$tag>$string\n"; + + $string =~ s/\s+/ /g; + $string =~ s/^ //; + $string =~ s/ $//; + $string = entity_decode($string); + + for my $lang (sort keys %po_files_by_lang) { + my $translation = $translations{$lang, $string}; + next if !$translation; + $translation = entity_encode($translation); + print OUTPUT "$spaces<$tag xml:lang=\"$lang\">$translation\n"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub keys_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () { + if (s/^(\s*)_(\w+=(.*))/$1$2/) { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/[$lang]$1=$translation/; + print OUTPUT; + } + } else { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub desktop_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () { + if (s/^(\s*)_(\w+=(.*))/$1$2/) { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/${1}[$lang]=$translation/; + print OUTPUT; + } + } else { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub schemas_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + # Support for <_foo>blah style translations. + + my $regex_start = "^(.*?)([ \t]*)"; + my $regex_short = "([ \t\n]*)(.*?)"; + my $regex_long = "([ \t\n]*)(.*?)"; + my $regex_end = "([ \t\n]*)"; + + while ($source =~ s|$regex_start$regex_short$regex_long$regex_end||s) { + print OUTPUT $1; + + my $locale_start_spaces = $2; + my $locale_end_spaces = $7; + my $short_spaces = $3; + my $short_string = $4; + my $long_spaces = $5; + my $long_string = $6; + + # English first + + print OUTPUT "$locale_start_spaces"; + print OUTPUT "$short_spaces$short_string"; + print OUTPUT "$long_spaces$long_string"; + print OUTPUT "$locale_end_spaces"; + + $short_string =~ s/\s+/ /g; + $short_string =~ s/^ //; + $short_string =~ s/ $//; + $short_string = entity_decode($short_string); + + $long_string =~ s/\s+/ /g; + $long_string =~ s/^ //; + $long_string =~ s/ $//; + $long_string = entity_decode($long_string); + + for my $lang (sort keys %po_files_by_lang) { + my $short_translation = $translations{$lang, $short_string}; + my $long_translation = $translations{$lang, $long_string}; + + next if (!$short_translation && !$long_translation); + + print OUTPUT "\n$locale_start_spaces"; + + if ($short_translation) + { + $short_translation = entity_encode($short_translation); + print OUTPUT "$short_spaces$short_translation"; + } + + if ($long_translation) + { + $long_translation = entity_encode($long_translation); + print OUTPUT "$long_spaces$long_translation"; + } + + print OUTPUT "$locale_end_spaces"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} diff --git a/linphone/intltool-update.in b/linphone/intltool-update.in new file mode 100644 index 000000000..cc5fc141d --- /dev/null +++ b/linphone/intltool-update.in @@ -0,0 +1,634 @@ +#!@INTLTOOL_PERL@ -w + +# +# The Intltool Message Updater +# +# Copyright (C) 2000-2002 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Maciej Stachowiak +# Darin Adler + +## Release information +my $PROGRAM = "intltool-update"; +my $VERSION = "0.22"; +my $PACKAGE = "intltool"; + +## Loaded modules +use strict; +use Getopt::Long; +use Cwd; +use File::Copy; +use File::Find; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $DIST_ARG = 0; +my $POT_ARG = 0; +my $HEADERS_ARG = 0; +my $MAINTAIN_ARG = 0; +my $REPORT_ARG = 0; +my $VERBOSE = 0; +my $GETTEXT_PACKAGE = ""; + +my @languages; +my %po_files_by_lang = (); + +# Regular expressions to categorize file types. +# FIXME: Please check if the following is correct + +my $xml_extension = +"xml(\.in)*|". # .in is not required +"ui|". +"glade2?(\.in)*|". # .in is not required +"scm(\.in)*|". # .in is not required +"oaf(\.in)+|". +"etspec|". +"sheet(\.in)+|". +"schemas(\.in)+|". +"pong(\.in)+"; + +my $ini_extension = +"desktop(\.in)+|". +"caves(\.in)+|". +"directory(\.in)+|". +"soundlist(\.in)+|". +"keys(\.in)+|". +"server(\.in)+"; + +## Always print as the first thing +$| = 1; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "dist|d" => \$DIST_ARG, + "pot|p" => \$POT_ARG, + "headers|s" => \$HEADERS_ARG, + "maintain|m" => \$MAINTAIN_ARG, + "report|r" => \$REPORT_ARG, + "verbose|x" => \$VERBOSE, + "gettext-package|g=s" => \$GETTEXT_PACKAGE, + ) or &print_error_invalid_option; + +&print_help if $HELP_ARG; +&print_version if $VERSION_ARG; + +my $arg_count = ($DIST_ARG > 0) + + ($POT_ARG > 0) + + ($HEADERS_ARG > 0) + + ($MAINTAIN_ARG > 0) + + ($REPORT_ARG > 0); +&print_help if $arg_count > 1; + +# --version and --help don't require a module name +my $MODULE = $GETTEXT_PACKAGE || &find_package_name; + +if ($DIST_ARG) { + if ($ARGV[0] =~ /^[a-z]/){ + &update_po_file ($ARGV[0]); + &print_status ($ARGV[0]); + } else { + &print_help; + } +} elsif ($POT_ARG) { + &generate_headers; + &generate_po_template; +} elsif ($HEADERS_ARG) { + &generate_headers; +} elsif ($MAINTAIN_ARG) { + &find_leftout_files; +} elsif ($REPORT_ARG) { + &print_report; +} else { + if ($ARGV[0] =~ /^[a-z]/) { + &main ($ARGV[0]); + } else { + &print_help; + } +} + +exit; + +######### + +sub print_version +{ + ## Print version information + print "${PROGRAM} (${PACKAGE}) $VERSION\n"; + print "Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.\n\n"; + print "Copyright (C) 2000-2002 Free Software Foundation, Inc.\n"; + print "This is free software; see the source for copying conditions. There is NO\n"; + print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"; + exit; +} + +sub print_help +{ + ## Print usage information + print "Usage: ${PROGRAM} [OPTIONS] ...LANGCODE\n"; + print "Updates PO template files and merge them with the translations.\n\n"; + print " -p, --pot generate the PO template only\n"; + print " -s, --headers generate the header files in POTFILES.in\n"; + print " -m, --maintain search for left out files from POTFILES.in\n"; + print " -r, --report display a status report for the module.\n"; + print " -x, --verbose display lots of feedback\n"; + print " --help display this help and exit\n"; + print " --version output version information and exit\n"; + print "\nExamples of use:\n"; + print "${PROGRAM} --pot just creates a new PO template from the source\n"; + print "${PROGRAM} da created new PO template and updated the da.po file\n\n"; + print "Report bugs to bugzilla.gnome.org, module 'intltool'.\n"; + exit; +} + +sub main +{ + my ($lang) = @_; + + ## Report error if the language file supplied + ## to the command line is non-existent + &print_error_not_existing("$lang.po") if ! -s "$lang.po"; + + print "Working, please wait..." unless $VERBOSE; + &generate_headers; + &generate_po_template; + &update_po_file ($lang); + &print_status ($lang); +} + +sub determine_type ($) +{ + my $type = $_; + my $gettext_type; + + # FIXME: Use $xml_extentions, and maybe do all this even nicer + my $xml_regex = + "(?:xml(\.in)*|ui|oaf(?:\.in)+|server(?:\.in)+|sheet(?:\.in)+|". + "pong(?:\.in)+|etspec|schemas(?:\.in)+)"; + my $ini_regex = + "(?:desktop(?:\.in)+|caves(?:\.in)+|directory(?:\.in)+|". + "soundlist(?:\.in)+)"; + + if ($type =~ /\[type: gettext\/([^\]].*)]/) { + $gettext_type=$1; + } + elsif ($type =~ /schemas(\.in)+$/) { + $gettext_type="schemas"; + } + elsif ($type =~ /$xml_regex$/) { + $gettext_type="xml"; + } + elsif ($type =~ /glade2?(\.in)*$/) { + $gettext_type="glade"; + } + elsif ($type =~ /$ini_regex$/) { + $gettext_type="ini"; + } + elsif ($type =~ /scm(\.in)*$/) { + $gettext_type="scheme"; + } + elsif ($type =~ /keys(\.in)+$/) { + $gettext_type="keys"; + } + else { $gettext_type=""; } + + return "gettext\/$gettext_type"; +} + +sub find_leftout_files +{ + my (@buf_i18n_plain, + @buf_i18n_xml, + @buf_i18n_xml_unmarked, + @buf_i18n_ini, + @buf_potfiles, + @buf_potfiles_ignore, + @buf_allfiles, + @buf_allfiles_sorted, + @buf_potfiles_sorted + ); + + ## Search and find all translatable files + find sub { + push @buf_i18n_plain, "$File::Find::name" if /\.(c|y|cc|cpp|c\+\+|h|gob)$/ + }, ".."; + find sub { + push @buf_i18n_xml, "$File::Find::name" if /\.($xml_extension)$/ + }, ".."; + find sub { + push @buf_i18n_ini, "$File::Find::name" if /\.($ini_extension)$/ + }, ".."; + find sub { + push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/ + }, ".."; + + + open POTFILES, "POTFILES.in" or die "$PROGRAM: there's no POTFILES.in!\n"; + + @buf_potfiles = grep /^[^#]/, ; + + print "Searching for missing translatable files...\n" if $VERBOSE; + + ## Check if we should ignore some found files, when + ## comparing with POTFILES.in + foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") { + if (-s $ignore) { + open FILE, $ignore; + while () { + if (/^[^#]/){ + push @buf_potfiles_ignore, $_; + } + } + print "Found $ignore: Ignoring files...\n" if $VERBOSE; + @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles); + } + } + + foreach my $file (@buf_i18n_plain) + { + my $in_comment = 0; + my $in_macro = 0; + + open FILE, "<$file"; + while () + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-) + { + warn "mismatched quotes at line $. in $file\n"; + s-$match.*--; + } + } + } + + + if (/_\(QUOTEDTEXT/) + { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml) { + open FILE, "<$file"; + while () { + if (/\s_(.*)=\"/ || /translatable=\"yes\"/){ + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + } + + foreach my $file (@buf_i18n_ini){ + open FILE, "<$file"; + while () { + if (/_(.*)=/){ + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + } + + foreach my $file (@buf_i18n_xml_unmarked){ + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + + + @buf_allfiles_sorted = sort (@buf_allfiles); + @buf_potfiles_sorted = sort (@buf_potfiles); + + my %in2; + foreach (@buf_potfiles_sorted) { + $in2{$_} = 1; + } + + my @result; + + foreach (@buf_allfiles_sorted){ + if (!exists($in2{$_})){ + push @result, $_ + } + } + + ## Save file with information about the files missing + ## if any, and give information about this procedure. + if (@result) { + print "\n" if $VERBOSE; + open OUT, ">missing"; + print OUT @result; + print "The following files contain translations and are currently not in use. Please\n"; + print "consider adding these to the POTFILES.in file, located in the po/ directory.\n\n"; + print @result, "\n"; + print "If some of these files are left out on purpose then please add them to\n"; + print "POTFILES.skip instead of POTFILES.in. A file 'missing' containing this list\n"; + print "of left out files has been written in the current directory.\n"; + } + + ## If there is nothing to complain about, notify the user + else { + print "\nAll files containing translations are present in POTFILES.in.\n"; + } +} + +sub print_error_invalid_option +{ + ## Handle invalid arguments + print "Try `${PROGRAM} --help' for more information.\n"; + exit 1; +} + +sub generate_headers +{ + my $EXTRACT = `which intltool-extract 2>/dev/null`; + chomp $EXTRACT; + + $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"}; + + ## Generate the .h header files, so we can allow glade and + ## xml translation support + if (! -s $EXTRACT) + { + print "\n *** The intltool-extract script wasn't found!" + ."\n *** Without it, intltool-update can not generate files.\n"; + exit; + } + else + { + open FILE, ") { + chomp; + + ## Find xml files in POTFILES.in and generate the + ## files with help from the extract script + + my $gettext_type= &determine_type ($1); + + if (/\.($xml_extension|$ini_extension)$/ || /^\[/){ + $_ =~ s/^\[[^\[].*]\s*//; + my $filename = "../$_"; + + if ($VERBOSE){ + system($EXTRACT, "--update", "--type=$gettext_type", $filename); + } else { + system($EXTRACT, "--update", "--type=$gettext_type", "--quiet", $filename); + } + } + } + close FILE; + } +} + +sub generate_po_template +{ + ## Generate the potfiles from the POTFILES.in file + + print "Building the $MODULE.pot...\n" if $VERBOSE; + + move ("POTFILES.in", "POTFILES.in.old"); + + open INFILE, "POTFILES.in"; + while () { + s/\.($xml_extension|$ini_extension)$/$&.h/; + s/^\[.*]\s*(.*)/$1.h/; + print OUTFILE $_; + } + close OUTFILE; + close INFILE; + + system ("xgettext", "--default-domain\=$MODULE", + "--directory\=\.\.", + "--add-comments", + "--keyword\=\_", + "--keyword\=N\_", + "--keyword\=U\_", + "--files-from\=\.\/POTFILES\.in"); + + move ("POTFILES.in.old", "POTFILES.in"); + + print "Removing generated header (.h) files..." if $VERBOSE; + + open FILE, ") + { + chomp; + unlink "../$_.h" if /\.($xml_extension|$ini_extension)$/; + } + + close FILE; + print "done\n" if $VERBOSE; + + if (!-e "$MODULE.po") { + print "WARNING: It seems that none of the files in POTFILES.in ". + "contain marked strings\n"; + exit (1); + } + + system ("rm", "-f", "$MODULE.pot"); + move ("$MODULE.po", "$MODULE.pot") or die "$PROGRAM: couldn't move $MODULE.po to $MODULE.pot.\n"; + + print "Wrote $MODULE.pot\n" if $VERBOSE; +} + +sub update_po_file +{ + my ($lang) = @_; + + print "Merging $lang.po with $MODULE.pot..." if $VERBOSE; + + copy ("$lang.po", "$lang.po.old") || die "copy failed: $!"; + + # Perform merge, remove backup file and the "messages" trash file + # generated by gettext + system ("msgmerge", "$lang.po.old", "$MODULE.pot", "-o", "$lang.po"); + unlink "$lang.po.old"; + unlink "messages"; +} + +sub print_error_not_existing +{ + my ($file) = @_; + + ## Report error if supplied language file is non-existing + print "$PROGRAM: $file does not exist!\n"; + print "Try '$PROGRAM --help' for more information.\n"; + exit; +} + +sub gather_po_files +{ + my @po_files = glob ("./*.po"); + + @languages = map (&po_file2lang, @po_files); + + foreach my $lang (@languages) { + $po_files_by_lang{$lang} = shift (@po_files); + } +} + +sub po_file2lang ($) +{ + my $tmp = $_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub print_status +{ + my ($lang) = @_; + + system ("msgfmt", "--statistics", "$lang.po"); + print "\n"; +} + +sub print_report +{ + &generate_headers; + &generate_po_template; + &gather_po_files; + + foreach my $lang (@languages) { + print "$lang: "; + &update_po_file ($lang); + } + + print "\n\n * Current translation support in $MODULE \n\n"; + + foreach my $lang (@languages){ + print "$lang: "; + system ("msgfmt", "--statistics", "$lang.po"); + } +} + +sub find_package_name +{ + my $base_dirname = getcwd(); + $base_dirname =~ s@.*/@@; + + my ($conf_in, $src_dir); + + if ($base_dirname =~ /^po(-.+)?$/) { + if (-f "../configure.in") { + $conf_in = "../configure.in"; + } elsif (-f "../configure.ac") { + $conf_in = "../configure.ac"; + } else { + my $makefile_source; + local (*IN); + open IN, ") { + if (/^top_srcdir[ \t]*=/) { + $src_dir = $_; + # print "${src_dir}\n"; + + $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + # print "${src_dir}\n"; + chomp $src_dir; + $conf_in = "$src_dir" . "/configure.in" . "\n"; + last; + } + } + $conf_in || die "Cannot find top_srcdir in Makefile." + } + + my %varhash = (); + my $conf_source; { + local (*IN); + open (IN, "<$conf_in") || die "can't open $conf_in: $!"; + while () { + if (/^(\w+)=(\S+)/) { $varhash{$1} = $2 }; + } + seek (IN, 0, 0); + local $/; # slurp mode + $conf_source = ; + } + + my $name = ""; + $name = $1 if $conf_source =~ /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m; + if ($conf_source =~ /^AC_INIT\([\s\[]*([^,\)\s\]]+)\]?\s*,/m) { + $name = $1; + $varhash{"AC_PACKAGE_NAME"} = $1; + } + $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\s\]]+)/m; + + $name = "\$AC_PACKAGE_NAME" if "$name" eq "AC_PACKAGE_NAME"; + + my $oldname = ""; + while (($name =~ /[\$](\S+)/) && ("$oldname" ne "$name")) { + $oldname = $name; + if (exists $varhash{$1}) { + $name =~ s/[\$](\S+)/$varhash{$1}/; + } + } + return $name if $name; + } + + print "$PROGRAM: Unable to determine package name.\n" . + "Make sure to run this script inside the po directory.\n"; + exit; +} diff --git a/linphone/ipkg/.cvsignore b/linphone/ipkg/.cvsignore new file mode 100644 index 000000000..bf7b0e90e --- /dev/null +++ b/linphone/ipkg/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +linphone.control diff --git a/linphone/ipkg/Makefile.am b/linphone/ipkg/Makefile.am new file mode 100644 index 000000000..b5d762405 --- /dev/null +++ b/linphone/ipkg/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST=ipaq-config.site linphone.control glib.control libosip.control linphone.control.in diff --git a/linphone/ipkg/glib.control b/linphone/ipkg/glib.control new file mode 100644 index 000000000..2af6a91f4 --- /dev/null +++ b/linphone/ipkg/glib.control @@ -0,0 +1,8 @@ +Package: libglib2.2 +Section: libs +Priority: optional +Version: 2.2.2 +Architecture: arm +Maintainer: Simon Morlat +Depends: libc6 +Description: a usefull set of C routines in a portable library. diff --git a/linphone/ipkg/ipaq-config.site b/linphone/ipkg/ipaq-config.site new file mode 100644 index 000000000..8a320dce5 --- /dev/null +++ b/linphone/ipkg/ipaq-config.site @@ -0,0 +1,89 @@ +# config.site for configure +# iPAQ Familiar Linux TARGET + +# this config file is only suitable for the 3.2 release of the arm toolchain. + +# run with +# CONFIG_SITE=/wherever/you/store/it/ipaq-config.site ./configure +# or +# export CONFIG_SITE=/wherever/you/store/it/ipaq-config.site +# if this is going to be a whole compilation orgy + +# Modified from the one provided by Bradley D. LaRonde +# Edited by Andrej Cedilnik +# Used some of solutions by Tilman Vogel +# Ported for iPAQ Familiar by Oliver Kurth + +HOSTCC=gcc + +# Names of the cross-compilers +CC=arm-linux-gcc +CXX=arm-linux-g++ + +# The cross compiler specific options +CFLAGS="-O2 -fno-exceptions" +CXXFLAGS="-O2 -fno-exceptions" +CPPFLAGS="-O2 -fno-exceptions" +LDFLAGS="" + +# Some other programs +AR=arm-linux-ar +RANLIB=arm-linux-ranlib +NM=arm-linux-nm +ac_cv_path_NM=arm-linux-nm +ac_cv_func_setpgrp_void=yes +host=arm-linux +#prefix=/usr/mipsel-linux +x_includes=/skiff/local/arm-linux/include/X11 +x_libraries=/skiff/local/arm-linux/lib/X11 + +# These are for GNU shellutils +jm_cv_have_proc_uptime=yes +jm_cv_func_working_gnu_strftime=yes + +# Some options for ease of compiling python +# (these are left over from the agenda. Not checked for iPAQ) +ac_cv_sizeof_int=4 +ac_cv_sizeof_char=1 +ac_cv_sizeof_short=2 +ac_cv_sizeof_float=4 +ac_cv_sizeof_double=8 +ac_cv_sizeof_pthread_t=4 +ac_cv_sizeof_long=4 +ac_cv_sizeof_void_p=4 +ac_cv_sizeof_long_long=8 +ac_cv_sizeof_off_t=4 +ac_cv_sizeof_fpos_t=4 +ac_cv_sizeof_time_t=4 + +# Some other stuff nobody knows why +#bad_forward=no +#LDSHARED='mipsel-linux-gcc -msoft-float -shared' +#ac_cv_malloc_zero=nonnull + +# squeak wants this +# can't do misaligned access to doubles +ac_cv_double_align=no +# dunno what order doubles are in +ac_cv_double_order=no + +ac_cv_header_wchar_h=no + +# added by oku, for compiling glib: +glib_cv_has__inline=yes +glib_cv_has__inline__=yes +glib_cv_hasinline=yes +glib_cv_sane_realloc=yes +glib_cv_va_copy=no +glib_cv___va_copy=yes +glib_cv_va_val_copy=yes +glib_cv_rtldglobal_broken=no +glib_cv_uscore=yes +ac_cv_func_getpwuid_r=yes +glib_cv_sizeof_gmutex=24 + +#added by Simon Morlat, for compiling glib-2.2.x + +glib_cv_stack_grows=no +ac_cv_func_posix_getpwuid_r=yes +glib_cv_use_pid_surrogate=yes diff --git a/linphone/ipkg/libosip.control b/linphone/ipkg/libosip.control new file mode 100644 index 000000000..2da070de4 --- /dev/null +++ b/linphone/ipkg/libosip.control @@ -0,0 +1,8 @@ +Package: libosip +Section: libs +Priority: optional +Version: 0.9.7-1 +Architecture: arm +Maintainer: Simon Morlat +Depends: libc6 +Description: a SIP (RFC3261) C library. diff --git a/linphone/ipkg/linphone.control.in b/linphone/ipkg/linphone.control.in new file mode 100644 index 000000000..4edc99577 --- /dev/null +++ b/linphone/ipkg/linphone.control.in @@ -0,0 +1,8 @@ +Package: linphone +Section: net +Priority: optional +Version: @VERSION@-1 +Architecture: arm +Maintainer: Simon Morlat +Depends: libc6, libosip +Description: a SIP (RFC3261) internet phone. diff --git a/linphone/linphone.kdevprj b/linphone/linphone.kdevprj new file mode 100644 index 000000000..a8c231dc2 --- /dev/null +++ b/linphone/linphone.kdevprj @@ -0,0 +1,2285 @@ +[./ABOUT-NLS] +dist=true +install=false +install_location= +type=DATA + +[./AUTHORS] +dist=true +install=false +install_location= +type=DATA + +[./BUGS] +dist=true +install=false +install_location= +type=DATA + +[./COPYING] +dist=true +install=false +install_location= +type=DATA + +[./ChangeLog] +dist=true +install=false +install_location= +type=DATA + +[./INSTALL] +dist=true +install=false +install_location= +type=DATA + +[./Makefile.am] +files=./ABOUT-NLS,./AUTHORS,./BUGS,./COPYING,./ChangeLog,./INSTALL,./NEWS,./README,./acconfig.h,./aclocal.m4,./config.guess,./config.h.in,./config.sub,./configure,./configure.in,./install-sh,./linphone.glade,./ltconfig,./ltmain.sh,./missing,./mkinstalldirs,./stamp-h.in,./config.log,./libtool,./linphone.log,./config.h,./config.cache,./stamp-h,./autogen.sh,./linphone.glade.bak,./config.status,./linphone.kdevprj, +sub_dirs=G711,audio,gsmlib,intl,lpc10-1.5,lprtplib,macros,osipua,pixmaps,po,share,src, +type=normal + +[./NEWS] +dist=true +install=false +install_location= +type=DATA + +[./README] +dist=true +install=false +install_location= +type=DATA + +[./acconfig.h] +dist=true +install=false +install_location= +type=HEADER + +[./aclocal.m4] +dist=true +install=false +install_location= +type=DATA + +[./autogen.sh] +dist=true +install=false +install_location= +type=DATA + +[./config.cache] +dist=true +install=false +install_location= +type=DATA + +[./config.guess] +dist=true +install=false +install_location= +type=DATA + +[./config.h] +dist=true +install=false +install_location= +type=HEADER + +[./config.h.in] +dist=true +install=false +install_location= +type=DATA + +[./config.log] +dist=true +install=false +install_location= +type=DATA + +[./config.status] +dist=true +install=false +install_location= +type=DATA + +[./config.sub] +dist=true +install=false +install_location= +type=DATA + +[./configure] +dist=true +install=false +install_location= +type=DATA + +[./configure.in] +dist=true +install=false +install_location= +type=DATA + +[./install-sh] +dist=true +install=false +install_location= +type=DATA + +[./libtool] +dist=true +install=false +install_location= +type=DATA + +[./linphone.glade] +dist=true +install=false +install_location= +type=DATA + +[./linphone.glade.bak] +dist=true +install=false +install_location= +type=DATA + +[./linphone.kdevprj] +dist=true +install=false +install_location= +type=DATA + +[./linphone.log] +dist=true +install=false +install_location= +type=DATA + +[./ltconfig] +dist=true +install=false +install_location= +type=DATA + +[./ltmain.sh] +dist=true +install=false +install_location= +type=DATA + +[./missing] +dist=true +install=false +install_location= +type=DATA + +[./mkinstalldirs] +dist=true +install=false +install_location= +type=DATA + +[./stamp-h] +dist=true +install=false +install_location= +type=DATA + +[./stamp-h.in] +dist=true +install=false +install_location= +type=DATA + +[Config for BinMakefileAm] +addcxxflags= +bin_program=linphone +cxxflags=\s-O1 +ldadd= +ldflags= +libtool_dir= +path_to_bin_program=./src + +[G711/Makefile.am] +files=G711/g711alaw.c,G711/g711alaw.h,G711/g711ulaw.c,G711/g711ulaw.h, +sub_dirs= +type=normal + +[G711/g711alaw.c] +dist=true +install=false +install_location= +type=SOURCE + +[G711/g711alaw.h] +dist=true +install=false +install_location= +type=HEADER + +[G711/g711ulaw.c] +dist=true +install=false +install_location= +type=SOURCE + +[G711/g711ulaw.h] +dist=true +install=false +install_location= +type=HEADER + +[General] +AMChanged=false +author=Simon Morlat +dir_where_make_will_be_called=./ +email=simon.morlat@linphone.org +kdevprj_version=1.3 +lfv_open_groups= +make_options=\s-j1 +makefiles=./Makefile.am,src/Makefile.am,share/Makefile.am,share/fr/Makefile.am,share/C/Makefile.am,po/Makefile.am,pixmaps/Makefile.am,pixmaps/.xvpics/Makefile.am,osipua/Makefile.am,macros/Makefile.am,lprtplib/Makefile.am,lpc10-1.5/Makefile.am,intl/Makefile.am,gsmlib/Makefile.am,audio/Makefile.am,G711/Makefile.am,developer-docs/mediastreamer/Makefile.am,developer-docs/Makefile.am,mediastreamer/Makefile.am,media_api/Makefile.am,oRTP/Makefile.am +modifyMakefiles=false +project_name=linphone +project_type=normal_empty +short_info= +sub_dir= +version= +version_control=CVS +workspace=1 + +[LFV Groups] +Desktop=*.desktop, +GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS, +Headers=*.h,*.hxx,*.hpp,*.H, +Others=*, +Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l, +Translations=*.ts,*.po, +User Interface=*.ui,*.kdevdlg,*.rc, +groups=Headers,Sources,GNU,Translations,User Interface,Desktop,Others + +[Makefile.am] +sub_dirs=osipua,developer-docs,mediastreamer,media_api,oRTP,src,share + +[audio/Makefile.am] +files=audio/alsa.c,audio/alsa.h,audio/audio.c,audio/audio.h,audio/audiotest.c,audio/iodisk.c,audio/iodisk.h,audio/loopback.c,audio/loopback.h,audio/oss.c,audio/oss.h,audio/ring.c,audio/ring.h, +sub_dirs= +type=normal + +[audio/alsa.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/alsa.h] +dist=true +install=false +install_location= +type=HEADER + +[audio/audio.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/audio.h] +dist=true +install=false +install_location= +type=HEADER + +[audio/audiotest.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/iodisk.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/iodisk.h] +dist=true +install=false +install_location= +type=HEADER + +[audio/loopback.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/loopback.h] +dist=true +install=false +install_location= +type=HEADER + +[audio/oss.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/oss.h] +dist=true +install=false +install_location= +type=HEADER + +[audio/ring.c] +dist=true +install=false +install_location= +type=SOURCE + +[audio/ring.h] +dist=true +install=false +install_location= +type=HEADER + +[developer-docs/Makefile.am] +sub_dirs=mediastreamer +type=normal + +[developer-docs/mediastreamer/Makefile.am] +files=developer-docs/mediastreamer/mediastreamer-decl.txt,developer-docs/mediastreamer/mediastreamer-docs.sgml,developer-docs/mediastreamer/mediastreamer-sections.txt,developer-docs/mediastreamer/mediastreamer.types +sub_dirs= +type=normal + +[developer-docs/mediastreamer/mediastreamer-decl.txt] +dist=true +install=false +install_location= +type=DATA + +[developer-docs/mediastreamer/mediastreamer-docs.sgml] +dist=true +install=false +install_location= +type=DATA + +[developer-docs/mediastreamer/mediastreamer-sections.txt] +dist=true +install=false +install_location= +type=DATA + +[developer-docs/mediastreamer/mediastreamer.types] +dist=true +install=false +install_location= +type=SCRIPT + +[gsmlib/COPYRIGHT] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/ChangeLog] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/ChangeLog.orig] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/INSTALL] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/MACHINES] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/MANIFEST] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/Makefile.am] +files=gsmlib/COPYRIGHT,gsmlib/ChangeLog,gsmlib/INSTALL,gsmlib/MACHINES,gsmlib/MANIFEST,gsmlib/README,gsmlib/add.c,gsmlib/code.c,gsmlib/config.h,gsmlib/debug.c,gsmlib/decode.c,gsmlib/gsm.h,gsmlib/gsm_create.c,gsmlib/gsm_decode.c,gsmlib/gsm_destroy.c,gsmlib/gsm_encode.c,gsmlib/gsm_explode.c,gsmlib/gsm_implode.c,gsmlib/gsm_option.c,gsmlib/gsm_print.c,gsmlib/gsm_wrapper.c,gsmlib/gsm_wrapper.h,gsmlib/long_term.c,gsmlib/lpc.c,gsmlib/preprocess.c,gsmlib/private.h,gsmlib/proto.h,gsmlib/rpe.c,gsmlib/short_term.c,gsmlib/table.c,gsmlib/toast.h,gsmlib/unproto.h,gsmlib/ChangeLog.orig, +sub_dirs= +type=normal + +[gsmlib/README] +dist=true +install=false +install_location= +type=DATA + +[gsmlib/add.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/code.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/config.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/debug.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/decode.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/gsm_create.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_decode.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_destroy.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_encode.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_explode.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_implode.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_option.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_print.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_wrapper.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/gsm_wrapper.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/long_term.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/lpc.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/preprocess.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/private.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/proto.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/rpe.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/short_term.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/table.c] +dist=true +install=false +install_location= +type=SOURCE + +[gsmlib/toast.h] +dist=true +install=false +install_location= +type=HEADER + +[gsmlib/unproto.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/ChangeLog] +dist=true +install=false +install_location= +type=DATA + +[intl/Makefile.am] +files=intl/ChangeLog,intl/VERSION,intl/bindtextdom.c,intl/cat-compat.c,intl/dcgettext.c,intl/dgettext.c,intl/explodename.c,intl/finddomain.c,intl/gettext.c,intl/gettext.h,intl/gettextP.h,intl/hash-string.h,intl/intl-compat.c,intl/l10nflist.c,intl/libgettext.h,intl/linux-msg.sed,intl/loadinfo.h,intl/loadmsgcat.c,intl/localealias.c,intl/po2tbl.sed.in,intl/textdomain.c,intl/xopen-msg.sed,intl/po2tbl.sed, +sub_dirs= +type=normal + +[intl/VERSION] +dist=true +install=false +install_location= +type=DATA + +[intl/bindtextdom.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/cat-compat.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/dcgettext.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/dgettext.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/explodename.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/finddomain.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/gettext.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/gettext.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/gettextP.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/hash-string.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/intl-compat.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/l10nflist.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/libgettext.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/linux-msg.sed] +dist=true +install=false +install_location= +type=DATA + +[intl/loadinfo.h] +dist=true +install=false +install_location= +type=HEADER + +[intl/loadmsgcat.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/localealias.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/po2tbl.sed] +dist=true +install=false +install_location= +type=DATA + +[intl/po2tbl.sed.in] +dist=true +install=false +install_location= +type=DATA + +[intl/textdomain.c] +dist=true +install=false +install_location= +type=SOURCE + +[intl/xopen-msg.sed] +dist=true +install=false +install_location= +type=DATA + +[lpc10-1.5/FAQ] +dist=true +install=false +install_location= +type=DATA + +[lpc10-1.5/Makefile.am] +files=lpc10-1.5/FAQ,lpc10-1.5/README,lpc10-1.5/README-1.0,lpc10-1.5/README.new,lpc10-1.5/analys.c,lpc10-1.5/bitio.c,lpc10-1.5/bsynz.c,lpc10-1.5/chanwr.c,lpc10-1.5/dcbias.c,lpc10-1.5/decode.c,lpc10-1.5/deemp.c,lpc10-1.5/difmag.c,lpc10-1.5/dyptrk.c,lpc10-1.5/encode.c,lpc10-1.5/energy.c,lpc10-1.5/f2c.h,lpc10-1.5/f2clib.c,lpc10-1.5/ham84.c,lpc10-1.5/hp100.c,lpc10-1.5/invert.c,lpc10-1.5/irc2pc.c,lpc10-1.5/ivfilt.c,lpc10-1.5/lpc10.h,lpc10-1.5/lpc10_wrapper.c,lpc10-1.5/lpc10_wrapper.h,lpc10-1.5/lpcdec.c,lpc10-1.5/lpcenc.c,lpc10-1.5/lpcini.c,lpc10-1.5/lpfilt.c,lpc10-1.5/median.c,lpc10-1.5/mload.c,lpc10-1.5/onset.c,lpc10-1.5/pitsyn.c,lpc10-1.5/placea.c,lpc10-1.5/placev.c,lpc10-1.5/preemp.c,lpc10-1.5/prepro.c,lpc10-1.5/random.c,lpc10-1.5/rcchk.c,lpc10-1.5/synths.c,lpc10-1.5/tbdm.c,lpc10-1.5/voicin.c,lpc10-1.5/vparms.c, +sub_dirs= +type=normal + +[lpc10-1.5/README] +dist=true +install=false +install_location= +type=DATA + +[lpc10-1.5/README-1.0] +dist=true +install=false +install_location= +type=DATA + +[lpc10-1.5/README.new] +dist=true +install=false +install_location= +type=DATA + +[lpc10-1.5/analys.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/bitio.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/bsynz.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/chanwr.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/dcbias.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/decode.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/deemp.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/difmag.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/dyptrk.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/encode.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/energy.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/f2c.h] +dist=true +install=false +install_location= +type=HEADER + +[lpc10-1.5/f2clib.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/ham84.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/hp100.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/invert.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/irc2pc.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/ivfilt.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/lpc10.h] +dist=true +install=false +install_location= +type=HEADER + +[lpc10-1.5/lpc10_wrapper.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/lpc10_wrapper.h] +dist=true +install=false +install_location= +type=HEADER + +[lpc10-1.5/lpcdec.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/lpcenc.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/lpcini.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/lpfilt.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/median.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/mload.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/onset.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/pitsyn.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/placea.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/placev.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/preemp.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/prepro.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/random.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/rcchk.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/synths.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/tbdm.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/voicin.c] +dist=true +install=false +install_location= +type=SOURCE + +[lpc10-1.5/vparms.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/Makefile.am] +files=lprtplib/rtp.c,lprtplib/rtp.h,lprtplib/rtp_private.h,lprtplib/rtp_ptypes.h,lprtplib/rtprecept.c,lprtplib/rtprecv.c,lprtplib/rtpsend.c,lprtplib/rtpsender.c,lprtplib/rtputils.c, +sub_dirs= +type=normal + +[lprtplib/rtp.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/rtp.h] +dist=true +install=false +install_location= +type=HEADER + +[lprtplib/rtp_private.h] +dist=true +install=false +install_location= +type=HEADER + +[lprtplib/rtp_ptypes.h] +dist=true +install=false +install_location= +type=HEADER + +[lprtplib/rtprecept.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/rtprecv.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/rtpsend.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/rtpsender.c] +dist=true +install=false +install_location= +type=SOURCE + +[lprtplib/rtputils.c] +dist=true +install=false +install_location= +type=SOURCE + +[macros/Makefile.am] +files=macros/aclocal-include.m4,macros/autogen.sh,macros/compiler-flags.m4,macros/curses.m4,macros/gnome-bonobo-check.m4,macros/gnome-common.m4,macros/gnome-fileutils.m4,macros/gnome-ghttp-check.m4,macros/gnome-gnorba-check.m4,macros/gnome-guile-checks.m4,macros/gnome-libgtop-check.m4,macros/gnome-objc-checks.m4,macros/gnome-orbit-check.m4,macros/gnome-print-check.m4,macros/gnome-pthread-check.m4,macros/gnome-support.m4,macros/gnome-undelfs.m4,macros/gnome-vfs.m4,macros/gnome-x-checks.m4,macros/gnome-xml-check.m4,macros/gnome.m4,macros/gperf-check.m4,macros/linger.m4,macros/need-declaration.m4, +sub_dirs= +type=normal + +[macros/aclocal-include.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/autogen.sh] +dist=true +install=false +install_location= +type=DATA + +[macros/compiler-flags.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/curses.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-bonobo-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-common.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-fileutils.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-ghttp-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-gnorba-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-guile-checks.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-libgtop-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-objc-checks.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-orbit-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-print-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-pthread-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-support.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-undelfs.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-vfs.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-x-checks.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome-xml-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gnome.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/gperf-check.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/linger.m4] +dist=true +install=false +install_location= +type=DATA + +[macros/need-declaration.m4] +dist=true +install=false +install_location= +type=DATA + +[media_api/DESIGN.txt] +dist=true +install=false +install_location= +type=DATA + +[media_api/Makefile.am] +dist=true +files=media_api/DESIGN.txt,media_api/Makefile.am +install=false +install_location= +sub_dirs= +type=DATA + +[mediastreamer/Makefile.am] +dist=true +files=mediastreamer/Makefile.am,mediastreamer/README,mediastreamer/ms.c,mediastreamer/ms.h,mediastreamer/msbuffer.c,mediastreamer/msbuffer.h,mediastreamer/mscopy.c,mediastreamer/mscopy.h,mediastreamer/msfifo.c,mediastreamer/msfifo.h,mediastreamer/msfilter.c,mediastreamer/msfilter.h,mediastreamer/msnosync.c,mediastreamer/msnosync.h,mediastreamer/msqueue.c,mediastreamer/msqueue.h,mediastreamer/msread.c,mediastreamer/msread.h,mediastreamer/mssync.c,mediastreamer/mssync.h,mediastreamer/mswrite.c,mediastreamer/mswrite.h,mediastreamer/test.c,mediastreamer/msoss.c,mediastreamer/msoss.h,mediastreamer/msosswrite.h,mediastreamer/msosswrite.c,mediastreamer/msringplayer.c,mediastreamer/msringplayer.h,mediastreamer/msossread.c,mediastreamer/msossread.h,mediastreamer/msGSMencoder.c,mediastreamer/msGSMencoder.h,mediastreamer/msrtprecv.c,mediastreamer/msrtprecv.h,mediastreamer/msGSMdecoder.c,mediastreamer/msGSMdecoder.h,mediastreamer/msLPC10encoder.c,mediastreamer/msLPC10encoder.h,mediastreamer/msLPC10decoder.c,mediastreamer/msLPC10decoder.h,mediastreamer/msAlawenc.h,mediastreamer/msAlawenc.c,mediastreamer/g711common.h,mediastreamer/msMUlawenc.c,mediastreamer/msMUlawenc.h,mediastreamer/msAlawdec.c,mediastreamer/msAlawdec.h,mediastreamer/msMUlawdec.c,mediastreamer/msMUlawdec.h,mediastreamer/msutils.h,mediastreamer/msvideosource.c,mediastreamer/msvideosource.h,mediastreamer/msv4l.h,mediastreamer/msv4l.c,mediastreamer/ring_test.c,mediastreamer/test_gsm.c,mediastreamer/test_lpc10.c,mediastreamer/test_alaw.c,mediastreamer/test_mulaw.c,mediastreamer/msavencoder.h,mediastreamer/msavencoder.c,mediastreamer/test_avenc.c,mediastreamer/msavdecoder.h,mediastreamer/msavdecoder.c,mediastreamer/test_avdec.c,mediastreamer/mstimer.h,mediastreamer/mstimer.c +install=false +install_location= +sub_dirs= +type=static_library + +[mediastreamer/README] +dist=true +install=false +install_location= +type=DATA + +[mediastreamer/g711common.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/ms.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/ms.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msAlawdec.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msAlawdec.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msAlawenc.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msAlawenc.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msGSMdecoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msGSMdecoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msGSMencoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msGSMencoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msLPC10decoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msLPC10decoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msLPC10encoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msLPC10encoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msMUlawdec.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msMUlawdec.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msMUlawenc.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msMUlawenc.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msavdecoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msavdecoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msavencoder.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msavencoder.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msbuffer.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msbuffer.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/mscopy.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/mscopy.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msfifo.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msfifo.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msfilter.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msfilter.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msnosync.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msnosync.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msoss.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msoss.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msossread.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msossread.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msosswrite.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msosswrite.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msqueue.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msqueue.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msread.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msread.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msringplayer.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msringplayer.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msrtprecv.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msrtprecv.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/mssync.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/mssync.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/mstimer.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/mstimer.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msutils.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msv4l.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msv4l.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/msvideosource.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/msvideosource.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/mswrite.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/mswrite.h] +dist=true +install=false +install_location= +type=HEADER + +[mediastreamer/ring_test.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_alaw.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_avdec.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_avenc.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_gsm.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_lpc10.c] +dist=true +install=false +install_location= +type=SOURCE + +[mediastreamer/test_mulaw.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/Makefile.am] +dist=true +files=oRTP/Makefile.am,oRTP/rtp.h,oRTP/rtpsession.c,oRTP/str_utils.c,oRTP/rtpsend.c,oRTP/rtprecv.c,oRTP/str_utils.h,oRTP/rtpsession.h,oRTP/rtpmod.c,oRTP/rtpmod.h +install=false +install_location= +sub_dirs= +type=static_library + +[oRTP/rtp.h] +dist=true +install=false +install_location= +type=HEADER + +[oRTP/rtpmod.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/rtpmod.h] +dist=true +install=false +install_location= +type=HEADER + +[oRTP/rtprecv.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/rtpsend.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/rtpsession.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/rtpsession.h] +dist=true +install=false +install_location= +type=HEADER + +[oRTP/str_utils.c] +dist=true +install=false +install_location= +type=SOURCE + +[oRTP/str_utils.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/Makefile.am] +dist=true +files=osipua/osipua.c,osipua/osipcallleg.c,osipua/osipua.h,osipua/callbacks_uac.c,osipua/callbacks_uas.c,osipua/osipua_tester.c,osipua/osipua_tester.h,osipua/utils.c,osipua/utils.h,osipua/osipcallleg.h,osipua/udp.c,osipua/udp.h,osipua/osipmanager.c,osipua/osipmanager.h,osipua/resolver.c,osipua/resolver.h,osipua/uatransaction.h,osipua/uatransaction.c,osipua/mediadesc.h,osipua/mediadesc.c,osipua/Makefile.am,osipua/regctxt.h,osipua/digcalc.h,osipua/regctxt.c,osipua/bodyhandlerinfo.h,osipua/authentication.c,osipua/bodyhandler.h,osipua/bodyhandlerinfo.c,osipua/bodyhandler.c,osipua/sdphandler.h,osipua/sdphandler.c,osipua/sdphandlerinfo.h,osipua/sdphandlerinfo.c +install=false +install_location= +sub_dirs= +type=static_library + +[osipua/authentication.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/bodyhandler.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/bodyhandler.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/bodyhandlerinfo.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/bodyhandlerinfo.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/callbacks_uac.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/callbacks_uas.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/digcalc.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/mediadesc.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/mediadesc.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/osipcallleg.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/osipcallleg.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/osipmanager.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/osipmanager.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/osipua.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/osipua.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/osipua_tester.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/osipua_tester.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/regctxt.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/regctxt.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/resolver.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/resolver.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/sdphandler.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/sdphandler.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/sdphandlerinfo.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/sdphandlerinfo.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/uatransaction.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/uatransaction.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/udp.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/udp.h] +dist=true +install=false +install_location= +type=HEADER + +[osipua/utils.c] +dist=true +install=false +install_location= +type=SOURCE + +[osipua/utils.h] +dist=true +install=false +install_location= +type=HEADER + +[pixmaps/.xvpics/Makefile.am] +files=pixmaps/.xvpics/linphone.png, +sub_dirs= +type=normal + +[pixmaps/.xvpics/linphone.png] +dist=true +install=false +install_location= +type=DATA + +[pixmaps/Makefile.am] +files=pixmaps/linphone2.png,pixmaps/linphone2.xpm,pixmaps/linphone.png, +sub_dirs= +type=normal + +[pixmaps/linphone.png] +dist=true +install=false +install_location= +type=DATA + +[pixmaps/linphone2.png] +dist=true +install=false +install_location= +type=DATA + +[pixmaps/linphone2.xpm] +dist=true +install=false +install_location= +type=DATA + +[po/ChangeLog] +dist=true +install=false +install_location= +type=DATA + +[po/Makefile.am] +files=po/ChangeLog,po/POTFILES.in,po/cat-id-tbl.c,po/fr.gmo,po/fr.po,po/linphone.pot,po/stamp-cat-id,po/POTFILES,po/fr.po.old,po/fr.po.new~,po/fr.po~, +sub_dirs= +type=po + +[po/POTFILES] +dist=true +install=false +install_location= +type=DATA + +[po/POTFILES.in] +dist=true +install=false +install_location= +type=DATA + +[po/cat-id-tbl.c] +dist=true +install=false +install_location= +type=SOURCE + +[po/fr.gmo] +dist=true +install=false +install_location= +type=DATA + +[po/fr.po] +dist=true +install=false +install_location= +type=DATA + +[po/fr.po.new~] +dist=true +install=false +install_location= +type=DATA + +[po/fr.po.old] +dist=true +install=false +install_location= +type=DATA + +[po/fr.po~] +dist=true +install=false +install_location= +type=DATA + +[po/linphone.pot] +dist=true +install=false +install_location= +type=DATA + +[po/stamp-cat-id] +dist=true +install=false +install_location= +type=DATA + +[share/C/Makefile.am] +files=share/C/manual.html,share/C/parameters-1.html,share/C/parameters-2.html,share/C/parameters-3.html,share/C/parameters-4.html,share/C/parameters-5.html,share/C/manual.sdw,share/C/css.css, +sub_dirs= +type=normal + +[share/C/css.css] +dist=true +install=false +install_location= +type=DATA + +[share/C/manual.html] +dist=true +install=false +install_location= +type=DATA + +[share/C/manual.sdw] +dist=true +install=false +install_location= +type=DATA + +[share/C/parameters-1.html] +dist=true +install=false +install_location= +type=DATA + +[share/C/parameters-2.html] +dist=true +install=false +install_location= +type=DATA + +[share/C/parameters-3.html] +dist=true +install=false +install_location= +type=DATA + +[share/C/parameters-4.html] +dist=true +install=false +install_location= +type=DATA + +[share/C/parameters-5.html] +dist=true +install=false +install_location= +type=DATA + +[share/Makefile.am] +dist=true +files=share/hello.wav,share/linphone.desktop,share/linphone.gnorba,share/linphone_applet.desktop,share/ring.wav,share/ringback.wav,share/Makefile.am +install=false +install_location= +sub_dirs=C,fr, +type=DATA + +[share/fr/Makefile.am] +files=share/fr/manual.html,share/fr/parameters-1.html,share/fr/parameters-2.html,share/fr/parameters-3.html,share/fr/parameters-4.html,share/fr/parameters-5.html,share/fr/css.css, +sub_dirs= +type=normal + +[share/fr/css.css] +dist=true +install=false +install_location= +type=DATA + +[share/fr/manual.html] +dist=true +install=false +install_location= +type=DATA + +[share/fr/parameters-1.html] +dist=true +install=false +install_location= +type=DATA + +[share/fr/parameters-2.html] +dist=true +install=false +install_location= +type=DATA + +[share/fr/parameters-3.html] +dist=true +install=false +install_location= +type=DATA + +[share/fr/parameters-4.html] +dist=true +install=false +install_location= +type=DATA + +[share/fr/parameters-5.html] +dist=true +install=false +install_location= +type=DATA + +[share/hello.wav] +dist=true +install=false +install_location= +type=DATA + +[share/linphone.desktop] +dist=true +install=false +install_location= +type=DATA + +[share/linphone.gnorba] +dist=true +install=false +install_location= +type=DATA + +[share/linphone_applet.desktop] +dist=true +install=false +install_location= +type=DATA + +[share/ring.wav] +dist=true +install=false +install_location= +type=DATA + +[share/ringback.wav] +dist=true +install=false +install_location= +type=DATA + +[src/LinphoneMain.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/LinphoneMain.h] +dist=true +install=false +install_location= +type=HEADER + +[src/Makefile.am] +dist=true +files=src/LinphoneMain.c,src/LinphoneMain.h,src/callbacks.c,src/callbacks.h,src/codec.c,src/codec.h,src/gui_utils.c,src/gui_utils.h,src/interface.h,src/interface.c_ref,src/interface.c,src/io.c,src/io.h,src/main.c,src/sip_handlers.h,src/sipomatic.c,src/sipomatic.h,src/state-machine.h,src/support.c,src/support.h,src/presence.c,src/presence.h,src/Makefile.am,src/propertybox.h,src/propertybox.c +install=false +install_location= +sub_dirs= +type=static_library + +[src/callbacks.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/callbacks.h] +dist=true +install=false +install_location= +type=HEADER + +[src/codec.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/codec.h] +dist=true +install=false +install_location= +type=HEADER + +[src/gui_utils.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/gui_utils.h] +dist=true +install=false +install_location= +type=HEADER + +[src/interface.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/interface.c_ref] +dist=true +install=false +install_location= +type=DATA + +[src/interface.h] +dist=true +install=false +install_location= +type=HEADER + +[src/io.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/io.h] +dist=true +install=false +install_location= +type=HEADER + +[src/main.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/presence.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/presence.h] +dist=true +install=false +install_location= +type=HEADER + +[src/propertybox.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/propertybox.h] +dist=true +install=false +install_location= +type=HEADER + +[src/sip_handlers.h] +dist=true +install=false +install_location= +type=HEADER + +[src/sipomatic.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/sipomatic.h] +dist=true +install=false +install_location= +type=HEADER + +[src/state-machine.h] +dist=true +install=false +install_location= +type=HEADER + +[src/support.c] +dist=true +install=false +install_location= +type=SOURCE + +[src/support.h] +dist=true +install=false +install_location= +type=HEADER diff --git a/linphone/linphone.spec.in b/linphone/linphone.spec.in new file mode 100644 index 000000000..3bdeeea57 --- /dev/null +++ b/linphone/linphone.spec.in @@ -0,0 +1,258 @@ +# -*- rpm-spec -*- + +## rpmbuild options + +# default is to build with video support & without truespeech support +%define video %{?_without_video:0}%{!?_without_video:1} +%define truespeech %{?_with_truespeech:1}%{!?_with_truespeech:0} + +# Linphone requires an old osip version, sometimes (e.g. fc6) +# delivered as "compat-" +%define _without_old_osip 0 + +Name: linphone +Version: @VERSION@ +Release: 1%{?dist} +Summary: Phone anywhere in the whole world by using the Internet + +Group: Applications/Communications +License: GPL +URL: http://www.linphone.org +Source0: http://download.savannah.gnu.org/releases/linphone/stable/source/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +%ifarch %{ix86} +BuildArch: i686 +%endif + +BuildRequires: gnome-panel-devel libgnomeui-devel glib2-devel alsa-lib-devel +BuildRequires: libosip2-devel speex-devel gettext desktop-file-utils +BuildRequires: readline-devel ncurses-devel +BuildRequires: intltool gettext-devel +%if %{video} +BuildRequires: ffmpeg-devel SDL-devel +%endif + +%description +Linphone is mostly sip compliant. It works successfully with these +implementations: + * eStara softphone (commercial software for windows) + * Pingtel phones (with DNS enabled and VLAN QOS support disabled). + * Hotsip, a free of charge phone for Windows. + * Vocal, an open source SIP stack from Vovida that includes a SIP proxy + that works with linphone since version 0.7.1. + * Siproxd is a free sip proxy being developped by Thomas Ries because he + would like to have linphone working behind his firewall. Siproxd is + simple to setup and works perfectly with linphone. + * Partysip aims at being a generic and fully functionnal SIP proxy. Visit + the web page for more details on its functionalities. + +Linphone may work also with other sip phones, but this has not been tested yet. + +%package devel +Summary: Development libraries for linphone +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: ortp-devel = @ORTP_VERSION@ +Requires: glib2-devel + +%description devel +Libraries and headers required to develop software with linphone. + +%package -n ortp +Summary: A C library implementing the RTP protocol (rfc1889) +Group: System Environment/Libraries +Version: @ORTP_VERSION@ + +%description -n ortp +oRTP is a LGPL licensed C library implementing the RTP protocol (rfc1889). It +is available for most *nix clones (primilarly Linux and HP-UX), and Win32. + +%package -n ortp-devel +Summary: Development libraries for ortp +Group: Development/Libraries +Version: @ORTP_VERSION@ +Requires: ortp = @ORTP_VERSION@ + +%description -n ortp-devel +oRTP is a LGPL licensed C library implementing the RTP protocol (rfc1889). It +is available for most *nix clones (primilarly Linux and HP-UX), and Win32. + +This package contains header files and development libraries needed to +develop programs using the oRTP library. + +%package -n mediastreamer2 +Summary: Audio/Video real-time streaming +Group: Development/Libraries +Version: @MS2_VERSION@ + +%description -n mediastreamer2 +Mediastreamer2 is a GPL licensed library to make audio and video +real-time streaming and processing. Written in pure C, it is based +upon the oRTP library. + +%package -n mediastreamer2-devel +Summary: Headers, libraries and docs for the mediastreamer2 library +Group: Development/Libraries +Version: @MS2_VERSION@ +Requires: mediastreamer2 = @MS2_VERSION@ +Requires: ortp-devel = @ORTP_VERSION@ + +%description -n mediastreamer2-devel +Mediastreamer2 is a GPL licensed library to make audio and video +real-time streaming and processing. Written in pure C, it is based +upon the ortp library. + +This package contains header files and development libraries needed to +develop programs using the mediastreamer2 library. + +%prep +%setup -q +#%patch -p 1 -b .pkgconfig +#%patch1 -p 1 -b .Werror +#%patch2 -p 1 -b .old + +%build +%configure \ + --with-osip=/usr \ + --with-speex=/usr \ + --with-readline=/usr \ +%if %{video} + --enable-video \ + --with-ffmpeg=/usr \ + --with-sdl=/usr \ +%endif +%if %{truespeech} + --enable-truespeech \ +%endif +%{?_without_old_osip: --with-osip-version=2.2.2} \ + --enable-ipv6 +%__make %{?_smp_mflags} + + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +install -p -m 0644 pixmaps/linphone2.png $RPM_BUILD_ROOT%{_datadir}/pixmaps +%find_lang %{name} +rm $RPM_BUILD_ROOT%{_datadir}/gnome/apps/Internet/linphone.desktop +desktop-file-install --vendor=fedora \ + --delete-original \ + --dir $RPM_BUILD_ROOT%{_datadir}/applications \ + --add-category X-Fedora \ + --add-category Telephony \ + --add-category GTK \ + $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%post -n ortp -p /sbin/ldconfig + +%postun -n ortp -p /sbin/ldconfig + +%post -n mediastreamer2 -p /sbin/ldconfig + +%postun -n mediastreamer2 -p /sbin/ldconfig + +%files -f %{name}.lang +%defattr(-,root,root) +%doc AUTHORS ChangeLog COPYING NEWS README TODO +%{_bindir}/* +%{_libdir}/bonobo/servers/*.server +%{_libdir}/liblinphone.so.* +%exclude %{_libdir}/libortp* +%{_libexecdir}/* +%{_mandir}/* +%{_datadir}/applications/*%{name}.desktop +%{_datadir}/gnome/help/linphone +%{_datadir}/gnome-2.0/ui/*.xml +%{_datadir}/pixmaps/linphone +%{_datadir}/pixmaps/linphone2.png +%{_datadir}/sounds/linphone + +%files devel +%defattr(-,root,root) +%{_includedir}/linphone +%{_libdir}/liblinphone.a +%{_libdir}/liblinphone.la +%{_libdir}/liblinphone.so +%{_libdir}/pkgconfig/linphone.pc + +%files -n ortp +%defattr(-,root,root) +%doc oRTP/AUTHORS oRTP/ChangeLog oRTP/COPYING oRTP/NEWS oRTP/README oRTP/TODO +%{_libdir}/libortp.so.* +%exclude %{_libdir}/liblinphone* + +%files -n ortp-devel +%defattr(-,root,root) +%{_includedir}/ortp +%{_libdir}/pkgconfig/ortp.pc +%{_libdir}/libortp.a +%{_libdir}/libortp.la +%{_libdir}/libortp.so +%{_datadir}/gtk-doc/html/ortp + +%files -n mediastreamer2 +%defattr(-,root,root) +%doc mediastreamer2/AUTHORS mediastreamer2/ChangeLog mediastreamer2/COPYING +%doc mediastreamer2/NEWS mediastreamer2/README +%{_libdir}/libmediastreamer.so.* +%{_libdir}/libquickstream.so.* + +%files -n mediastreamer2-devel +%{_includedir}/mediastreamer2 +%{_libdir}/pkgconfig/mediastreamer.pc +%{_libdir}/libmediastreamer.so +%{_libdir}/libmediastreamer.*a +%{_libdir}/libquickstream.so +%{_libdir}/libquickstream.*a + +%changelog +* Wed Sep 28 2005 Francois-Xavier 'FiX' KOWALSKI - 1.2.0pre3 +- Updated to latests Simon's work + +* Fri May 27 2005 Ignacio Vazquez-Abrams 1.0.1-3 +- Fix multiple menu entry and missing icon (#158975) +- Clean up spec file + +* Fri May 6 2005 Ignacio Vazquez-Abrams 1.0.1-2 +- Fix libosip2-devel BR + +* Wed May 4 2005 Ignacio Vazquez-Abrams 1.0.1-1 +- Update to 1.0.1 +- Port patches from devel + +* Wed Mar 23 2005 Ignacio Vazquez-Abrams 0.12.2-7 +- pkgconfig and -devel fixes + +* Wed Mar 23 2005 Ignacio Vazquez-Abrams 0.12.2-6 +- Fix build on x86_64 + +* Sat Mar 19 2005 Ignacio Vazquez-Abrams 0.12.2-5 +- %% + +* Sat Mar 19 2005 Ignacio Vazquez-Abrams 0.12.2-4 +- Used %%find_lang +- Tightened up %%files +- Streamlined spec file + +* Thu Mar 17 2005 Ignacio Vazquez-Abrams 0.12.2-3 +- Broke %%description at 80 columns + +* Wed Mar 16 2005 Ignacio Vazquez-Abrams 0.12.2-2 +- Removed explicit Requires + +* Tue Mar 15 2005 Ignacio Vazquez-Abrams 0.12.2-1 +- Bump release to 1 +- Cleaned up the -docs and -speex patches + +* Fri Jan 21 2005 Ignacio Vazquez-Abrams 0:0.12.2-0.iva.1 +- Fixed a silly spec error + +* Fri Jan 21 2005 Ignacio Vazquez-Abrams 0:0.12.2-0.iva.0 +- Initial RPM release. diff --git a/linphone/linphone2-gtk.glade b/linphone/linphone2-gtk.glade new file mode 100644 index 000000000..58e091051 --- /dev/null +++ b/linphone/linphone2-gtk.glade @@ -0,0 +1,3788 @@ + + + + + + True + linphone + False + linphone2.xpm + + + + True + + + True + + + True + Go + True + + + + + True + Address book + True + + + + True + gtk-open + 1 + + + + + + + True + gtk-preferences + True + True + + + + + + True + Shows calls + Call history + True + + + + True + gtk-justify-fill + 1 + + + + + + + True + + + + + True + Exit + True + + + + True + gtk-quit + 1 + + + + + + + + + + + True + Help + True + + + + + True + gtk-about + True + True + + + + + + True + gtk-help + True + True + + + + + + + + + + + + True + 9 + 0 + + + True + + + True + + + True + + + True + 5 + 0 + + + True + True + Enter sip address or phone number here + * + sip: + + + + + + + True + Sip address: + + + label_item + + + + + + + True + True + Shows the address book + 15 + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-open + + + False + False + + + + + True + ... + True + + + False + False + 1 + + + + + + + + + False + False + 1 + + + + + + + True + + + True + Proxy to use: + GTK_JUSTIFY_CENTER + + + + + + + + 1 + + + + + + + True + + + True + True + 8 + Call or +answer + True + 0 + + + + + + True + True + 8 + Hangup +or refuse + True + 0 + + + + 1 + + + + + 1 + + + + + True + True + 8 + Or chat ! + True + 0 + + + + False + False + 2 + + + + + True + True + 0 + True + True + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-jump-to + + + False + False + + + + + True + Show more... + True + + + False + False + 1 + + + + + + + + + False + False + 3 + + + + + True + True + + + True + + + True + 11 + 0 + + + True + 2 + + + True + 7.4505801528346183e-09 + Playback level: + + + False + False + + + + + True + True + 75 0 100 0 0 0 + 0 + GTK_POS_RIGHT + + + + 1 + + + + + True + 7.4505801528346183e-09 + Recording level: + + + False + False + 2 + + + + + True + True + 75 0 100 0 0 0 + 0 + GTK_POS_RIGHT + + + + 3 + + + + + True + 7.4505801528346183e-09 + Ring level: + + + False + False + 4 + + + + + True + True + 75 0 100 0 0 0 + 0 + GTK_POS_RIGHT + + + + 5 + + + + + + + True + Sound + + + label_item + + + + + False + False + + + + + True + 0 + + + True + 12 + + + True + + + True + True + Enable video + True + 0 + True + True + + + + False + False + + + + + + + + + True + Video + True + + + label_item + + + + + False + False + 1 + + + + + False + + + + + True + Controls + GTK_JUSTIFY_CENTER + + + tab + False + False + + + + + True + + + True + 11 + 0 + + + True + + + True + True + Reachable + True + 0 + True + True + + + + False + False + + + + + True + + + True + True + Busy, I'll be back in + True + 0 + True + presence_reachable + + + + + + True + True + The other party will be informed that you'll be back in X minutes + * + 5 + + + + False + False + 1 + + + + + True + mn + GTK_JUSTIFY_CENTER + + + 2 + + + + + False + 1 + + + + + True + True + Away + True + 0 + True + presence_reachable + + + + False + False + 2 + + + + + True + True + Do not disturb + True + 0 + True + presence_reachable + + + + False + False + 3 + + + + + True + True + Moved temporarily + True + 0 + True + presence_reachable + + + + False + False + 4 + + + + + True + True + Alternative service + True + 0 + True + presence_reachable + + + + False + False + 5 + + + + + True + + + True + URL: + GTK_JUSTIFY_CENTER + + + + + True + True + * + + + + False + False + 1 + + + + + False + 6 + + + + + + + + + 1 + False + + + + + True + Presence + GTK_JUSTIFY_CENTER + + + tab + 1 + False + False + + + + + True + 15 + 0 + + + True + + + True + True + Press digits to send DTMFs. + * + + + + False + False + + + + + True + 14 + 4 + 3 + 10 + 10 + True + + + True + True + # + True + 0 + + + + 2 + 3 + 3 + 4 + + + + + True + True + 0 + True + 0 + + + + 1 + 2 + 3 + 4 + + + + + True + True + * + True + 0 + + + + 3 + 4 + + + + + True + True + 9 +wxyz + True + 0 + + + + 2 + 3 + 2 + 3 + + + + + True + True + 8 +tuv + True + 0 + + + + 1 + 2 + 2 + 3 + + + + + True + True + 7 +pqrs + True + 0 + + + + 2 + 3 + + + + + True + True + 6 +mno + True + 0 + + + + 2 + 3 + 1 + 2 + + + + + True + True + 5 +jkl + True + 0 + + + + 1 + 2 + 1 + 2 + + + + + True + True + 4 +ghi + True + 0 + + + + 1 + 2 + + + + + True + True + 1 + True + 0 + + + + + + True + True + 2 +abc + True + 0 + + + + 1 + 2 + + + + + True + True + 3 +def + True + 0 + + + + 2 + 3 + + + + + 1 + + + + + + + 2 + False + + + + + True + DTMF + GTK_JUSTIFY_CENTER + + + tab + 2 + False + False + + + + + True + + + True + True + + + True + True + + + + + + + + + + + 3 + False + + + + + True + My online friends + + + tab + 3 + False + False + + + + + 4 + + + + + + + 1 + + + + + True + 0 + + + True + + + + + 2 + + + + + + + True + 5 + True + GDK_WINDOW_TYPE_HINT_NORMAL + Linphone + C: 2001 +Made in Old Europe + Linphone is a web-phone. +It is compatible with SIP and RTP protocols. + http://www.linphone.org + http://www.linphone.org + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Simon MORLAT +Aymeric Moizard +Sharath K Udupa + Simon MORLAT +Philippe Beau + it: Alberto Zanoni +de: Jean Jacques Sarton +fr: Simon Morlat +de: Jean-Jacques Sarton, Ursula Herles-Hartz +es: Jesus Benitez, Nelson Benitez +ja: Yamaguchi Yoshiya +nl: Hendrik-Jan Heins +pl: Robert Nasiadek &lt;darkone@darkone.pl&gt; +pt_BR: Rafael Caesar Lenzi <rc_lenzi@yahoo.com.br> +sv: Daniel Nylander <po@danielnylander.se> + linphone.png + + + + + + + + False + GTK_PACK_END + + + + + + + True + Parameters + False + linphone2.xpm + GDK_WINDOW_TYPE_HINT_NORMAL + + + + + + + + True + True + + + True + + + True + 6 + 0 + + + True + 12 + + + True + + + True + True + Toggle this if you are on an ipv6 network and you wish linphone to use it. + Use IPv6 network (if available) + True + 0 + True + + + + False + False + + + + + + + + + True + Global + True + + + label_item + + + + + + + True + 5 + 0 + + + True + 6 + + + True + 12 + These options is only for users in a private network, behind a gateway. If you are not in this situation, then leave this empty. + True + + + + + True + 3 + 2 + + + + + + True + True + * + + + + 1 + 2 + 1 + 2 + + + + + + True + True + * + + + + 1 + 2 + 2 + 3 + + + + + + True + True + Specify firewall address manually: + True + 0 + True + no_nat + + + + 2 + 3 + GTK_FILL + + + + + + True + True + Use this STUN server to guess firewall address : + True + 0 + True + no_nat + + + + 1 + 2 + GTK_FILL + + + + + + True + True + No firewall + True + 0 + True + + + + GTK_FILL + + + + + + False + False + 1 + + + + + + + True + NAT traversal options (experimental) + + + label_item + + + + + 1 + + + + + True + 5 + 0 + + + True + 2 + 2 + + + True + RTP port used for audio: + GTK_JUSTIFY_CENTER + + + GTK_FILL + + + + + True + Number of buffered miliseconds (jitter compensation): + GTK_JUSTIFY_CENTER + True + + + 1 + 2 + + + + + + True + True + 7000 5000 65535 1 10 10 + 4 + True + + + + 1 + 2 + GTK_EXPAND + 20 + + + + + True + True + 150 60 512 10 0 0 + 0 + GTK_POS_RIGHT + + + + 1 + 2 + 1 + 2 + GTK_EXPAND + 20 + + + + + + + True + RTP properties + + + label_item + + + + + 2 + + + + + True + 5 + 0 + + + True + 12 + + + True + + + True + True + RTP-RFC2833 is the recommended way. + Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting + True + 0 + True + + + + False + False + + + + + + + + + True + Other + True + + + label_item + + + + + 3 + + + + + False + + + + + True + Network + GTK_JUSTIFY_CENTER + + + tab + False + False + + + + + True + + + True + + + True + 10 + 0 + + + True + + + True + 6 + 2 + + + True + + + True + Choose file + + + + + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-dialog-info + + + False + False + + + + + True + Listen + True + + + False + False + 1 + + + + + + + + + False + False + 10 + 1 + + + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + 0 + Enable echo-canceler (cancels the echo heard by the remote party) + GTK_JUSTIFY_CENTER + + + 5 + 6 + + + + + True + True + True + 0 + True + + + + 1 + 2 + 5 + 6 + GTK_FILL + + + + + + True + + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + 0 + Ring sound: + GTK_JUSTIFY_CENTER + + + 4 + 5 + + + + + + + True + 0 + Ring sound device + GTK_JUSTIFY_CENTER + + + 3 + 4 + GTK_EXPAND + + + + + + True + 0 + Recording source: + + + 2 + 3 + + + + + + + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + 0 + Capture sound device: + GTK_JUSTIFY_CENTER + + + 1 + 2 + + + + + + + True + False + False + True + + + 1 + 2 + 2 + 3 + + + + + + + True + 0 + Playback sound device: + + + GTK_EXPAND + GTK_EXPAND + + + + + + + + + True + Sound properties + + + label_item + + + + + + + False + + + + + 1 + False + + + + + True + Sound device + GTK_JUSTIFY_CENTER + + + tab + 1 + False + False + + + + + True + + + True + 10 + 0 + + + True + 67 + + + True + Run sip user agent on port: + GTK_JUSTIFY_CENTER + + + + + True + True + It is strongly recommended to use port 5060. + 5060 5000 65535 1 10 10 + 4 + + + + 32 + 1 + + + + + + + True + SIP port + + + label_item + + + + + False + + + + + True + 10 + 0 + + + True + + + True + + + True + Your sip address: + GTK_JUSTIFY_CENTER + + + False + + + + + True + sip: + GTK_JUSTIFY_RIGHT + + + False + False + 1 + + + + + True + True + * + + + + False + False + 2 + + + + + True + @ + GTK_JUSTIFY_CENTER + + + False + False + 3 + + + + + True + True + * + + + + False + 4 + + + + + + + True + True + Automatically guess a valid hostname + True + 0 + True + + + + 1 + + + + + + + True + Identity + + + label_item + + + + + False + 1 + + + + + True + 10 + 0 + + + True + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_OUT + + + 100 + True + True + + + + + + + True + 5 + GTK_BUTTONBOX_SPREAD + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-add + + + False + False + + + + + True + Add proxy/registrar + True + + + False + False + 1 + + + + + + + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-jump-to + + + False + False + + + + + True + Edit + True + + + False + False + 1 + + + + + + + + + 1 + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-cancel + + + False + False + + + + + True + Remove + True + + + False + False + 1 + + + + + + + + + 2 + + + + + 1 + + + + + + + True + Remote services + + + label_item + + + + + 2 + + + + + True + 10 + 0 + + + True + 12 + + + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-delete + + + False + False + + + + + True + Clear all stored authentication information (username,password...) + True + + + False + False + 1 + + + + + + + + + + + + + True + Authentication information + + + label_item + + + + + 3 + + + + + 2 + False + + + + + True + SIP + GTK_JUSTIFY_CENTER + + + tab + 2 + False + False + + + + + True + + + True + 10 + 0 + + + True + + + True + 9 + + + True + 0 + List of audio codecs, in order of preference: + + + False + False + 4 + + + + + True + True + + + True + False + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_IN + + + True + True + True + + + + + False + + + + + True + Audio codecs + + + tab + False + False + + + + + True + True + GTK_SHADOW_IN + + + True + True + + + + + 1 + False + + + + + True + Video Codecs + + + tab + 1 + False + False + + + + + 1 + + + + + True + 10 + + + True + True + True + gtk-go-up + True + 0 + + + + + + True + True + True + gtk-go-down + True + 0 + + + + 1 + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-apply + + + False + False + + + + + True + Enable + True + + + False + False + 1 + + + + + + + + + 2 + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-cancel + + + False + False + + + + + True + Disable + True + + + False + False + 1 + + + + + + + + + 3 + + + + + False + False + 2 + + + + + True + 2 + 2 + True + + + True + True + 0 0 100000 10 100 10 + 1 + + + + 1 + 2 + 1 + 2 + + + + + + True + True + 0 0 100000 10 100 10 + 1 + GTK_UPDATE_IF_VALID + + + + 1 + 2 + + + + + + True + 0 + Download bandwidth (kbit/sec): + GTK_JUSTIFY_CENTER + + + GTK_FILL + + + + + + True + 0 + Upload bandwidth (kbit/sec): + GTK_JUSTIFY_CENTER + + + 1 + 2 + GTK_FILL + + + + + + False + 3 + + + + + + + True + + + True + 15 + Note: Codecs in red are not usable regarding to your connection type to the internet. + GTK_JUSTIFY_CENTER + True + + + False + False + + + + + True + 8 + 0 + + + True + 10 + 10 + No information availlable + GTK_JUSTIFY_CENTER + True + + + + + True + Codec information + + + label_item + + + + + 5 + 1 + + + + + False + 1 + + + + + + + True + 0.52999997138977051 + Audio and video codecs + + + label_item + + + + + + + 3 + False + + + + + True + Codecs + GTK_JUSTIFY_CENTER + + + tab + 3 + False + False + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-help + True + -11 + + + + + + True + True + True + gtk-apply + True + -10 + + + 1 + + + + + True + True + True + gtk-close + True + -7 + + + 2 + + + + + True + True + True + gtk-ok + True + -5 + + + 3 + + + + + False + GTK_PACK_END + + + + + + + True + Address Book + 305 + linphone2.xpm + GDK_WINDOW_TYPE_HINT_NORMAL + + + True + + + True + 12 + + + True + False + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + + + True + True + + + + + + + + + 2 + + + + + True + GTK_BUTTONBOX_SPREAD + + + True + 11 + + + True + True + True + gtk-add + GTK_RELIEF_HALF + True + 0 + + + + + + True + True + True + gtk-delete + GTK_RELIEF_HALF + True + 0 + + + + 1 + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-justify-center + + + False + False + + + + + True + Edit + True + + + False + False + 1 + + + + + + + + + 2 + + + + + True + True + True + gtk-close + True + 0 + + + + 3 + + + + + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-quit + + + False + False + + + + + True + Select + True + + + False + False + 1 + + + + + + + + + 4 + + + + + + + False + False + GTK_PACK_END + + + + + + + True + Information + False + True + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + + + True + + + True + 25 + 5 + User is not reachable at the moment but he invites you to contact him using the following alternate ressource: + GTK_JUSTIFY_CENTER + True + + + 10 + + + + + True + True + 12 + None. + GTK_RELIEF_NONE + True + 0 + + + + + False + False + 1 + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-close + True + -7 + + + + + False + GTK_PACK_END + + + + + + + True + True + Proxy/Registrar configuration box + True + True + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + + True + + + True + 8 + 0 + + + True + 7 + 2 + + + + + + + + + True + True + True + 0 + True + + + 1 + 2 + 6 + 7 + GTK_FILL + + + + + + True + 0 + Publish presence information: + + + 6 + 7 + GTK_FILL + + + + + + True + 0 + Send registration: + + + 1 + 2 + GTK_FILL + + + + + + True + True + 900 120 72000 1 10 10 + 1 + True + + + 1 + 2 + 2 + 3 + + + + + + True + 0 + Registration Period: + + + 2 + 3 + GTK_FILL + + + + + + True + True + 256 + * + sip: + + + 1 + 2 + 3 + 4 + + + + + + True + 0 + SIP Identity: + + + 3 + 4 + GTK_FILL + + + + + + True + 0 + SIP Proxy: + + + 4 + 5 + GTK_FILL + + + + + + True + True + 250 + * + sip: + + + 1 + 2 + 4 + 5 + + + + + + True + True + 256 + * + + + 1 + 2 + 5 + 6 + + + + + + True + 0 + Route (optional): + + + 5 + 6 + GTK_FILL + + + + + + True + True + True + 0 + True + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + + + True + Proxy/Registrar configuration box + + + label_item + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-help + True + -11 + + + + + True + True + True + gtk-ok + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + True + True + Edit contact information + True + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + + True + + + True + 6 + 0 + + + True + + + True + 4 + 2 + True + + + + + + + + + True + 0 + Subscribe policy: + + + 3 + 4 + GTK_FILL + + + + + + True + 0 + Proxy to use: + + + 2 + 3 + GTK_FILL + + + + + + True + 0 + Sip address: + + + 1 + 2 + + + + + + True + 0 + Name: + + + + + + + + True + True + * + + + 1 + 2 + + + + + + True + True + * + sip: + + + 1 + 2 + 1 + 2 + + + + + + + + True + True + Send subscription (see person's online status) + True + 0 + True + + + 1 + + + + + + + True + Contact information + + + label_item + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-help + True + -11 + + + + + True + True + True + gtk-cancel + True + -6 + + + 1 + + + + + True + True + True + gtk-ok + True + -5 + + + 2 + + + + + False + GTK_PACK_END + + + + + + + True + New incoming subscription + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + + True + + + True + + + True + gtk-dialog-warning + + + False + + + + + True + 14 + 9 + You have received a new subscription... + True + + + 1 + + + + + 2 + + + + + True + GTK_BUTTONBOX_SPREAD + + + True + True + True + -2 + + + True + 0 + 0 + + + True + 2 + + + True + gtk-stop + + + False + False + + + + + True + Refuse + True + + + False + False + 1 + + + + + + + + + + + True + True + True + -3 + + + True + 0 + 0 + + + True + 2 + + + True + gtk-jump-to + + + False + False + + + + + True + Accept + True + + + False + False + 1 + + + + + + + + + 1 + + + + + False + GTK_PACK_END + + + + + + + True + Authentication requested + True + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + + True + + + True + + + True + + + True + 16 + gtk-dialog-question + + + + + True + 29 + 14 + Authentication required for realm + GTK_JUSTIFY_CENTER + + + 1 + + + + + False + False + + + + + True + 5 + 2 + + + + + + + + + True + 0 + realm: + GTK_JUSTIFY_CENTER + + + GTK_EXPAND + + + + + + True + 0 + username: + GTK_JUSTIFY_CENTER + + + 1 + 2 + + + + + + + True + 0 + password: + GTK_JUSTIFY_CENTER + + + 2 + 3 + GTK_EXPAND + + + + + + True + 0 + userid: + GTK_JUSTIFY_CENTER + + + 3 + 4 + GTK_EXPAND | GTK_SHRINK + + + + + + True + True + * + + + 1 + 2 + 3 + 4 + + + + + + True + True + False + * + + + 1 + 2 + 2 + 3 + + + + + + True + True + * + + + 1 + 2 + 1 + 2 + + + + + + True + True + False + * + + + 1 + 2 + + + + + + 1 + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + True + True + gtk-ok + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + + + True + Linphone - Call history + 240 + 240 + True + linphone2.xpm + GDK_WINDOW_TYPE_HINT_DIALOG + + + + + True + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + False + False + + + + + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-close + True + -7 + + + + + False + GTK_PACK_END + + + + + + + True + Chat Room + 400 + 400 + True + linphone2.xpm + + + + True + + + True + True + GTK_SHADOW_IN + + + True + True + False + + + + + + + True + + + True + Text: + + + False + False + + + + + True + True + True + * + + + + 1 + + + + + False + 1 + + + + + True + True + gtk-close + True + 0 + + + + False + False + 2 + + + + + + + True + 5 + True + GDK_WINDOW_TYPE_HINT_NORMAL + Linphone + C: 2001 +Made in Old Europe + Linphone is a web-phone. +It is compatible with SIP and RTP protocols. + http://www.linphone.org + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Simon MORLAT +Aymeric Moizard +Sharath K Udupa + Simon MORLAT +Philippe Beau + it: Alberto Zanoni +de: Jean Jacques Sarton +fr: Simon Morlat +es: Jesus Benitez +ja: Yamaguchi Yoshiya +pl: obert Nasiadek <darkone@darkone.pl> +pt_BR: Rafael Caesar Lenzi <rc_lenzi@yahoo.com.br> +sv: Daniel Nylander <po@danielnylander.se> + linphone.png + + + + + + + False + GTK_PACK_END + + + + + + diff --git a/linphone/linphone2.glade b/linphone/linphone2.glade new file mode 100644 index 000000000..5b2464b91 --- /dev/null +++ b/linphone/linphone2.glade @@ -0,0 +1,6127 @@ + + + + + + + + + True + linphone + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + True + True + + + + 2 + True + GTK_SHADOW_OUT + + + + True + GTK_PACK_DIRECTION_LTR + GTK_PACK_DIRECTION_LTR + + + + True + Go + True + + + + + + + True + Address book + True + + + + + True + gnome-stock-book-open + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + GNOMEUIINFO_MENU_PREFERENCES_ITEM + + + + + + + True + Shows calls + Call history + True + + + + + True + gtk-justify-fill + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + + + + + + True + GNOMEUIINFO_MENU_EXIT_ITEM + + + + + + + + + + + True + GNOMEUIINFO_MENU_HELP_TREE + + + + + + + True + GNOMEUIINFO_MENU_ABOUT_ITEM + + + + + + + True + User manual + True + + + + + True + gtk-help + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + + + BONOBO_DOCK_TOP + 0 + 0 + 0 + BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL + + + + + + 9 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + False + 0 + + + + True + False + 0 + + + + 5 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + enter sip uri here + True + True + True + 0 + sip: + True + * + False + + + + + + + + True + Sip address: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + 15 + True + Shows the address book + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gnome-stock-book-open + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + ... + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + 0 + True + True + + + + + + True + False + 0 + + + + True + Proxy to use: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + True + False + 0 + + + + 8 + True + True + Call or +answer + True + GTK_RELIEF_NORMAL + True + + + + 0 + True + True + + + + + + 8 + True + True + Hangup +or refuse + True + GTK_RELIEF_NORMAL + True + + + + 0 + True + True + + + + + 0 + True + True + + + + + + 8 + True + True + Or chat ! + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + + + + True + True + GTK_RELIEF_NORMAL + True + True + False + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-jump-to + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Show more... + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + + True + True + True + True + GTK_POS_TOP + False + False + + + + True + False + 0 + + + + 11 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 2 + True + False + 0 + + + + True + Playback level: + False + False + GTK_JUSTIFY_LEFT + False + False + 7.45058015283e-09 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + GTK_POS_RIGHT + 0 + GTK_UPDATE_CONTINUOUS + False + 75 0 100 0 0 0 + + + + 0 + True + True + + + + + + True + Recording level: + False + False + GTK_JUSTIFY_LEFT + False + False + 7.45058015283e-09 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + GTK_POS_RIGHT + 0 + GTK_UPDATE_CONTINUOUS + False + 75 0 100 0 0 0 + + + + 0 + True + True + + + + + + True + Ring level: + False + False + GTK_JUSTIFY_LEFT + False + False + 7.45058015283e-09 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + GTK_POS_RIGHT + 0 + GTK_UPDATE_CONTINUOUS + False + 75 0 100 0 0 0 + + + + 0 + True + True + + + + + + + + True + Sound + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + False + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + True + Enable video + True + GTK_RELIEF_NORMAL + True + True + False + True + + + + 0 + False + False + + + + + + + + + + True + Video + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + False + + + + + False + True + + + + + + True + Controls + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + 11 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + True + Reachable + True + GTK_RELIEF_NORMAL + True + True + False + True + + + + 0 + False + False + + + + + + True + False + 0 + + + + True + True + Busy, I'll be back in + True + GTK_RELIEF_NORMAL + True + False + False + True + presence_reachable + + + + 0 + True + True + + + + + + True + The other party will be informed that you'll be back in X minutes + True + True + True + 0 + 5 + True + * + False + + + + 0 + False + False + + + + + + True + mn + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + 0 + False + True + + + + + + True + True + Away + True + GTK_RELIEF_NORMAL + True + False + False + True + presence_reachable + + + + 0 + False + False + + + + + + True + True + Do not disturb + True + GTK_RELIEF_NORMAL + True + False + False + True + presence_reachable + + + + 0 + False + False + + + + + + True + True + Moved temporarily + True + GTK_RELIEF_NORMAL + True + False + False + True + presence_reachable + + + + 0 + False + False + + + + + + True + True + Alternative service + True + GTK_RELIEF_NORMAL + True + False + False + True + presence_reachable + + + + 0 + False + False + + + + + + True + False + 0 + + + + True + URL: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + True + True + True + 0 + + True + * + False + + + + 0 + False + False + + + + + 0 + False + True + + + + + + + 0 + True + True + + + + + False + True + + + + + + True + Presence + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + 15 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + Press digits to send DTMFs. + True + True + True + 0 + + True + * + False + + + + 0 + False + False + + + + + + 14 + True + 4 + 3 + True + 10 + 10 + + + + True + True + 3 +def + True + GTK_RELIEF_NORMAL + True + + + + 2 + 3 + 0 + 1 + + + + + + True + True + 2 +abc + True + GTK_RELIEF_NORMAL + True + + + + 1 + 2 + 0 + 1 + + + + + + True + True + 1 + True + GTK_RELIEF_NORMAL + True + + + + 0 + 1 + 0 + 1 + + + + + + True + True + 4 +ghi + True + GTK_RELIEF_NORMAL + True + + + + 0 + 1 + 1 + 2 + + + + + + True + True + 5 +jkl + True + GTK_RELIEF_NORMAL + True + + + + 1 + 2 + 1 + 2 + + + + + + True + True + 6 +mno + True + GTK_RELIEF_NORMAL + True + + + + 2 + 3 + 1 + 2 + + + + + + True + True + 7 +pqrs + True + GTK_RELIEF_NORMAL + True + + + + 0 + 1 + 2 + 3 + + + + + + True + True + 8 +tuv + True + GTK_RELIEF_NORMAL + True + + + + 1 + 2 + 2 + 3 + + + + + + True + True + 9 +wxyz + True + GTK_RELIEF_NORMAL + True + + + + 2 + 3 + 2 + 3 + + + + + + True + True + * + True + GTK_RELIEF_NORMAL + True + + + + 0 + 1 + 3 + 4 + + + + + + True + True + 0 + True + GTK_RELIEF_NORMAL + True + + + + 1 + 2 + 3 + 4 + + + + + + True + True + # + True + GTK_RELIEF_NORMAL + True + + + + 2 + 3 + 3 + 4 + + + + + 0 + True + True + + + + + + + False + True + + + + + + True + DTMF + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + True + True + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_SHADOW_NONE + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + False + False + False + + + + + + 0 + True + True + + + + + + + + + False + True + + + + + + True + My online friends + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + 0 + True + True + + + + + + + + + 0 + True + True + + + + + + True + True + False + True + + + 0 + True + True + + + + + + 5 + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + linphone.png + C: 2001 +Made in Old Europe + Linphone is a web-phone. +It is compatible with SIP and RTP protocols. + Simon MORLAT +Aymeric Moizard +Sharath K Udupa + Simon MORLAT +Philippe Beau + cs: Klara Cihlarova, Petr Pisar +de: Jean-Jacques Sarton, Ursula Herles-Hartz +es: Jesus Benitez, Nelson Benitez +fr: Simon Morlat +it: Alberto Zanoni +ja: Yamaguchi Yoshiya +nl: Hendrik-Jan Heins +pl: Robert Nasiadek <darkone@darkone.pl> +pt_BR: Rafael Caesar Lenzi <rc_lenzi@yahoo.com.br> +sv: Daniel Nylander <po@danielnylander.se> + + + + True + Parameters + GTK_WIN_POS_NONE + False + False + False + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + + + + + True + True + True + True + GTK_POS_TOP + False + False + + + + True + False + 0 + + + + 6 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + Toggle this if you are on an ipv6 network and you wish linphone to use it. + True + Use IPv6 network (if available) + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + + + + + True + Global + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + 5 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + 6 + True + False + 0 + + + + True + These options is only for users in a private network, behind a gateway. If you are not in this situation, then leave this empty. + False + False + GTK_JUSTIFY_LEFT + True + False + 0.5 + 0.5 + 0 + 12 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + 3 + 2 + False + 0 + 0 + + + + True + True + No firewall + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + True + Use this STUN server to guess firewall address : + True + GTK_RELIEF_NORMAL + True + False + False + True + no_nat + + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + True + Specify firewall address manually: + True + GTK_RELIEF_NORMAL + True + False + False + True + no_nat + + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + + 1 + 2 + 2 + 3 + + + + + + + True + True + True + True + 0 + + True + * + False + + + + 1 + 2 + 1 + 2 + + + + + + 0 + False + False + + + + + + + + True + NAT traversal options (experimental) + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + 5 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 2 + 2 + False + 0 + 0 + + + + True + True + True + GTK_POS_RIGHT + 0 + GTK_UPDATE_CONTINUOUS + False + 150 60 512 10 0 0 + + + + 1 + 2 + 1 + 2 + 20 + expand + + + + + + True + True + 4 + 0 + True + GTK_UPDATE_ALWAYS + False + False + 7000 5000 65535 1 10 10 + + + + 1 + 2 + 0 + 1 + 20 + expand + + + + + + True + Number of buffered miliseconds (jitter compensation): + False + False + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + + + + + + + True + RTP port used for audio: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + + True + RTP properties + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + 5 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + RTP-RFC2833 is the recommended way. + True + Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + + + + + True + Other + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + False + True + + + + + + True + Network + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + True + False + 0 + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + 6 + 2 + False + 0 + 0 + + + + True + Playback sound device: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + expand + expand + + + + + + True + True + False + False + True + False + + + + True + True + False + True + 0 + + True + * + False + + + + + + + True + GTK_SELECTION_BROWSE + + + + True + + + + True + micro + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + True + + + + True + line + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + True + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + + + + 1 + 2 + 2 + 3 + + + + + + + + True + Capture sound device: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + + + + + + + + True + False + True + + + + 1 + 2 + 0 + 1 + fill + fill + + + + + + True + False + True + + + + 1 + 2 + 1 + 2 + fill + fill + + + + + + True + False + 0 + + + + True + 10 + Ring sound selection + False + True + False + GTK_FILE_CHOOSER_ACTION_OPEN + + + + + True + True + True + True + 0 + + True + * + False + + + + + 0 + True + True + + + + + + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gnome-stock-volume + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Listen + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 10 + False + False + + + + + 1 + 2 + 4 + 5 + fill + + + + + + True + Recording source: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + + + + + + + + True + Ring sound device + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 3 + 4 + expand + + + + + + + True + Ring sound: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 4 + 5 + + + + + + + + True + False + True + + + + 1 + 2 + 3 + 4 + fill + fill + + + + + + True + True + + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 1 + 2 + 5 + 6 + fill + + + + + + + True + Enable echo-canceler (cancels the echo heard by the remote party) + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 5 + 6 + + + + + 0 + True + True + + + + + + + + True + Sound properties + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + 0 + False + True + + + + + False + True + + + + + + True + Sound device + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 67 + + + + True + Run sip user agent on port: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + It is strongly recommended to use port 5060. + True + 4 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 5060 5000 65535 1 10 10 + + + + 32 + True + True + + + + + + + + True + SIP port + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + False + 0 + + + + True + Your sip address: + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + False + + + + + + True + sip: + False + False + GTK_JUSTIFY_RIGHT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + True + 0 + + True + * + False + + + + 0 + False + False + + + + + + True + @ + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + True + 0 + + True + * + False + + + + 0 + False + True + + + + + 0 + True + True + + + + + + True + True + Automatically guess a valid hostname + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + True + True + + + + + + + + True + Identity + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_OUT + GTK_CORNER_TOP_LEFT + + + + 100 + True + True + True + False + False + True + False + False + False + + + + + 0 + True + True + + + + + + 5 + True + GTK_BUTTONBOX_SPREAD + 0 + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-add + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Add proxy/registrar + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-jump-to + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Edit + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-cancel + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Remove + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + 0 + True + True + + + + + + + + True + Remote services + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-delete + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Clear all stored authentication information (username,password...) + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + + + True + Authentication information + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + False + True + + + + + + True + SIP + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + 10 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + 9 + True + False + 0 + + + + True + List of audio codecs, in order of preference: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 4 + False + False + + + + + + True + True + True + True + GTK_POS_TOP + False + False + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + True + True + False + False + False + + + + + False + True + + + + + + True + Audio codecs + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + True + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + False + False + False + + + + + False + True + + + + + + True + Video Codecs + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + 0 + True + True + + + + + + 10 + True + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + + + + True + True + True + gtk-go-up + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + gtk-go-down + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-apply + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Enable + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-cancel + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Disable + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + 0 + False + False + + + + + + True + 2 + 2 + True + 0 + 0 + + + + True + Upload bandwidth (kbit/sec): + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + Download bandwidth (kbit/sec): + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_IF_VALID + False + False + 0 0 100000 10 100 10 + + + + 1 + 2 + 0 + 1 + + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 0 0 100000 10 100 10 + + + + 1 + 2 + 1 + 2 + + + + + + 0 + False + True + + + + + 0 + True + True + + + + + + True + False + 0 + + + + True + Note: Codecs in red are not usable regarding to your connection type to the internet. + False + False + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 15 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + 8 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + No information availlable + False + False + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 10 + 10 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + + + + True + Codec information + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 5 + True + True + + + + + 0 + True + False + + + + + + + + True + Audio and video codecs + False + False + GTK_JUSTIFY_LEFT + False + False + 0.52999997139 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + False + True + + + + + + True + Codecs + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + 0 + True + True + + + + + + True + Address Book + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 305 + True + False + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_SPREAD + + + + True + GTK_BUTTONBOX_DEFAULT_STYLE + 11 + + + + True + True + True + gtk-add + True + GTK_RELIEF_HALF + True + + + + + + + True + True + True + gtk-delete + True + GTK_RELIEF_HALF + True + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-justify-center + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Edit + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-quit + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Select + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + + 0 + False + False + GTK_PACK_END + + + + + + 12 + True + False + 0 + + + + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + GTK_SHADOW_IN + + + + True + True + True + False + False + True + False + False + False + + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + + + True + Information + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + -7 + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + False + 0 + + + + True + User is not reachable at the moment but he invites you to contact him using the following alternate ressource: + False + False + GTK_JUSTIFY_CENTER + True + False + 0.5 + 0.5 + 25 + 5 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 10 + True + True + + + + + + 12 + True + True + None. + True + GTK_RELIEF_NONE + True + + + + + 0 + False + False + + + + + 0 + True + True + + + + + + + + True + True + Proxy/Registrar configuration box + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + True + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-help + True + GTK_RELIEF_NORMAL + True + -11 + + + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + True + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 8 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + 7 + 2 + False + 0 + 0 + + + + True + True + + True + GTK_RELIEF_NORMAL + True + True + False + True + + + 1 + 2 + 1 + 2 + fill + + + + + + + True + Route (optional): + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 5 + 6 + fill + + + + + + + True + True + True + True + 256 + + True + * + False + + + 1 + 2 + 5 + 6 + + + + + + + True + True + True + True + 250 + sip: + True + * + False + + + 1 + 2 + 4 + 5 + + + + + + + True + SIP Proxy: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 4 + 5 + fill + + + + + + + True + SIP Identity: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 3 + 4 + fill + + + + + + + True + True + True + True + 256 + sip: + True + * + False + + + 1 + 2 + 3 + 4 + + + + + + + True + Registration Period: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + True + 1 + 0 + True + GTK_UPDATE_ALWAYS + False + False + 900 120 72000 1 10 10 + + + 1 + 2 + 2 + 3 + + + + + + + True + Send registration: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + Publish presence information: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 6 + 7 + fill + + + + + + + True + True + + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 1 + 2 + 6 + 7 + fill + + + + + + + + + True + Proxy/Registrar configuration box + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + + + True + True + Edit contact information + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-help + True + GTK_RELIEF_NORMAL + True + -11 + + + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + True + -6 + + + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + True + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + 6 + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + 4 + 2 + True + 0 + 0 + + + + True + True + True + True + 0 + sip: + True + * + False + + + 1 + 2 + 1 + 2 + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 0 + 1 + + + + + + + True + Name: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + + + + + + + True + Sip address: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + + + + + + + True + Proxy to use: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + Subscribe policy: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 3 + 4 + fill + + + + + + 0 + True + True + + + + + + True + True + Send subscription (see person's online status) + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + True + True + + + + + + + + True + Contact information + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + + + True + New incoming subscription + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_SPREAD + + + + True + True + True + GTK_RELIEF_NORMAL + True + -2 + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-stop + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Refuse + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + + True + True + True + GTK_RELIEF_NORMAL + True + -3 + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-jump-to + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Accept + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + False + 0 + + + + True + gtk-dialog-warning + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + True + + + + + + True + You have received a new subscription... + False + False + GTK_JUSTIFY_LEFT + True + False + 0.5 + 0.5 + 14 + 9 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + 0 + True + True + + + + + + + + True + Authentication requested + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-cancel + True + GTK_RELIEF_NORMAL + True + -6 + + + + + + True + True + True + gtk-ok + True + GTK_RELIEF_NORMAL + True + -5 + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + False + 0 + + + + True + False + 0 + + + + True + gtk-dialog-question + 4 + 0.5 + 0.5 + 16 + 0 + + + 0 + True + True + + + + + + True + Authentication required for realm + False + False + GTK_JUSTIFY_CENTER + False + False + 0.5 + 0.5 + 29 + 14 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + 0 + False + False + + + + + + True + 5 + 2 + False + 0 + 0 + + + + True + True + False + True + 0 + + True + * + False + + + 1 + 2 + 0 + 1 + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 1 + 2 + + + + + + + True + True + True + False + 0 + + True + * + False + + + 1 + 2 + 2 + 3 + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 3 + 4 + + + + + + + True + userid: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 3 + 4 + expand|shrink + + + + + + + True + password: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + expand + + + + + + + True + username: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + + + + + + + + True + realm: + False + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + expand + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + + + True + Linphone - Call history + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 240 + 240 + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + False + True + + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + -7 + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_NONE + False + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + + + + True + Chat Room + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 400 + 400 + True + True + linphone2.xpm + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + + True + False + 0 + + + + True + True + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_NONE + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + + True + False + 0 + + + + True + Text: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + True + True + True + 0 + + True + * + False + + + + 0 + True + True + + + + + 0 + False + True + + + + + + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + + + + + diff --git a/linphone/lpc10-1.5/.cvsignore b/linphone/lpc10-1.5/.cvsignore new file mode 100644 index 000000000..fe404a3f7 --- /dev/null +++ b/linphone/lpc10-1.5/.cvsignore @@ -0,0 +1,6 @@ +*.lo +.deps +.libs +Makefile +Makefile.in +liblpc10.la diff --git a/linphone/lpc10-1.5/FAQ b/linphone/lpc10-1.5/FAQ new file mode 100644 index 000000000..559c251b9 --- /dev/null +++ b/linphone/lpc10-1.5/FAQ @@ -0,0 +1,102 @@ + Information on 2400 bps LPC and 4800 bps CELP speech coders + for Frequently Asked Questions lists (audio-formats, comp.compression) + +The U.S. DoD's Federal-Standard-1016 based 4800 bps code excited linear +prediction voice coder version 3.2 (CELP 3.2) Fortran and C simulation +source codes are available for worldwide distribution (on DOS +diskettes, but configured to compile on Sun SPARC stations) from NTIS +and DTIC. Example input and processed speech files are included. A +Technical Information Bulletin (TIB), "Details to Assist in +Implementation of Federal Standard 1016 CELP," and the official +standard, "Federal Standard 1016, Telecommunications: Analog to +Digital Conversion of Radio Voice by 4,800 bit/second Code Excited +Linear Prediction (CELP)," are also available. + +This is available through the National Technical Information Service: + +NTIS +U.S. Department of Commerce +5285 Port Royal Road +Springfield, VA 22161 +USA +(703) 487-4650 + +The "AD" ordering number for the CELP software is AD M000 118 +(US$ 90.00) and for the TIB it's AD A256 629 (US$ 17.50). The LPC-10 +standard, described below, is FIPS Pub 137 (US$ 12.50). There is a +$3.00 shipping charge on all U.S. orders. The telephone number for +their automated system is 703-487-4650, or 703-487-4600 if you'd prefer +to talk with a real person. + +(U.S. DoD personnel and contractors can receive the package from the +Defense Technical Information Center: DTIC, Building 5, Cameron +Station, Alexandria, VA 22304-6145. Their telephone number is +703-274-7633.) + +The following articles describe the Federal-Standard-1016 4.8-kbps CELP +coder (it's unnecessary to read more than one): + +Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. Welch, +"The Federal Standard 1016 4800 bps CELP Voice Coder," Digital Signal +Processing, Academic Press, 1991, Vol. 1, No. 3, p. 145-155. + +Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. Welch, +"The DoD 4.8 kbps Standard (Proposed Federal Standard 1016)," +in Advances in Speech Coding, ed. Atal, Cuperman and Gersho, +Kluwer Academic Publishers, 1991, Chapter 12, p. 121-133. + +Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. Welch, "The +Proposed Federal Standard 1016 4800 bps Voice Coder: CELP," Speech +Technology Magazine, April/May 1990, p. 58-64. + + +The U.S. DoD's Federal-Standard-1015/NATO-STANAG-4198 based 2400 bps +linear prediction coder (LPC-10) was republished as a Federal +Information Processing Standards Publication 137 (FIPS Pub 137). +It is described in: + +Thomas E. Tremain, "The Government Standard Linear Predictive Coding +Algorithm: LPC-10," Speech Technology Magazine, April 1982, p. 40-49. + +There is also a section about FS-1015 in the book: +Panos E. Papamichalis, Practical Approaches to Speech Coding, +Prentice-Hall, 1987. + +The voicing classifier used in the enhanced LPC-10 (LPC-10e) is described in: +Campbell, Joseph P., Jr. and T. E. Tremain, "Voiced/Unvoiced Classification +of Speech with Applications to the U.S. Government LPC-10E Algorithm," +Proceedings of the IEEE International Conference on Acoustics, Speech, and +Signal Processing, 1986, p. 473-6. + +Copies of the official standard +"Federal Standard 1016, Telecommunications: Analog to Digital Conversion +of Radio Voice by 4,800 bit/second Code Excited Linear Prediction (CELP)" +are available for US$ 5.00 each from: + +GSA Federal Supply Service Bureau +Specification Section, Suite 8100 +470 E. L'Enfant Place, S.W. +Washington, DC 20407 +(202)755-0325 + +Realtime DSP code for FS-1015 and FS-1016 is sold by: + +John DellaMorte +DSP Software Engineering +165 Middlesex Tpk, Suite 206 +Bedford, MA 01730 +USA +1-617-275-3733 +1-617-275-4323 (fax) +dspse.bedford@channel1.com + +DSP Software Engineering's FS-1016 code can run on a DSP Research's Tiger 30 +(a PC board with a TMS320C3x and analog interface suited to development work). + +DSP Research +1095 E. Duane Ave. +Sunnyvale, CA 94086 +USA +(408)773-1042 +(408)736-3451 (fax) + diff --git a/linphone/lpc10-1.5/Makefile.am b/linphone/lpc10-1.5/Makefile.am new file mode 100644 index 000000000..289649bab --- /dev/null +++ b/linphone/lpc10-1.5/Makefile.am @@ -0,0 +1,49 @@ +EXTRA_DIST=README README-1.0 FAQ README.new + +noinst_LTLIBRARIES=liblpc10.la + + +liblpc10_la_SOURCES=f2clib.c lpc10.h f2c.h\ + analys.c \ + bsynz.c \ + chanwr.c \ + dcbias.c \ + decode.c \ + deemp.c \ + difmag.c \ + dyptrk.c \ + encode.c \ + energy.c \ + ham84.c \ + hp100.c \ + invert.c \ + irc2pc.c \ + ivfilt.c \ + lpcdec.c \ + lpcenc.c \ + lpcini.c \ + lpfilt.c \ + median.c \ + mload.c \ + onset.c \ + pitsyn.c \ + placea.c \ + placev.c \ + preemp.c \ + prepro.c \ + random.c \ + rcchk.c \ + synths.c \ + tbdm.c \ + voicin.c \ + vparms.c + +liblpc10_la_LIBADD=-lm + +#noinst_PROGRAMS=bitio + +#bitio_SOURCES=bitio.c lpc10_wrapper.h + +#bitio_LDADD=liblpc10.la + +AM_CFLAGS=-w diff --git a/linphone/lpc10-1.5/README b/linphone/lpc10-1.5/README new file mode 100644 index 000000000..b31e79315 --- /dev/null +++ b/linphone/lpc10-1.5/README @@ -0,0 +1,81 @@ + U.S. Department of Defense + LPC-10 2400 bps Voice Coder + Release 1.5 + October 1997 + +(Note that this release 1.5 is not from any "official" source. It is +from Andy Fingerhut. Contact information below.) + +This package is available from: + +http://www.arl.wustl.edu/~jaf/lpc/lpc10-1.5.tar.gz + + +New in release 1.5: + +Just some minor fixes to sample applications "nuke" and "unnuke" that +caused them not to work correctly on compilers with 16 bit int's. +This was only a bug in the sample application code, not in the LPC-10 +library itself. + +NEW IN RELEASE 1.4! + +You can now compress (or decompress) multiple audio streams +"simultaneously", by alternating the compression (or decompression) of +frames for each audio stream. Only the C version supports this +feature, but who really cared whether the Fortran version supported +this or not, eh? + + +Contents: + README - This file + README-1.0 - The original README file from Release 1.0 + FAQ - Frequently Asked Questions items for LPC and CELP + lpc55 - modified Fortran code for LPC-10 Version 55 + README - summary of modifications made + README.f2c - hints on installing f2c on some machines, + and notes on the f2c invocation options used + README.jaf - hints on using the LPC-10 coder from a C application + RCS - Revision Control System directory containing + master files for all sources, showing the steps + of changes that I made to the original 1.0 sources. + lpc55-C - Hand-modified C version of code, most of + which was created by running f2c on the + Fortran code in directory lpc55 above. I'm + fairly certain that the C code from the 1.0 + release was out of date with respect to the + Fortran code, so it was not included in this + distribution. + data - Sample speech files, containing: + dam9.spd - Sample input speech file + dam9-out.spd - Speech processed by modified Fortran code. + This is identical to dam9_lpc55.spd from + release 1.0, except for 180 0 samples at the + beginning, and many samples here and there + that are off by 1, probably due to different + rounding of reals. + abtool_1.2 - Sun GUI tool for playing listening comparisons + between speech files (this is a beta version) + misc + bin - Several useful shell scripts for audio on Sun machines + README - Description of audio file formats + fortran-locals - Some files I made when determining whether local + variables in Fortran subroutines and functions + were like C "static" local variables or not. + gcc-2.6.0-bug - A program that demonstrates a bug in GCC 2.6.0 + on the Solaris 2.4 machine siesta.cs.wustl.edu. + I don't know how widespread this problem is, + but it does have an unpleasant side effect if + GCC 2.6.0 is used to compile f2c. + +See also the file README-1.0 for some other useful details. + + +Andy Fingerhut +Applied Research Laboratory <-- this line is optional if +Washington University, Campus Box 1045/Bryan 509 you have limited space +One Brookings Drive +Saint Louis, MO 63130-4899 + +jaf@arl.wustl.edu +http://www.arl.wustl.edu/~jaf/ diff --git a/linphone/lpc10-1.5/README-1.0 b/linphone/lpc10-1.5/README-1.0 new file mode 100644 index 000000000..7fb7871dc --- /dev/null +++ b/linphone/lpc10-1.5/README-1.0 @@ -0,0 +1,47 @@ + U.S. Department of Defense + LPC-10 2400 bps Voice Coder + Release 1.0 + October 1993 + + +Contents: + README - This file + FAQ - Frequently Asked Questions items for LPC and CELP + lpc55 - Fortran code for LPC-10 Version 55 + lpc55-C - C code for LPC-10 + data - Sample speech files, containing: + dam9.spd - Sample input speech file + dam9_lpc55.spd - Speech processed by LPC-10 + abtool_1.2 - Sun GUI tool for playing listening comparisons + between speech files (this is a beta version) + + The distribution file has been compressed with the GNU compression +program gzip version 1.2.3, available from archives such as ftp.uu.net and +wuarchive.wustl.edu. To unpack it, use the commands: + + gunzip lpc-1.0.tar (uncompress the archive file) + tar xvf lpc-1.0.tar (extract the contents of the archive) + +(For distribution on pcfs floppy disks (IBM PC format), the file names may + not appear exactly as shown above.) + + Documentation on using the above programs is included in README files +in each directory. Documentation describing the internal operation of +LPC-10 is currently available only in hardcopy format. We will include +more extensive documentation with future releases of this package. + + All development of LPC-10 has been done in Fortran, so the Fortran +code has been written for flexible and easy use in a research environment. +The C version was translated from the Fortran to assist in porting LPC +to Digital Signal Processors (DSPs), and does not have the debugging +features or I/O flexiblility of the Fortran version. Both versions +have been tested on a Sun SPARCstation-10 running Solaris 2.2 and +SunOS 4.1.2. + + The speech files are in 16 bit linear format, sampled at 8000 Hz. There +are no headers on these files, so some manipulation may be required to +play them on your system. The following alias will play speech files on +the Sun speakerbox: + + alias play 'audioconvert -i pcm16,mono,raw,r=8k -f sun \!* | audioplay' + play dam9.spd diff --git a/linphone/lpc10-1.5/README.new b/linphone/lpc10-1.5/README.new new file mode 100644 index 000000000..30abe4c97 --- /dev/null +++ b/linphone/lpc10-1.5/README.new @@ -0,0 +1,89 @@ +Tue Aug 20 16:19:51 CDT 1996 +Andy Fingerhut (jaf@arl.wustl.edu) + +In release 1.4, there are quite a few hand modifications to the C code +that was automatically created from the Fortran code with f2c. They +are all summarized in change log comments at the beginning of the +changed files. All of the original files from f2c were checked in to +RCS before modification, so it is possible to see exactly what changes +were made, for the extremely curious. That precaution was also for my +benefit, in case I ever recompile the Fortran sources, and want to +make similar changes to that new C source code. + +Below is the README file for this directory included with the 1.3 +release of the LPC-10 package. A few parts of it are a little out of +date, but it is correct for the most part. + + +Sun Jul 7 15:30:31 CDT 1996 +Andy Fingerhut (jaf@arl.wustl.edu) + +To create the LPC-10 library, copy the appropriate makefile to the +proper name for easy use, e.g., for Unix, copy makefile.unx to the +file "Makefile". The file makefile.dos has been used with some +version of the 'nmake' utility that comes with the Microsoft C +compiler (the same one used for Nautilus v1.5a, which I believe +specifies Microsoft C version 7.0 or later). + +Then edit the file lpc10.h in the directory above. It should already +be set up to work properly on any Unix compiler for which "int" is 32 +bits and "short" is 16 bits, and under the Microsoft C compiler +configured so that "long" is 32 bits and "int" is 16 bits. There must +be a typedef for the two types INT32 and INT16 in that file. You +should choose types that compile to those sizes using your compiler, +because there are places in the LPC-10 code that expect INT16's to +have exactly 16 bits (at least, I *think* they must be no larger), and +INT32's to have exactly 32 bits. + + +A few notes on how these files were created +------------------------------------------- + +(This section is mostly for my benefit, so I can remember what I did. +You don't need to read it if you just want to use this package. It +might be useful to read it if you change the Fortran sources and want +to recreate a usable library of C sources. -- Andy) + +These C sources were created automatically from the Fortran sources +using f2c, for the most part. Listed below are the extra +modifications that were made after this automatic conversion. Many of +them were made so that it was not necessary to install f2c in order to +use this LPC-10 coder. + +1. + +Put all of those files that were necessary for only the coder, rather +than an application that uses the coder, into this subdirectory called +lpc10. + +2. + +Copied f2c.h from the f2c distribution into this subdirectory. Some +modifications were made to the "typedef" statements in this file, to +explicitly indicate the sizes (in bits) that different integer types +should be. The types INT32 and INT16 must be defined in a file called +lpc10.h in the directory above. Created the file f2clib.c, containing +only the functions pow_ii(), r_sign(), and i_nint() from the f2c +library. + +3. + +The f2c output originally had a file called contrl_com.c, that defined +a small structure containing a few variables that were used in many +different functions of the LPC10 code. Every file containing +functions that used it defined it as "extern", while contrl_com.c +actually allocated storage for the structure. Bill Dorsey, one of the +lead developers of Nautilus, said that the Microsoft C compiler had +problems either compiling this file, or linking it with all of the +other compiled files, so he just eliminated that file and removed the +"extern" keyword from the one of the files that declared it that way. +The file chosen (arbitrarily) was analys.c. + +4. + +Copied the makefiles for Unix and Microsoft C from the Nautilus v1.5a +distribution into the lpc10 directory. Modified them to take out +references to Nautilus. These makefiles don't create an executable, +but a library of compiled functions called liblpc10.a (Unix) or +LPC10.LIB (DOS). This library can be used when linking an executable +that calls the functions lpcini_(), lpcenc_(), and lpcdec_(). diff --git a/linphone/lpc10-1.5/analys.c b/linphone/lpc10-1.5/analys.c new file mode 100644 index 000000000..6e8ece4ab --- /dev/null +++ b/linphone/lpc10-1.5/analys.c @@ -0,0 +1,617 @@ +/* + +$Log: analys.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:16:01 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:29:08 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int analys_(real *speech, integer *voice, integer *pitch, real *rms, real *rc, struct lpc10_encoder_state *st); +/* comlen contrl_ 12 */ +/*:ref: preemp_ 14 5 6 6 4 6 6 */ +/*:ref: onset_ 14 7 6 4 4 4 4 4 4 */ +/*:ref: placev_ 14 11 4 4 4 4 4 4 4 4 4 4 4 */ +/*:ref: lpfilt_ 14 4 6 6 4 4 */ +/*:ref: ivfilt_ 14 5 6 6 4 4 6 */ +/*:ref: tbdm_ 14 8 6 4 4 4 6 4 4 4 */ +/*:ref: voicin_ 14 12 4 6 6 4 4 6 6 4 6 4 4 4 */ +/*:ref: dyptrk_ 14 6 6 4 4 4 4 4 */ +/*:ref: placea_ 14 9 4 4 4 4 4 4 4 4 4 */ +/*:ref: dcbias_ 14 3 4 6 6 */ +/*:ref: energy_ 14 3 4 6 6 */ +/*:ref: mload_ 14 6 4 4 4 6 6 6 */ +/*:ref: invert_ 14 4 4 6 6 6 */ +/*:ref: rcchk_ 14 3 4 6 6 */ +/*:ref: initonset_ 14 0 */ +/*:ref: initvoicin_ 14 0 */ +/*:ref: initdyptrk_ 14 0 */ +/* Rerunning f2c -P may change prototypes or declarations. */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* Table of constant values */ + +static integer c__10 = 10; +static integer c__181 = 181; +static integer c__720 = 720; +static integer c__3 = 3; +static integer c__90 = 90; +static integer c__156 = 156; +static integer c__307 = 307; +static integer c__462 = 462; +static integer c__312 = 312; +static integer c__60 = 60; +static integer c__1 = 1; + +/* ****************************************************************** */ + +/* ANALYS Version 55 */ + +/* $Log: analys.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:16:01 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:29:08 jaf + * Initial revision + * */ +/* Revision 1.9 1996/05/23 19:41:07 jaf */ +/* Commented out some unnecessary lines that were reading uninitialized */ +/* values. */ + +/* Revision 1.8 1996/03/27 23:57:55 jaf */ +/* Added some comments about which indices of the local buffers INBUF, */ +/* LPBUF, etc., get read or modified by some of the subroutine calls. I */ +/* just did this while trying to figure out the discrepancy between the */ +/* embedded code compiled with all local variables implicitly saved, and */ +/* without. */ + +/* I added some debugging write statements in hopes of finding a problem. */ +/* None of them ever printed anything while running with the long input */ +/* speech file dam9.spd provided in the distribution. */ + +/* Revision 1.7 1996/03/27 18:06:20 jaf */ +/* Commented out access to MAXOSP, which is just a debugging variable */ +/* that was defined in the COMMON block CONTRL in contrl.fh. */ + +/* Revision 1.6 1996/03/26 19:31:33 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.5 1996/03/21 15:19:35 jaf */ +/* Added comments for ENTRY PITDEC. */ + +/* Revision 1.4 1996/03/19 20:54:27 jaf */ +/* Added a line to INITANALYS. See comments there. */ + +/* Revision 1.3 1996/03/19 20:52:49 jaf */ +/* Rearranged the order of the local variables quite a bit, to separate */ +/* them into groups of "constants", "locals that don't need to be saved */ +/* from one call to the next", and "local that do need to be saved from */ +/* one call to the next". */ + +/* Several locals in the last set should have been given initial values, */ +/* but weren't. I gave them all initial values of 0. */ + +/* Added a separate ENTRY INITANALYS that initializes all local state */ +/* that should be, and also calls the corresponding entries of the */ +/* subroutines called by ANALYS that also have local state. */ + +/* There used to be DATA statements in ANALYS. I got rid of most of */ +/* them, and added a local logical variable FIRST that calls the entry */ +/* INITANALYS on the first call to ANALYS. This is just so that one need */ +/* not remember to call INITANALYS first in order for the state to be */ +/* initialized. */ + +/* Revision 1.2 1996/03/11 23:29:32 jaf */ +/* Added several comments with my own personal questions about the */ +/* Fortran 77 meaning of the parameters passed to the subroutine PREEMP. */ + +/* Revision 1.1 1996/02/07 14:42:29 jaf */ +/* Initial revision */ + + +/* ****************************************************************** */ + +/* SUBROUTINE ANALYS */ + +/* Input: */ +/* SPEECH */ +/* Indices 1 through LFRAME read. */ +/* Output: */ +/* VOICE */ +/* Indices 1 through 2 written. */ +/* PITCH */ +/* Written in subroutine DYPTRK, and then perhaps read and written */ +/* some more. */ +/* RMS */ +/* Written. */ +/* RC */ +/* Indices 1 through ORDER written (ORDER defined in contrl.fh). */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITANALYS. */ + + +/* ENTRY PITDEC */ + +/* Input: */ +/* PITCH - Encoded pitch index */ +/* Output: */ +/* PTAU - Decoded pitch period */ + +/* This entry has no local state. It accesses a "constant" array */ +/* declared in ANALYS. */ + +/* Subroutine */ int analys_(real *speech, integer *voice, integer + *pitch, real *rms, real *rc, struct lpc10_encoder_state *st) +{ + /* Initialized data */ + + static integer tau[60] = { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, + 35,36,37,38,39,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, + 74,76,78,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136, + 140,144,148,152,156 }; + static integer buflim[4] = { 181,720,25,720 }; + static real precoef = .9375f; + + /* System generated locals */ + integer i__1; + + /* Local variables */ + real amdf[60]; + integer half; + real abuf[156]; + real *bias; + extern /* Subroutine */ int tbdm_(real *, integer *, integer *, integer *, + real *, integer *, integer *, integer *); + integer *awin; + integer midx, ewin[6] /* was [2][3] */; + real ivrc[2], temp; + real *zpre; + integer *vwin; + integer i__, j, lanal; + extern /* Subroutine */ int rcchk_(integer *, real *, real *), mload_( + integer *, integer *, integer *, real *, real *, real *); + real *inbuf, *pebuf; + real *lpbuf, *ivbuf; + real *rcbuf; + integer *osbuf; + extern /* Subroutine */ int onset_(real *, integer *, integer *, integer * + , integer *, integer *, integer *, struct lpc10_encoder_state *); + integer *osptr; + extern /* Subroutine */ placea_(integer *, integer * + , integer *, integer *, integer *, integer *, integer *, integer * + , integer *), dcbias_(integer *, real *, real *), placev_(integer + *, integer *, integer *, integer *, integer *, integer *, integer + *, integer *, integer *, integer *, integer *); + integer ipitch; + integer *obound; + extern /* Subroutine */ int preemp_(real *, real *, integer *, real *, + real *), voicin_(integer *, real *, real *, integer *, integer *, + real *, real *, integer *, real *, integer *, integer *, integer *, + struct lpc10_encoder_state *); + integer *voibuf; + integer mintau; + real *rmsbuf; + extern /* Subroutine */ int lpfilt_(real *, real *, integer *, integer *), + ivfilt_(real *, real *, integer *, integer *, real *), energy_( + integer *, real *, real *), invert_(integer *, real *, real *, + real *); + integer minptr, maxptr; + extern /* Subroutine */ int dyptrk_(real *, integer *, integer *, integer + *, integer *, integer *, struct lpc10_encoder_state *); + real phi[100] /* was [10][10] */, psi[10]; + +/* $Log: analys.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:16:01 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:29:08 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments to ANALYS */ +/* $Log: analys.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:16:01 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:29:08 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Arguments to entry PITDEC (below) */ +/* Parameters/constants */ +/* Constants */ +/* NF = Number of frames */ +/* AF = Frame in which analysis is done */ +/* OSLEN = Length of the onset buffer */ +/* LTAU = Number of pitch lags */ +/* SBUFL, SBUFH = Start and end index of speech buffers */ +/* LBUFL, LBUFH = Start and end index of LPF speech buffer */ +/* MINWIN, MAXWIN = Min and Max length of voicing (and analysis) windows +*/ +/* PWLEN, PWINH, PWINL = Length, upper and lower limits of pitch window + */ +/* DVWINL, DVWINH = Default lower and upper limits of voicing window */ +/* The tables TAU and BUFLIM, and the variable PRECOEF, are not */ +/* Fortran PARAMETER's, but they are initialized with DATA */ +/* statements, and never modified. Thus, they need not have SAVE */ +/* statements for them to keep their values from one invocation to +*/ +/* the next. */ +/* Local variables that need not be saved */ +/* Local state */ +/* Data Buffers */ +/* INBUF Raw speech (with DC bias removed each frame) */ +/* PEBUF Preemphasized speech */ +/* LPBUF Low pass speech buffer */ +/* IVBUF Inverse filtered speech */ +/* OSBUF Indexes of onsets in speech buffers */ +/* VWIN Voicing window indices */ +/* AWIN Analysis window indices */ +/* EWIN Energy window indices */ +/* VOIBUF Voicing decisions on windows in VWIN */ +/* RMSBUF RMS energy */ +/* RCBUF Reflection Coefficients */ + +/* Pitch is handled separately from the above parameters. */ +/* The following variables deal with pitch: */ +/* MIDX Encoded initial pitch estimate for analysis frame */ +/* IPITCH Initial pitch computed for frame AF (decoded from MIDX) */ +/* PITCH The encoded pitch value (index into TAU) for the present */ +/* frame (delayed and smoothed by Dyptrack) */ + /* Parameter adjustments */ + if (speech) { + --speech; + } + if (voice) { + --voice; + } + if (rc) { + --rc; + } + + /* Function Body */ + +/* Calculations are done on future frame due to requirements */ +/* of the pitch tracker. Delay RMS and RC's 2 frames to give */ +/* current frame parameters on return. */ +/* Update all buffers */ + + inbuf = &(st->inbuf[0]); + pebuf = &(st->pebuf[0]); + lpbuf = &(st->lpbuf[0]); + ivbuf = &(st->ivbuf[0]); + bias = &(st->bias); + osbuf = &(st->osbuf[0]); + osptr = &(st->osptr); + obound = &(st->obound[0]); + vwin = &(st->vwin[0]); + awin = &(st->awin[0]); + voibuf = &(st->voibuf[0]); + rmsbuf = &(st->rmsbuf[0]); + rcbuf = &(st->rcbuf[0]); + zpre = &(st->zpre); + + i__1 = 720 - contrl_1.lframe; + for (i__ = 181; i__ <= i__1; ++i__) { + inbuf[i__ - 181] = inbuf[contrl_1.lframe + i__ - 181]; + pebuf[i__ - 181] = pebuf[contrl_1.lframe + i__ - 181]; + } + i__1 = 540 - contrl_1.lframe; + for (i__ = 229; i__ <= i__1; ++i__) { + ivbuf[i__ - 229] = ivbuf[contrl_1.lframe + i__ - 229]; + } + i__1 = 720 - contrl_1.lframe; + for (i__ = 25; i__ <= i__1; ++i__) { + lpbuf[i__ - 25] = lpbuf[contrl_1.lframe + i__ - 25]; + } + j = 1; + i__1 = (*osptr) - 1; + for (i__ = 1; i__ <= i__1; ++i__) { + if (osbuf[i__ - 1] > contrl_1.lframe) { + osbuf[j - 1] = osbuf[i__ - 1] - contrl_1.lframe; + ++j; + } + } + *osptr = j; + voibuf[0] = voibuf[2]; + voibuf[1] = voibuf[3]; + for (i__ = 1; i__ <= 2; ++i__) { + vwin[(i__ << 1) - 2] = vwin[(i__ + 1 << 1) - 2] - contrl_1.lframe; + vwin[(i__ << 1) - 1] = vwin[(i__ + 1 << 1) - 1] - contrl_1.lframe; + awin[(i__ << 1) - 2] = awin[(i__ + 1 << 1) - 2] - contrl_1.lframe; + awin[(i__ << 1) - 1] = awin[(i__ + 1 << 1) - 1] - contrl_1.lframe; +/* EWIN(*,J) is unused for J .NE. AF, so the following shift is +*/ +/* unnecessary. It also causes error messages when the C versio +n */ +/* of the code created from this by f2c is run with Purify. It +*/ +/* correctly complains that uninitialized memory is being read. +*/ +/* EWIN(1,I) = EWIN(1,I+1) - LFRAME */ +/* EWIN(2,I) = EWIN(2,I+1) - LFRAME */ + obound[i__ - 1] = obound[i__]; + voibuf[i__ * 2] = voibuf[(i__ + 1) * 2]; + voibuf[(i__ << 1) + 1] = voibuf[(i__ + 1 << 1) + 1]; + rmsbuf[i__ - 1] = rmsbuf[i__]; + i__1 = contrl_1.order; + for (j = 1; j <= i__1; ++j) { + rcbuf[j + i__ * 10 - 11] = rcbuf[j + (i__ + 1) * 10 - 11]; + } + } +/* Copy input speech, scale to sign+12 bit integers */ +/* Remove long term DC bias. */ +/* If the average value in the frame was over 1/4096 (after current +*/ +/* BIAS correction), then subtract that much more from samples in */ +/* next frame. If the average value in the frame was under */ +/* -1/4096, add 1/4096 more to samples in next frame. In all other +*/ +/* cases, keep BIAS the same. */ + temp = 0.f; + i__1 = contrl_1.lframe; + for (i__ = 1; i__ <= i__1; ++i__) { + inbuf[720 - contrl_1.lframe + i__ - 181] = speech[i__] * 4096.f - + (*bias); + temp += inbuf[720 - contrl_1.lframe + i__ - 181]; + } + if (temp > (real) contrl_1.lframe) { + *bias += 1; + } + if (temp < (real) (-contrl_1.lframe)) { + *bias += -1; + } +/* Place Voicing Window */ + i__ = 721 - contrl_1.lframe; + preemp_(&inbuf[i__ - 181], &pebuf[i__ - 181], &contrl_1.lframe, &precoef, + zpre); + onset_(pebuf, osbuf, osptr, &c__10, &c__181, &c__720, &contrl_1.lframe, st); + +/* MAXOSP is just a debugging variable. */ + +/* MAXOSP = MAX( MAXOSP, OSPTR ) */ + + placev_(osbuf, osptr, &c__10, &obound[2], vwin, &c__3, &contrl_1.lframe, + &c__90, &c__156, &c__307, &c__462); +/* The Pitch Extraction algorithm estimates the pitch for a frame +*/ +/* of speech by locating the minimum of the average magnitude difference + */ +/* function (AMDF). The AMDF operates on low-pass, inverse filtered */ +/* speech. (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR +*/ +/* filter and the inverse filter is a 2nd-order LPC filter.) The pitch +*/ +/* estimate is later refined by dynamic programming (DYPTRK). However, +*/ +/* since some of DYPTRK's parameters are a function of the voicing */ +/* decisions, a voicing decision must precede the final pitch estimation. +*/ +/* See subroutines LPFILT, IVFILT, and TBDM. */ +/* LPFILT reads indices LBUFH-LFRAME-29 = 511 through LBUFH = 720 */ +/* of INBUF, and writes indices LBUFH+1-LFRAME = 541 through LBUFH +*/ +/* = 720 of LPBUF. */ + lpfilt_(&inbuf[228], &lpbuf[384], &c__312, &contrl_1.lframe); +/* IVFILT reads indices (PWINH-LFRAME-7) = 353 through PWINH = 540 +*/ +/* of LPBUF, and writes indices (PWINH-LFRAME+1) = 361 through */ +/* PWINH = 540 of IVBUF. */ + ivfilt_(&lpbuf[204], ivbuf, &c__312, &contrl_1.lframe, ivrc); +/* TBDM reads indices PWINL = 229 through */ +/* (PWINL-1)+MAXWIN+(TAU(LTAU)-TAU(1))/2 = 452 of IVBUF, and writes +*/ +/* indices 1 through LTAU = 60 of AMDF. */ + tbdm_(ivbuf, &c__156, tau, &c__60, amdf, &minptr, &maxptr, &mintau); +/* Voicing decisions are made for each half frame of input speech. +*/ +/* An initial voicing classification is made for each half of the */ +/* analysis frame, and the voicing decisions for the present frame */ +/* are finalized. See subroutine VOICIN. */ +/* The voicing detector (VOICIN) classifies the input signal as */ +/* unvoiced (including silence) or voiced using the AMDF windowed */ +/* maximum-to-minimum ratio, the zero crossing rate, energy measures, */ +/* reflection coefficients, and prediction gains. */ +/* The pitch and voicing rules apply smoothing and isolated */ +/* corrections to the pitch and voicing estimates and, in the process, +*/ +/* introduce two frames of delay into the corrected pitch estimates and +*/ +/* voicing decisions. */ + for (half = 1; half <= 2; ++half) { + voicin_(&vwin[4], inbuf, lpbuf, buflim, &half, &amdf[minptr - 1], & + amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, &c__3, st); + } +/* Find the minimum cost pitch decision over several frames */ +/* given the current voicing decision and the AMDF array */ + dyptrk_(amdf, &c__60, &minptr, &voibuf[7], pitch, &midx, st); + ipitch = tau[midx - 1]; +/* Place spectrum analysis and energy windows */ + placea_(&ipitch, voibuf, &obound[2], &c__3, vwin, awin, ewin, & + contrl_1.lframe, &c__156); +/* Remove short term DC bias over the analysis window, Put result in ABUF +*/ + lanal = awin[5] + 1 - awin[4]; + dcbias_(&lanal, &pebuf[awin[4] - 181], abuf); +/* ABUF(1:LANAL) is now defined. It is equal to */ +/* PEBUF(AWIN(1,AF):AWIN(2,AF)) corrected for short term DC bias. */ +/* Compute RMS over integer number of pitch periods within the */ +/* analysis window. */ +/* Note that in a hardware implementation this computation may be */ +/* simplified by using diagonal elements of PHI computed by MLOAD. */ + i__1 = ewin[5] - ewin[4] + 1; + energy_(&i__1, &abuf[ewin[4] - awin[4]], &rmsbuf[2]); +/* Matrix load and invert, check RC's for stability */ + mload_(&contrl_1.order, &c__1, &lanal, abuf, phi, psi); + invert_(&contrl_1.order, phi, psi, &rcbuf[20]); + rcchk_(&contrl_1.order, &rcbuf[10], &rcbuf[20]); +/* Set return parameters */ + voice[1] = voibuf[2]; + voice[2] = voibuf[3]; + *rms = rmsbuf[0]; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + rc[i__] = rcbuf[i__ - 1]; + } + return 0; +} /* analys_ */ diff --git a/linphone/lpc10-1.5/bitio.c b/linphone/lpc10-1.5/bitio.c new file mode 100644 index 000000000..86c38f0c9 --- /dev/null +++ b/linphone/lpc10-1.5/bitio.c @@ -0,0 +1,20 @@ +#include "lpc10_wrapper.c" +#include + + + +int main() +{ + FILE *input; + int i; + unsigned char buffer[10]; + INT32 bits[54]; + + input=fopen("/tmp/dam9.bits","r"); + if (input==NULL) printf("error opening file\n"); + fread(buffer,7,1,input); + read_bits(buffer,bits,54); + for (i=0;i<54;i++) printf("%i ",bits[i]); + fclose(input); + return(0); +} \ No newline at end of file diff --git a/linphone/lpc10-1.5/bsynz.c b/linphone/lpc10-1.5/bsynz.c new file mode 100644 index 000000000..4cec9d14e --- /dev/null +++ b/linphone/lpc10-1.5/bsynz.c @@ -0,0 +1,423 @@ +/* + +$Log: bsynz.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:18:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:58 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int bsynz_(real *coef, integer *ip, integer *iv, real *sout, real *rms, real *ratio, real *g2pass, struct lpc10_decoder_state *st); +/* comlen contrl_ 12 */ +/*:ref: random_ 4 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* ***************************************************************** */ + +/* BSYNZ Version 54 */ + +/* $Log: bsynz.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:18:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:58 jaf + * Initial revision + * */ +/* Revision 1.4 1996/03/27 18:11:22 jaf */ +/* Changed the range of NOISE printed out in the debugging statements, */ +/* even though they are commented out. I didn't discover this until I */ +/* tried comparing two different versions of the LPC-10 coder, each with */ +/* full tracing enabled. */ + +/* Revision 1.3 1996/03/26 19:33:23 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.2 1996/03/20 17:12:54 jaf */ +/* Added comments about which indices of array arguments are read or */ +/* written. */ + +/* Rearranged local variable declarations to indicate which need to be */ +/* saved from one invocation to the next. Added entry INITBSYNZ to */ +/* reinitialize the local state variables, if desired. */ + +/* Revision 1.1 1996/02/07 14:43:15 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Synthesize One Pitch Epoch */ + +/* Input: */ +/* COEF - Predictor coefficients */ +/* Indices 1 through ORDER read. */ +/* IP - Pitch period (number of samples to synthesize) */ +/* IV - Voicing for the current epoch */ +/* RMS - Energy for the current epoch */ +/* RATIO - Energy slope for plosives */ +/* G2PASS- Sharpening factor for 2 pass synthesis */ +/* Output: */ +/* SOUT - Synthesized speech */ +/* Indices 1 through IP written. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITBSYNZ. */ + +/* Subroutine */ int bsynz_(real *coef, integer *ip, integer *iv, + real *sout, real *rms, real *ratio, real *g2pass, + struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + integer *ipo; + real *rmso; + static integer kexc[25] = { 8,-16,26,-48,86,-162,294,-502,718,-728,184, + 672,-610,-672,184,728,718,502,294,162,86,48,26,16,8 }; + real *exc; + real *exc2; + real *lpi1; + real *lpi2; + real *lpi3; + real *hpi1; + real *hpi2; + real *hpi3; + + /* System generated locals */ + integer i__1, i__2; + real r__1, r__2; + + /* Builtin functions */ + double sqrt(doublereal); + + /* Local variables */ + real gain, xssq; + integer i__, j, k; + real noise[166], pulse; + integer px; + real sscale; + extern integer random_(struct lpc10_decoder_state *); + real xy, sum, ssq; + real lpi0, hpi0; + +/* $Log: bsynz.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:18:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:58 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments */ +/* $Log: bsynz.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:18:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:58 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Function return value definitions */ +/* Parameters/constants */ +/* KEXC is not a Fortran PARAMETER, but it is an array initialized +*/ +/* with a DATA statement that is never modified. */ +/* Local variables that need not be saved */ +/* NOISE is declared with range (1:MAXPIT+MAXORD), but only indices +*/ +/* ORDER+1 through ORDER+IP are ever used, and I think that IP */ +/* .LE. MAXPIT. Why not declare it to be in the range (1:MAXPIT) */ +/* and use that range? */ +/* Local state */ +/* I believe that only indices 1 through ORDER of EXC need to be */ +/* saved from one invocation to the next, but we may as well save */ +/* the whole array. */ +/* None of these local variables were given initial values in the */ +/* original code. I'm guessing that 0 is a reasonable initial */ +/* value for all of them. */ + /* Parameter adjustments */ + if (coef) { + --coef; + } + if (sout) { + --sout; + } + + /* Function Body */ + ipo = &(st->ipo); + exc = &(st->exc[0]); + exc2 = &(st->exc2[0]); + lpi1 = &(st->lpi1); + lpi2 = &(st->lpi2); + lpi3 = &(st->lpi3); + hpi1 = &(st->hpi1); + hpi2 = &(st->hpi2); + hpi3 = &(st->hpi3); + rmso = &(st->rmso_bsynz); + +/* MAXPIT+MAXORD=166 */ +/* Calculate history scale factor XY and scale filter state */ +/* Computing MIN */ + r__1 = *rmso / (*rms + 1e-6f); + xy = min(r__1,8.f); + *rmso = *rms; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + exc2[i__ - 1] = exc2[*ipo + i__ - 1] * xy; + } + *ipo = *ip; + if (*iv == 0) { +/* Generate white noise for unvoiced */ + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + exc[contrl_1.order + i__ - 1] = (real) (random_(st) / 64); + } +/* Impulse doublet excitation for plosives */ +/* (RANDOM()+32768) is in the range 0 to 2**16-1. Therefore the + */ +/* following expression should be evaluated using integers with +at */ +/* least 32 bits (16 isn't enough), and PX should be in the rang +e */ +/* ORDER+1+0 through ORDER+1+(IP-2) .EQ. ORDER+IP-1. */ + px = (random_(st) + 32768) * (*ip - 1) / 65536 + contrl_1.order + 1; + r__1 = *ratio / 4 * 1.f; + pulse = r__1 * 342; + if (pulse > 2e3f) { + pulse = 2e3f; + } + exc[px - 1] += pulse; + exc[px] -= pulse; +/* Load voiced excitation */ + } else { + sscale = sqrt((real) (*ip)) / 6.928f; + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + exc[contrl_1.order + i__ - 1] = 0.f; + if (i__ <= 25) { + exc[contrl_1.order + i__ - 1] = sscale * kexc[i__ - 1]; + } + lpi0 = exc[contrl_1.order + i__ - 1]; + r__2 = exc[contrl_1.order + i__ - 1] * .125f + *lpi1 * .75f; + r__1 = r__2 + *lpi2 * .125f; + exc[contrl_1.order + i__ - 1] = r__1 + *lpi3 * 0.f; + *lpi3 = *lpi2; + *lpi2 = *lpi1; + *lpi1 = lpi0; + } + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + noise[contrl_1.order + i__ - 1] = random_(st) * 1.f / 64; + hpi0 = noise[contrl_1.order + i__ - 1]; + r__2 = noise[contrl_1.order + i__ - 1] * -.125f + *hpi1 * .25f; + r__1 = r__2 + *hpi2 * -.125f; + noise[contrl_1.order + i__ - 1] = r__1 + *hpi3 * 0.f; + *hpi3 = *hpi2; + *hpi2 = *hpi1; + *hpi1 = hpi0; + } + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + exc[contrl_1.order + i__ - 1] += noise[contrl_1.order + i__ - 1]; + } + } +/* Synthesis filters: */ +/* Modify the excitation with all-zero filter 1 + G*SUM */ + xssq = 0.f; + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + k = contrl_1.order + i__; + sum = 0.f; + i__2 = contrl_1.order; + for (j = 1; j <= i__2; ++j) { + sum += coef[j] * exc[k - j - 1]; + } + sum *= *g2pass; + exc2[k - 1] = sum + exc[k - 1]; + } +/* Synthesize using the all pole filter 1 / (1 - SUM) */ + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + k = contrl_1.order + i__; + sum = 0.f; + i__2 = contrl_1.order; + for (j = 1; j <= i__2; ++j) { + sum += coef[j] * exc2[k - j - 1]; + } + exc2[k - 1] = sum + exc2[k - 1]; + xssq += exc2[k - 1] * exc2[k - 1]; + } +/* Save filter history for next epoch */ + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + exc[i__ - 1] = exc[*ip + i__ - 1]; + exc2[i__ - 1] = exc2[*ip + i__ - 1]; + } +/* Apply gain to match RMS */ + r__1 = *rms * *rms; + ssq = r__1 * *ip; + gain = sqrt(ssq / xssq); + i__1 = *ip; + for (i__ = 1; i__ <= i__1; ++i__) { + sout[i__] = gain * exc2[contrl_1.order + i__ - 1]; + } + return 0; +} /* bsynz_ */ diff --git a/linphone/lpc10-1.5/chanwr.c b/linphone/lpc10-1.5/chanwr.c new file mode 100644 index 000000000..7a2712ec3 --- /dev/null +++ b/linphone/lpc10-1.5/chanwr.c @@ -0,0 +1,225 @@ +/* + +$Log: chanwr.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:20:24 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Revision 1.1 1996/08/19 22:40:31 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int chanwr_(integer *order, integer *ipitv, integer *irms, integer *irc, integer *ibits, struct lpc10_encoder_state *st); +extern int chanrd_(integer *order, integer *ipitv, integer *irms, integer *irc, integer *ibits); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* *********************************************************************** */ + +/* CHANL Version 49 */ + +/* $Log: chanwr.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:20:24 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Revision 1.1 1996/08/19 22:40:31 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/21 15:14:57 jaf */ +/* Added comments about which indices of argument arrays are read or */ +/* written, and about the one bit of local state in CHANWR. CHANRD */ +/* has no local state. */ + +/* Revision 1.2 1996/03/13 18:55:10 jaf */ +/* Comments added explaining which of the local variables of this */ +/* subroutine need to be saved from one invocation to the next, and which */ +/* do not. */ + +/* Revision 1.1 1996/02/07 14:43:31 jaf */ +/* Initial revision */ + + +/* *********************************************************************** */ + +/* CHANWR: */ +/* Place quantized parameters into bitstream */ + +/* Input: */ +/* ORDER - Number of reflection coefficients (not really variable) */ +/* IPITV - Quantized pitch/voicing parameter */ +/* IRMS - Quantized energy parameter */ +/* IRC - Quantized reflection coefficients */ +/* Indices 1 through ORDER read. */ +/* Output: */ +/* IBITS - Serial bitstream */ +/* Indices 1 through 54 written. */ +/* Bit 54, the SYNC bit, alternates from one call to the next. */ + +/* Subroutine CHANWR maintains one bit of local state from one call to */ +/* the next, in the variable ISYNC. I believe that this one bit is only */ +/* intended to allow a receiver to resynchronize its interpretation of */ +/* the bit stream, by looking for which of the 54 bits alternates every */ +/* frame time. This is just a simple framing mechanism that is not */ +/* useful when other, higher overhead framing mechanisms are used to */ +/* transmit the coded frames. */ + +/* I'm not going to make an entry to reinitialize this bit, since it */ +/* doesn't help a receiver much to know whether the first sync bit is a 0 */ +/* or a 1. It needs to examine several frames in sequence to have */ +/* reasonably good assurance that its framing is correct. */ + + +/* CHANRD: */ +/* Reconstruct parameters from bitstream */ + +/* Input: */ +/* ORDER - Number of reflection coefficients (not really variable) */ +/* IBITS - Serial bitstream */ +/* Indices 1 through 53 read (SYNC bit is ignored). */ +/* Output: */ +/* IPITV - Quantized pitch/voicing parameter */ +/* IRMS - Quantized energy parameter */ +/* IRC - Quantized reflection coefficients */ +/* Indices 1 through ORDER written */ + +/* Entry CHANRD has no local state. */ + + + +/* IBITS is 54 bits of LPC data ordered as follows: */ +/* R1-0, R2-0, R3-0, P-0, A-0, */ +/* R1-1, R2-1, R3-1, P-1, A-1, */ +/* R1-2, R4-0, R3-2, A-2, P-2, R4-1, */ +/* R1-3, R2-2, R3-3, R4-2, A-3, */ +/* R1-4, R2-3, R3-4, R4-3, A-4, */ +/* P-3, R2-4, R7-0, R8-0, P-4, R4-4, */ +/* R5-0, R6-0, R7-1,R10-0, R8-1, */ +/* R5-1, R6-1, R7-2, R9-0, P-5, */ +/* R5-2, R6-2,R10-1, R8-2, P-6, R9-1, */ +/* R5-3, R6-3, R7-3, R9-2, R8-3, SYNC */ +/* Subroutine */ int chanwr_0_(int n__, integer *order, integer *ipitv, + integer *irms, integer *irc, integer *ibits, + struct lpc10_encoder_state *st) +{ + /* Initialized data */ + + integer *isync; + static integer bit[10] = { 2,4,8,8,8,8,16,16,16,16 }; + static integer iblist[53] = { 13,12,11,1,2,13,12,11,1,2,13,10,11,2,1,10, + 13,12,11,10,2,13,12,11,10,2,1,12,7,6,1,10,9,8,7,4,6,9,8,7,5,1,9,8, + 4,6,1,5,9,8,7,5,6 }; + + /* System generated locals */ + integer i__1; + + /* Local variables */ + integer itab[13], i__; + +/* Arguments */ +/* Parameters/constants */ +/* These arrays are not Fortran PARAMETER's, but they are defined */ +/* by DATA statements below, and their contents are never altered. +*/ +/* Local variables that need not be saved */ +/* Local state */ +/* ISYNC is only used by CHANWR, not by ENTRY CHANRD. */ + + /* Parameter adjustments */ + --irc; + --ibits; + + /* Function Body */ + switch(n__) { + case 1: goto L_chanrd; + } + + isync = &(st->isync); + +/* *********************************************************************** + */ +/* Place quantized parameters into bitstream */ +/* *********************************************************************** + */ +/* Place parameters into ITAB */ + itab[0] = *ipitv; + itab[1] = *irms; + itab[2] = 0; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + itab[i__ + 2] = irc[*order + 1 - i__] & 32767; + } +/* Put 54 bits into IBITS array */ + for (i__ = 1; i__ <= 53; ++i__) { + ibits[i__] = itab[iblist[i__ - 1] - 1] & 1; + itab[iblist[i__ - 1] - 1] /= 2; + } + ibits[54] = *isync & 1; + *isync = 1 - *isync; + return 0; +/* *********************************************************************** + */ +/* Reconstruct parameters from bitstream */ +/* *********************************************************************** + */ + +L_chanrd: +/* Reconstruct ITAB */ + for (i__ = 1; i__ <= 13; ++i__) { + itab[i__ - 1] = 0; + } + for (i__ = 1; i__ <= 53; ++i__) { + itab[iblist[54 - i__ - 1] - 1] = (itab[iblist[54 - i__ - 1] - 1] << 1) + + ibits[54 - i__]; + } +/* Sign extend RC's */ + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + if ((itab[i__ + 2] & bit[i__ - 1]) != 0) { + itab[i__ + 2] -= bit[i__ - 1] << 1; + } + } +/* Restore variables */ + *ipitv = itab[0]; + *irms = itab[1]; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + irc[i__] = itab[*order + 4 - i__ - 1]; + } + return 0; +} /* chanwr_ */ + +/* Subroutine */ int chanwr_(integer *order, integer *ipitv, integer *irms, + integer *irc, integer *ibits, struct lpc10_encoder_state *st) +{ + return chanwr_0_(0, order, ipitv, irms, irc, ibits, st); + } + +/* Subroutine */ int chanrd_(integer *order, integer *ipitv, integer *irms, + integer *irc, integer *ibits) +{ + return chanwr_0_(1, order, ipitv, irms, irc, ibits, 0); + } diff --git a/linphone/lpc10-1.5/dcbias.c b/linphone/lpc10-1.5/dcbias.c new file mode 100644 index 000000000..60d41e9ae --- /dev/null +++ b/linphone/lpc10-1.5/dcbias.c @@ -0,0 +1,95 @@ +/* + +$Log: dcbias.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:40:23 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int dcbias_(integer *len, real *speech, real *sigout); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* DCBIAS Version 50 */ + +/* $Log: dcbias.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:40:23 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/18 21:19:22 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:44:53 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:44:21 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Calculate and remove DC bias from buffer. */ + +/* Input: */ +/* LEN - Length of speech buffers */ +/* SPEECH - Input speech buffer */ +/* Indices 1 through LEN read. */ +/* Output: */ +/* SIGOUT - Output speech buffer */ +/* Indices 1 through LEN written */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int dcbias_(integer *len, real *speech, real *sigout) +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + real bias; + integer i__; + +/* Arguments */ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + --sigout; + --speech; + + /* Function Body */ + bias = 0.f; + i__1 = *len; + for (i__ = 1; i__ <= i__1; ++i__) { + bias += speech[i__]; + } + bias /= *len; + i__1 = *len; + for (i__ = 1; i__ <= i__1; ++i__) { + sigout[i__] = speech[i__] - bias; + } + return 0; +} /* dcbias_ */ + diff --git a/linphone/lpc10-1.5/decode.c b/linphone/lpc10-1.5/decode.c new file mode 100644 index 000000000..8e2abb325 --- /dev/null +++ b/linphone/lpc10-1.5/decode.c @@ -0,0 +1,589 @@ +/* + +$Log: decode.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:22:39 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:38 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int decode_(integer *ipitv, integer *irms, integer *irc, integer *voice, integer *pitch, real *rms, real *rc, struct lpc10_decoder_state *st); +/* comlen contrl_ 12 */ +/*:ref: ham84_ 14 3 4 4 4 */ +/*:ref: median_ 4 3 4 4 4 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* Table of constant values */ + +static integer c__2 = 2; + +/* ***************************************************************** */ + +/* DECODE Version 54 */ + +/* $Log: decode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:22:39 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:38 jaf + * Initial revision + * */ +/* Revision 1.5 1996/05/23 20:06:03 jaf */ +/* Assigned PITCH a "default" value on the first call, since otherwise it */ +/* would be left uninitialized. */ + +/* Revision 1.4 1996/03/26 19:35:18 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.3 1996/03/21 21:10:50 jaf */ +/* Added entry INITDECODE to reinitialize the local state of subroutine */ +/* DECODE. */ + +/* Revision 1.2 1996/03/21 21:04:50 jaf */ +/* Determined which local variables should be saved from one invocation */ +/* to the next, and guessed initial values for some that should have been */ +/* saved, but weren't given initial values. Many of the arrays are */ +/* "constants", and many local variables are only used if the "global" */ +/* variable CORRP is .TRUE. */ + +/* Added comments explaining which indices of array arguments are read or */ +/* written. */ + +/* Revision 1.1 1996/02/12 03:21:10 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* This subroutine provides error correction and decoding */ +/* for all LPC parameters */ + +/* Input: */ +/* IPITV - Index value of pitch */ +/* IRMS - Coded Energy */ +/* CORRP - Error correction: */ +/* If FALSE, parameters are decoded directly with no delay. If TRUE, */ +/* most important parameter bits are protected by Hamming code and */ +/* median smoothed. This requires an additional frame of delay. */ +/* Input/Output: */ +/* IRC - Coded Reflection Coefficients */ +/* Indices 1 through ORDER always read, then written. */ +/* Output: */ +/* VOICE - Half frame voicing decisions */ +/* Indices 1 through 2 written. */ +/* PITCH - Decoded pitch */ +/* RMS - Energy */ +/* RC - Reflection coefficients */ +/* Indices 1 through ORDER written. */ + +/* NOTE: Zero RC's should be done more directly, but this would affect */ +/* coded parameter printout. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITDECODE. */ + +/* Subroutine */ int decode_(integer *ipitv, integer *irms, + integer *irc, integer *voice, integer *pitch, real *rms, real *rc, + struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + logical *first; + static integer ethrs = 2048; + static integer ethrs1 = 128; + static integer ethrs2 = 1024; + static integer ethrs3 = 2048; + static integer ivtab[32] = { 24960,24960,24960,24960,25480,25480,25483, + 25480,16640,1560,1560,1560,16640,1816,1563,1560,24960,24960,24859, + 24856,26001,25881,25915,25913,1560,1560,7800,3640,1561,1561,3643, + 3641 }; + static real corth[32] /* was [4][8] */ = { 32767.f,10.f,5.f,0.f, + 32767.f,8.f,4.f,0.f,32.f,6.4f,3.2f,0.f,32.f,6.4f,3.2f,0.f,32.f, + 11.2f,6.4f,0.f,32.f,11.2f,6.4f,0.f,16.f,5.6f,3.2f,0.f,16.f,5.6f, + 3.2f,0.f }; + static integer detau[128] = { 0,0,0,3,0,3,3,31,0,3,3,21,3,3,29,30,0,3,3, + 20,3,25,27,26,3,23,58,22,3,24,28,3,0,3,3,3,3,39,33,32,3,37,35,36, + 3,38,34,3,3,42,46,44,50,40,48,3,54,3,56,3,52,3,3,1,0,3,3,108,3,78, + 100,104,3,84,92,88,156,80,96,3,3,74,70,72,66,76,68,3,62,3,60,3,64, + 3,3,1,3,116,132,112,148,152,3,3,140,3,136,3,144,3,3,1,124,120,128, + 3,3,3,3,1,3,3,3,1,3,1,1,1 }; + static integer rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420, + 384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102, + 92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15, + 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }; + static integer detab7[32] = { 4,11,18,25,32,39,46,53,60,66,72,77,82,87,92, + 96,101,104,108,111,114,115,117,119,121,122,123,124,125,126,127, + 127 }; + static real descl[8] = { .6953f,.625f,.5781f,.5469f,.5312f,.5391f,.4688f, + .3828f }; + integer *ivp2h; + static integer deadd[8] = { 1152,-2816,-1536,-3584,-1280,-2432,768,-1920 } + ; + static integer qb[8] = { 511,511,1023,1023,1023,1023,2047,4095 }; + static integer nbit[10] = { 8,8,5,5,4,4,4,4,3,2 }; + static integer zrc[10] = { 0,0,0,0,0,3,0,2,0,0 }; + static integer bit[5] = { 2,4,8,16,32 }; + integer *iovoic; + integer *iavgp; + integer *iptold; + integer *erate; + integer *drc; + integer *dpit; + integer *drms; + + /* System generated locals */ + integer i__1, i__2; + + /* Builtin functions */ + integer pow_ii(integer *, integer *); + + /* Local variables */ + extern /* Subroutine */ int ham84_(integer *, integer *, integer *); + integer ipit, iout, i__, icorf, index, ivoic, ixcor, i1, i2, i4; + extern integer median_(integer *, integer *, integer *); + integer ishift, errcnt, lsb; + +/* $Log: decode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:22:39 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:38 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments */ +/* $Log: decode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:22:39 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:38 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Function return value definitions */ + +/* Parameters/constants */ + +/* The variables below that are not Fortran PARAMETER's are */ +/* initialized with DATA statements, and then never modified. */ +/* The following are used regardless of CORRP's value. */ + +/* DETAU, NBIT, QB, DEADD, DETAB7, RMST, DESCL */ + +/* The following are used only if CORRP is .TRUE. */ + +/* ETHRS, ETHRS1, ETHRS2, ETHRS3, IVTAB, BIT, CORTH, ZRC */ + +/* Local variables that need not be saved */ + +/* The following are used regardless of CORRP's value */ +/* The following are used only if CORRP is .TRUE. */ + +/* Local state */ + +/* The following are used regardless of CORRP's value */ +/* The following are used only if CORRP is .TRUE. */ +/* I am guessing the initial values for IVP2H, IOVOIC, DRC, DPIT, */ +/* and DRMS. They should be checked to see if they are reasonable. +*/ +/* I'm also guessing for ERATE, but I think 0 is the right initial +*/ +/* value. */ + /* Parameter adjustments */ + if (irc) { + --irc; + } + if (voice) { + --voice; + } + if (rc) { + --rc; + } + + /* Function Body */ + + iptold = &(st->iptold); + first = &(st->first); + ivp2h = &(st->ivp2h); + iovoic = &(st->iovoic); + iavgp = &(st->iavgp); + erate = &(st->erate); + drc = &(st->drc[0]); + dpit = &(st->dpit[0]); + drms = &(st->drms[0]); + +/* DATA statements for "constants" defined above. */ +/* IF (LISTL.GE.3) WRITE(FDEBUG,800) IPITV,IRMS,(IRC(J),J=1,ORDER) */ +/* 800 FORMAT(1X,' <>',T32,6X,I6,I5,T50,10I8) */ +/* If no error correction, do pitch and voicing then jump to decode */ + i4 = detau[*ipitv]; + if (! contrl_1.corrp) { + voice[1] = 1; + voice[2] = 1; + if (*ipitv <= 1) { + voice[1] = 0; + } + if (*ipitv == 0 || *ipitv == 2) { + voice[2] = 0; + } + *pitch = i4; + if (*pitch <= 4) { + *pitch = *iptold; + } + if (voice[1] == 1 && voice[2] == 1) { + *iptold = *pitch; + } + if (voice[1] != voice[2]) { + *pitch = *iptold; + } + goto L900; + } +/* Do error correction pitch and voicing */ + if (i4 > 4) { + dpit[0] = i4; + ivoic = 2; + *iavgp = (*iavgp * 15 + i4 + 8) / 16; + } else { + ivoic = i4; + dpit[0] = *iavgp; + } + drms[0] = *irms; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + drc[i__ * 3 - 3] = irc[i__]; + } +/* Determine index to IVTAB from V/UV decision */ +/* If error rate is high then use alternate table */ + index = (*ivp2h << 4) + (*iovoic << 2) + ivoic + 1; + i1 = ivtab[index - 1]; + ipit = i1 & 3; + icorf = i1 / 8; + if (*erate < ethrs) { + icorf /= 64; + } +/* Determine error rate: 4=high 1=low */ + ixcor = 4; + if (*erate < ethrs3) { + ixcor = 3; + } + if (*erate < ethrs2) { + ixcor = 2; + } + if (*erate < ethrs1) { + ixcor = 1; + } +/* Voice/unvoice decision determined from bits 0 and 1 of IVTAB */ + voice[1] = icorf / 2 & 1; + voice[2] = icorf & 1; +/* Skip decoding on first frame because present data not yet available */ + if (*first) { + *first = FALSE_; +/* Assign PITCH a "default" value on the first call, since */ +/* otherwise it would be left uninitialized. The two lines +*/ +/* below were copied from above, since it seemed like a */ +/* reasonable thing to do for the first call. */ + *pitch = i4; + if (*pitch <= 4) { + *pitch = *iptold; + } + goto L500; + } +/* If bit 4 of ICORF is set then correct RMS and RC(1) - RC(4). */ +/* Determine error rate and correct errors using a Hamming 8,4 code */ +/* during transition or unvoiced frame. If IOUT is negative, */ +/* more than 1 error occurred, use previous frame's parameters. */ + if ((icorf & bit[3]) != 0) { + errcnt = 0; + lsb = drms[1] & 1; + index = (drc[22] << 4) + drms[1] / 2; + ham84_(&index, &iout, &errcnt); + drms[1] = drms[2]; + if (iout >= 0) { + drms[1] = (iout << 1) + lsb; + } + for (i__ = 1; i__ <= 4; ++i__) { + if (i__ == 1) { + i1 = ((drc[25] & 7) << 1) + (drc[28] & 1); + } else { + i1 = drc[(9 - i__) * 3 - 2] & 15; + } + i2 = drc[(5 - i__) * 3 - 2] & 31; + lsb = i2 & 1; + index = (i1 << 4) + i2 / 2; + ham84_(&index, &iout, &errcnt); + if (iout >= 0) { + iout = (iout << 1) + lsb; + if ((iout & 16) == 16) { + iout += -32; + } + } else { + iout = drc[(5 - i__) * 3 - 1]; + } + drc[(5 - i__) * 3 - 2] = iout; + } +/* Determine error rate */ + *erate = *erate * .96875f + errcnt * 102; + } +/* Get unsmoothed RMS, RC's, and PITCH */ + *irms = drms[1]; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + irc[i__] = drc[i__ * 3 - 2]; + } + if (ipit == 1) { + dpit[1] = dpit[2]; + } + if (ipit == 3) { + dpit[1] = dpit[0]; + } + *pitch = dpit[1]; +/* If bit 2 of ICORF is set then smooth RMS and RC's, */ + if ((icorf & bit[1]) != 0) { + if ((i__1 = drms[1] - drms[0], (real) abs(i__1)) >= corth[ixcor + 3] + && (i__2 = drms[1] - drms[2], (real) abs(i__2)) >= corth[ + ixcor + 3]) { + *irms = median_(&drms[2], &drms[1], drms); + } + for (i__ = 1; i__ <= 6; ++i__) { + if ((i__1 = drc[i__ * 3 - 2] - drc[i__ * 3 - 3], (real) abs(i__1)) + >= corth[ixcor + (i__ + 2 << 2) - 5] && (i__2 = drc[i__ * + 3 - 2] - drc[i__ * 3 - 1], (real) abs(i__2)) >= corth[ + ixcor + (i__ + 2 << 2) - 5]) { + irc[i__] = median_(&drc[i__ * 3 - 1], &drc[i__ * 3 - 2], &drc[ + i__ * 3 - 3]); + } + } + } +/* If bit 3 of ICORF is set then smooth pitch */ + if ((icorf & bit[2]) != 0) { + if ((i__1 = dpit[1] - dpit[0], (real) abs(i__1)) >= corth[ixcor - 1] + && (i__2 = dpit[1] - dpit[2], (real) abs(i__2)) >= corth[ + ixcor - 1]) { + *pitch = median_(&dpit[2], &dpit[1], dpit); + } + } +/* If bit 5 of ICORF is set then RC(5) - RC(10) are loaded with */ +/* values so that after quantization bias is removed in decode */ +/* the values will be zero. */ +L500: + if ((icorf & bit[4]) != 0) { + i__1 = contrl_1.order; + for (i__ = 5; i__ <= i__1; ++i__) { + irc[i__] = zrc[i__ - 1]; + } + } +/* House keeping - one frame delay */ + *iovoic = ivoic; + *ivp2h = voice[2]; + dpit[2] = dpit[1]; + dpit[1] = dpit[0]; + drms[2] = drms[1]; + drms[1] = drms[0]; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + drc[i__ * 3 - 1] = drc[i__ * 3 - 2]; + drc[i__ * 3 - 2] = drc[i__ * 3 - 3]; + } +L900: +/* IF (LISTL.GE.3)WRITE(FDEBUG,801)VOICE,PITCH,IRMS,(IRC(J),J=1,ORDER) */ +/* 801 FORMAT(1X,'<>',T32,2I3,I6,I5,T50,10I8) */ +/* Decode RMS */ + *irms = rmst[(31 - *irms) * 2]; +/* Decode RC(1) and RC(2) from log-area-ratios */ +/* Protect from illegal coded value (-16) caused by bit errors */ + for (i__ = 1; i__ <= 2; ++i__) { + i2 = irc[i__]; + i1 = 0; + if (i2 < 0) { + i1 = 1; + i2 = -i2; + if (i2 > 15) { + i2 = 0; + } + } + i2 = detab7[i2 * 2]; + if (i1 == 1) { + i2 = -i2; + } + ishift = 15 - nbit[i__ - 1]; + irc[i__] = i2 * pow_ii(&c__2, &ishift); + } +/* Decode RC(3)-RC(10) to sign plus 14 bits */ + i__1 = contrl_1.order; + for (i__ = 3; i__ <= i__1; ++i__) { + i2 = irc[i__]; + ishift = 15 - nbit[i__ - 1]; + i2 *= pow_ii(&c__2, &ishift); + i2 += qb[i__ - 3]; + irc[i__] = i2 * descl[i__ - 3] + deadd[i__ - 3]; + } +/* IF (LISTL.GE.3) WRITE(FDEBUG,811) IRMS, (IRC(I),I=1,ORDER) */ +/* 811 FORMAT(1X,'<>',T45,I4,1X,10I8) */ +/* Scale RMS and RC's to reals */ + *rms = (real) (*irms); + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + rc[i__] = irc[i__] / 16384.f; + } + return 0; +} /* decode_ */ diff --git a/linphone/lpc10-1.5/deemp.c b/linphone/lpc10-1.5/deemp.c new file mode 100644 index 000000000..6f5f0f3a9 --- /dev/null +++ b/linphone/lpc10-1.5/deemp.c @@ -0,0 +1,142 @@ +/* + +$Log: deemp.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:23:46 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:34 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int deemp_(real *x, integer *n, struct lpc10_decoder_state *st); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ***************************************************************** */ + +/* DEEMP Version 48 */ + +/* $Log: deemp.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:23:46 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:32:34 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/20 15:54:37 jaf */ +/* Added comments about which indices of array arguments are read or */ +/* written. */ + +/* Added entry INITDEEMP to reinitialize the local state variables, if */ +/* desired. */ + +/* Revision 1.2 1996/03/14 22:11:13 jaf */ +/* Comments added explaining which of the local variables of this */ +/* subroutine need to be saved from one invocation to the next, and which */ +/* do not. */ + +/* Revision 1.1 1996/02/07 14:44:53 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* De-Emphasize output speech with 1 / ( 1 - .75z**-1 ) */ +/* cascaded with 200 Hz high pass filter */ +/* ( 1 - 1.9998z**-1 + z**-2 ) / ( 1 - 1.75z**-1 + .78z**-2 ) */ + +/* WARNING! The coefficients above may be out of date with the code */ +/* below. Either that, or some kind of transformation was performed */ +/* on the coefficients above to create the code below. */ + +/* Input: */ +/* N - Number of samples */ +/* Input/Output: */ +/* X - Speech */ +/* Indices 1 through N are read before being written. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITDEEMP. */ + +/* Subroutine */ int deemp_(real *x, integer *n, struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + real *dei1; + real *dei2; + real *deo1; + real *deo2; + real *deo3; + + /* System generated locals */ + integer i__1; + real r__1; + + /* Local variables */ + integer k; + real dei0; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Local state */ +/* All of the locals saved below were not given explicit initial */ +/* values in the original code. I think 0 is a safe choice. */ + /* Parameter adjustments */ + if (x) { + --x; + } + + /* Function Body */ + + dei1 = &(st->dei1); + dei2 = &(st->dei2); + deo1 = &(st->deo1); + deo2 = &(st->deo2); + deo3 = &(st->deo3); + + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + dei0 = x[k]; + r__1 = x[k] - *dei1 * 1.9998f + *dei2; + x[k] = r__1 + *deo1 * 2.5f - *deo2 * 2.0925f + *deo3 * .585f; + *dei2 = *dei1; + *dei1 = dei0; + *deo3 = *deo2; + *deo2 = *deo1; + *deo1 = x[k]; + } + return 0; +} /* deemp_ */ diff --git a/linphone/lpc10-1.5/difmag.c b/linphone/lpc10-1.5/difmag.c new file mode 100644 index 000000000..7a3589872 --- /dev/null +++ b/linphone/lpc10-1.5/difmag.c @@ -0,0 +1,121 @@ +/* + +$Log: difmag.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:31 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int difmag_(real *speech, integer *lpita, integer *tau, integer *ltau, integer *maxlag, real *amdf, integer *minptr, integer *maxptr); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************** */ + +/* DIFMAG Version 49 */ + +/* $Log: difmag.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:14 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:31 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/15 23:09:39 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 14:41:31 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:45:04 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Compute Average Magnitude Difference Function */ + +/* Inputs: */ +/* SPEECH - Low pass filtered speech */ +/* Indices MIN_N1 through MAX_N1+LPITA-1 are read, where */ +/* MIN_N1 = (MAXLAG - MAX_TAU)/2+1 MAX_TAU = max of TAU(I) for I=1,LTAU +*/ +/* MAX_N1 = (MAXLAG - MIN_TAU)/2+1 MIN_TAU = min of TAU(I) for I=1,LTAU +*/ +/* LPITA - Length of speech buffer */ +/* TAU - Table of lags */ +/* Indices 1 through LTAU read. */ +/* LTAU - Number of lag values to compute */ +/* MAXLAG - Maximum possible lag value */ +/* Outputs: */ +/* (All of these outputs are also read, but only after being written.) */ +/* AMDF - Average Magnitude Difference for each lag in TAU */ +/* Indices 1 through LTAU written */ +/* MINPTR - Index of minimum AMDF value */ +/* MAXPTR - Index of maximum AMDF value */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int difmag_(real *speech, integer *lpita, integer *tau, + integer *ltau, integer *maxlag, real *amdf, integer *minptr, integer * + maxptr) +{ + /* System generated locals */ + integer i__1, i__2; + real r__1; + + /* Local variables */ + integer i__, j, n1, n2; + real sum; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Local state */ +/* None */ + /* Parameter adjustments */ + --amdf; + --tau; + --speech; + + /* Function Body */ + *minptr = 1; + *maxptr = 1; + i__1 = *ltau; + for (i__ = 1; i__ <= i__1; ++i__) { + n1 = (*maxlag - tau[i__]) / 2 + 1; + n2 = n1 + *lpita - 1; + sum = 0.f; + i__2 = n2; + for (j = n1; j <= i__2; j += 4) { + sum += (r__1 = speech[j] - speech[j + tau[i__]], abs(r__1)); + } + amdf[i__] = sum; + if (amdf[i__] < amdf[*minptr]) { + *minptr = i__; + } + if (amdf[i__] > amdf[*maxptr]) { + *maxptr = i__; + } + } + return 0; +} /* difmag_ */ + diff --git a/linphone/lpc10-1.5/dyptrk.c b/linphone/lpc10-1.5/dyptrk.c new file mode 100644 index 000000000..168d2c3a6 --- /dev/null +++ b/linphone/lpc10-1.5/dyptrk.c @@ -0,0 +1,387 @@ +/* + +$Log: dyptrk.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:25:29 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:32:26 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int dyptrk_(real *amdf, integer *ltau, integer *minptr, integer *voice, integer *pitch, integer *midx, struct lpc10_encoder_state *st); +/* comlen contrl_ 12 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* ********************************************************************* */ + +/* DYPTRK Version 52 */ + +/* $Log: dyptrk.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:25:29 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:32:26 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/26 19:35:35 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.4 1996/03/19 18:03:22 jaf */ +/* Replaced the initialization "DATA P/60*DEPTH*0/" with "DATA P/120*0/", */ +/* because apparently Fortran (or at least f2c) can't handle expressions */ +/* like that. */ + +/* Revision 1.3 1996/03/19 17:38:32 jaf */ +/* Added comments about the local variables that should be saved from one */ +/* invocation to the next. None of them were given initial values in the */ +/* original code, but from my testing, it appears that initializing them */ +/* all to 0 works. */ + +/* Added entry INITDYPTRK to reinitialize these local variables. */ + +/* Revision 1.2 1996/03/13 16:32:17 jaf */ +/* Comments added explaining which of the local variables of this */ +/* subroutine need to be saved from one invocation to the next, and which */ +/* do not. */ + +/* WARNING! Some of them that should are never given initial values in */ +/* this code. Hopefully, Fortran 77 defines initial values for them, but */ +/* even so, giving them explicit initial values is preferable. */ + +/* Revision 1.1 1996/02/07 14:45:14 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Dynamic Pitch Tracker */ + +/* Input: */ +/* AMDF - Average Magnitude Difference Function array */ +/* Indices 1 through LTAU read, and MINPTR */ +/* LTAU - Number of lags in AMDF */ +/* MINPTR - Location of minimum AMDF value */ +/* VOICE - Voicing decision */ +/* Output: */ +/* PITCH - Smoothed pitch value, 2 frames delayed */ +/* MIDX - Initial estimate of current frame pitch */ +/* Compile time constant: */ +/* DEPTH - Number of frames to trace back */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITDYPTRK. */ + +/* Subroutine */ int dyptrk_(real *amdf, integer *ltau, integer * + minptr, integer *voice, integer *pitch, integer *midx, + struct lpc10_encoder_state *st) +{ + /* Initialized data */ + + real *s; + integer *p; + integer *ipoint; + real *alphax; + + /* System generated locals */ + integer i__1; + + /* Local variables */ + integer pbar; + real sbar; + integer path[2], iptr, i__, j; + real alpha, minsc, maxsc; + +/* Arguments */ +/* $Log: dyptrk.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:25:29 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:32:26 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Parameters/constants */ +/* Local variables that need not be saved */ +/* Note that PATH is only used for debugging purposes, and can be */ +/* removed. */ +/* Local state */ +/* It would be a bit more "general" to define S(LTAU), if Fortran */ +/* allows the argument of a function to be used as the dimension of +*/ +/* a local array variable. */ +/* IPOINT is always in the range 0 to DEPTH-1. */ +/* WARNING! */ + +/* In the original version of this subroutine, IPOINT, ALPHAX, */ +/* every element of S, and potentially any element of P with the */ +/* second index value .NE. IPTR were read without being given */ +/* initial values (all indices of P with second index equal to */ +/* IPTR are all written before being read in this subroutine). */ + +/* From examining the code carefully, it appears that all of these +*/ +/* should be saved from one invocation to the next. */ + +/* I've run lpcsim with the "-l 6" option to see all of the */ +/* debugging information that is printed out by this subroutine */ +/* below, and it appears that S, P, IPOINT, and ALPHAX are all */ +/* initialized to 0 (these initial values would likely be different +*/ +/* on different platforms, compilers, etc.). Given that the output +*/ +/* of the coder sounds reasonable, I'm going to initialize these */ +/* variables to 0 explicitly. */ + + s = &(st->s[0]); + p = &(st->p[0]); + ipoint = &(st->ipoint); + alphax = &(st->alphax); + + + /* Parameter adjustments */ + if (amdf) { + --amdf; + } + + /* Function Body */ + +/* Calculate the confidence factor ALPHA, used as a threshold slope in +*/ +/* SEESAW. If unvoiced, set high slope so that every point in P array +*/ +/* is marked as a potential pitch frequency. A scaled up version (ALPHAX +)*/ +/* is used to maintain arithmetic precision. */ + if (*voice == 1) { + *alphax = *alphax * .75f + amdf[*minptr] / 2.f; + } else { + *alphax *= .984375f; + } + alpha = *alphax / 16; + if (*voice == 0 && *alphax < 128.f) { + alpha = 8.f; + } +/* SEESAW: Construct a pitch pointer array and intermediate winner functio +n*/ +/* Left to right pass: */ + iptr = *ipoint + 1; + p[iptr * 60 - 60] = 1; + i__ = 1; + pbar = 1; + sbar = s[0]; + i__1 = *ltau; + for (i__ = 1; i__ <= i__1; ++i__) { + sbar += alpha; + if (sbar < s[i__ - 1]) { + s[i__ - 1] = sbar; + p[i__ + iptr * 60 - 61] = pbar; + } else { + sbar = s[i__ - 1]; + p[i__ + iptr * 60 - 61] = i__; + pbar = i__; + } + } +/* Right to left pass: */ + i__ = pbar - 1; + sbar = s[i__]; + while(i__ >= 1) { + sbar += alpha; + if (sbar < s[i__ - 1]) { + s[i__ - 1] = sbar; + p[i__ + iptr * 60 - 61] = pbar; + } else { + pbar = p[i__ + iptr * 60 - 61]; + i__ = pbar; + sbar = s[i__ - 1]; + } + --i__; + } +/* Update S using AMDF */ +/* Find maximum, minimum, and location of minimum */ + s[0] += amdf[1] / 2; + minsc = s[0]; + maxsc = minsc; + *midx = 1; + i__1 = *ltau; + for (i__ = 2; i__ <= i__1; ++i__) { + s[i__ - 1] += amdf[i__] / 2; + if (s[i__ - 1] > maxsc) { + maxsc = s[i__ - 1]; + } + if (s[i__ - 1] < minsc) { + *midx = i__; + minsc = s[i__ - 1]; + } + } +/* Subtract MINSC from S to prevent overflow */ + i__1 = *ltau; + for (i__ = 1; i__ <= i__1; ++i__) { + s[i__ - 1] -= minsc; + } + maxsc -= minsc; +/* Use higher octave pitch if significant null there */ + j = 0; + for (i__ = 20; i__ <= 40; i__ += 10) { + if (*midx > i__) { + if (s[*midx - i__ - 1] < maxsc / 4) { + j = i__; + } + } + } + *midx -= j; +/* TRACE: look back two frames to find minimum cost pitch estimate */ + j = *ipoint; + *pitch = *midx; + for (i__ = 1; i__ <= 2; ++i__) { + j = j % 2 + 1; + *pitch = p[*pitch + j * 60 - 61]; + path[i__ - 1] = *pitch; + } + +/* The following statement subtracts one from IPOINT, mod DEPTH. I +*/ +/* think the author chose to add DEPTH-1, instead of subtracting 1, +*/ +/* because then it will work even if MOD doesn't work as desired on +*/ +/* negative arguments. */ + + *ipoint = (*ipoint + 1) % 2; + return 0; +} /* dyptrk_ */ diff --git a/linphone/lpc10-1.5/encode.c b/linphone/lpc10-1.5/encode.c new file mode 100644 index 000000000..4c0f9d330 --- /dev/null +++ b/linphone/lpc10-1.5/encode.c @@ -0,0 +1,349 @@ +/* + +$Log: encode.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:21 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int encode_(integer *voice, integer *pitch, real *rms, real *rc, integer *ipitch, integer *irms, integer *irc); +/* comlen contrl_ 12 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* Table of constant values */ + +static integer c__2 = 2; + +/* ***************************************************************** */ + +/* ENCODE Version 54 */ + +/* $Log: encode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:21 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/26 19:35:50 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.4 1996/03/21 00:26:29 jaf */ +/* Added the comment that this subroutine has no local state. */ + +/* In the last check-in, I forgot to mention that I had added comments */ +/* explaining which indices of array arguments are read or written. */ + +/* Revision 1.3 1996/03/21 00:22:39 jaf */ +/* Added comments explaining that all local arrays are effectively */ +/* constants. */ + +/* Revision 1.2 1996/03/13 18:48:33 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:45:29 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Quantize LPC parameters for transmission */ + +/* INPUTS: */ +/* VOICE - Half frame voicing decisions */ +/* Indices 1 through 2 read. */ +/* PITCH - Pitch */ +/* RMS - Energy */ +/* RC - Reflection coefficients */ +/* Indices 1 through ORDER read. */ +/* CORRP - Error Correction: TRUE = yes, FALSE = none */ +/* (this is defined in file control.fh) */ +/* OUTPUTS: */ +/* IPITCH - Coded pitch and voicing */ +/* IRMS - Quantized energy */ +/* IRC - Quantized reflection coefficients */ +/* Indices 1 through MAX(ORDER,2) written. */ +/* If CORRP is .TRUE., then indices 1 through 10 written */ +/* for unvoiced frames. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int encode_(integer *voice, integer *pitch, real *rms, real * + rc, integer *ipitch, integer *irms, integer *irc) +{ + /* Initialized data */ + + static integer enctab[16] = { 0,7,11,12,13,10,6,1,14,9,5,2,3,4,8,15 }; + static integer entau[60] = { 19,11,27,25,29,21,23,22,30,14,15,7,39,38,46, + 42,43,41,45,37,53,49,51,50,54,52,60,56,58,26,90,88,92,84,86,82,83, + 81,85,69,77,73,75,74,78,70,71,67,99,97,113,112,114,98,106,104,108, + 100,101,76 }; + static integer enadd[8] = { 1920,-768,2432,1280,3584,1536,2816,-1152 }; + static real enscl[8] = { .0204f,.0167f,.0145f,.0147f,.0143f,.0135f,.0125f, + .0112f }; + static integer enbits[8] = { 6,5,4,4,4,4,3,3 }; + static integer entab6[64] = { 0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3, + 3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,9,9, + 9,10,10,11,11,12,13,14,15 }; + static integer rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420, + 384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102, + 92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15, + 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }; + + /* System generated locals */ + integer i__1, i__2; + + /* Builtin functions */ + integer pow_ii(integer *, integer *); + + /* Local variables */ + integer idel, nbit, i__, j, i2, i3, mrk; + +/* $Log: encode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:21 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments */ +/* $Log: encode.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:21 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Parameters/constants */ +/* These arrays are not Fortran PARAMETER's, but they are defined */ +/* by DATA statements below, and their contents are never altered. +*/ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + --irc; + --rc; + --voice; + + /* Function Body */ +/* Scale RMS and RC's to integers */ + *irms = *rms; + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { + irc[i__] = rc[i__] * 32768.f; + } +/* IF(LISTL.GE.3)WRITE(FDEBUG,800)VOICE,PITCH,IRMS,(IRC(I),I=1,ORDER) */ +/* 800 FORMAT(1X,/,' <>',T32,2I3,I6,I5,T50,10I8) */ +/* Encode pitch and voicing */ + if (voice[1] != 0 && voice[2] != 0) { + *ipitch = entau[*pitch - 1]; + } else { + if (contrl_1.corrp) { + *ipitch = 0; + if (voice[1] != voice[2]) { + *ipitch = 127; + } + } else { + *ipitch = (voice[1] << 1) + voice[2]; + } + } +/* Encode RMS by binary table search */ + j = 32; + idel = 16; + *irms = min(*irms,1023); + while(idel > 0) { + if (*irms > rmst[j - 1]) { + j -= idel; + } + if (*irms < rmst[j - 1]) { + j += idel; + } + idel /= 2; + } + if (*irms > rmst[j - 1]) { + --j; + } + *irms = 31 - j / 2; +/* Encode RC(1) and (2) as log-area-ratios */ + for (i__ = 1; i__ <= 2; ++i__) { + i2 = irc[i__]; + mrk = 0; + if (i2 < 0) { + i2 = -i2; + mrk = 1; + } + i2 /= 512; + i2 = min(i2,63); + i2 = entab6[i2]; + if (mrk != 0) { + i2 = -i2; + } + irc[i__] = i2; + } +/* Encode RC(3) - (10) linearly, remove bias then scale */ + i__1 = contrl_1.order; + for (i__ = 3; i__ <= i__1; ++i__) { + i2 = irc[i__] / 2; + i2 = (i2 + enadd[contrl_1.order + 1 - i__ - 1]) * enscl[ + contrl_1.order + 1 - i__ - 1]; +/* Computing MIN */ + i__2 = max(i2,-127); + i2 = min(i__2,127); + nbit = enbits[contrl_1.order + 1 - i__ - 1]; + i3 = 0; + if (i2 < 0) { + i3 = -1; + } + i2 /= pow_ii(&c__2, &nbit); + if (i3 == -1) { + --i2; + } + irc[i__] = i2; + } +/* Protect the most significant bits of the most */ +/* important parameters during non-voiced frames. */ +/* RC(1) - RC(4) are protected using 20 parity bits */ +/* replacing RC(5) - RC(10). */ + if (contrl_1.corrp) { + if (*ipitch == 0 || *ipitch == 127) { + irc[5] = enctab[(irc[1] & 30) / 2]; + irc[6] = enctab[(irc[2] & 30) / 2]; + irc[7] = enctab[(irc[3] & 30) / 2]; + irc[8] = enctab[(*irms & 30) / 2]; + irc[9] = enctab[(irc[4] & 30) / 2] / 2; + irc[10] = enctab[(irc[4] & 30) / 2] & 1; + } + } +/* IF(LISTL.GE.3)WRITE(FDEBUG,801)VOICE,IPITCH,IRMS,(IRC(J),J=1,ORDER) */ +/* 801 FORMAT(1X,'<>',T32,2I3,I6,I5,T50,10I8) */ + return 0; +} /* encode_ */ + diff --git a/linphone/lpc10-1.5/energy.c b/linphone/lpc10-1.5/energy.c new file mode 100644 index 000000000..995cbac47 --- /dev/null +++ b/linphone/lpc10-1.5/energy.c @@ -0,0 +1,91 @@ +/* + +$Log: energy.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:17 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int energy_(integer *len, real *speech, real *rms); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* ENERGY Version 50 */ + +/* $Log: energy.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:17 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/18 21:17:41 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:46:02 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:45:40 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Compute RMS energy. */ + +/* Input: */ +/* LEN - Length of speech buffer */ +/* SPEECH - Speech buffer */ +/* Indices 1 through LEN read. */ +/* Output: */ +/* RMS - Root Mean Square energy */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int energy_(integer *len, real *speech, real *rms) +{ + /* System generated locals */ + integer i__1; + + /* Builtin functions */ + double sqrt(doublereal); + + /* Local variables */ + integer i__; + +/* Arguments */ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + --speech; + + /* Function Body */ + *rms = 0.f; + i__1 = *len; + for (i__ = 1; i__ <= i__1; ++i__) { + *rms += speech[i__] * speech[i__]; + } + *rms = sqrt(*rms / *len); + return 0; +} /* energy_ */ + diff --git a/linphone/lpc10-1.5/f2c.h b/linphone/lpc10-1.5/f2c.h new file mode 100644 index 000000000..5193e277a --- /dev/null +++ b/linphone/lpc10-1.5/f2c.h @@ -0,0 +1,260 @@ +/* + +$Log: f2c.h,v $ +Revision 1.2 2005/11/30 20:07:31 smorlat +ready for 1.2.0 ? + +Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:26:28 jaf + * Any typedef defining a type that was used in lpc10_encoder_state or + * lpc10_decoder_state struct's was commented out here and added to + * lpc10.h. + * + * Revision 1.1 1996/08/19 22:32:13 jaf + * Initial revision + * + +*/ + +/* + * f2c.h + * + * SCCS ID: @(#)f2c.h 1.2 96/05/19 + */ + +/* f2c.h -- Standard Fortran to C header file */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef F2C_INCLUDE +#define F2C_INCLUDE + +#include "lpc10.h" + +/*typedef long int integer;*/ +/*typedef INT32 integer;*/ +/*typedef short int shortint;*/ +/*typedef INT16 shortint;*/ +/*typedef float real;*/ +/* doublereal only used for function arguments to sqrt, exp, etc. */ +typedef double doublereal; +/* 32 bits seems wasteful, but there really aren't that many logical + * variables around, and making them 32 bits could avoid word + * alignment problems, perhaps. */ +/*typedef long int logical;*/ +/*typedef INT32 logical;*/ +/* The following types are not used in the translated C code for the + * LPC-10 coder, but they might be needed by the definitions down + * below, so they don't cause compilation errors. */ +typedef char *address; +typedef struct { real r, i; } complex; +typedef struct { doublereal r, i; } doublecomplex; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +/* typedef long long longint; */ /* system-dependent */ + +#define TRUE_ (1) +#define FALSE_ (0) + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef long int flag; +typedef long int ftnlen; +typedef long int ftnint; +#endif + +/*external read, write*/ +typedef struct +{ flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct +{ flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct +{ flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct +{ flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct +{ flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct +{ flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +#define VOID void + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; + }; + +typedef union Multitype Multitype; + +/*typedef long int Long;*/ /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; + }; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; + }; +typedef struct Namelist Namelist; + +/* to avoid a conflict on netbsd 3.0 */ +#ifdef abs +#undef abs +#endif + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal)abs(x) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#define dmin(a,b) (doublereal)min(a,b) +#define dmax(a,b) (doublereal)max(a,b) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +#ifdef __cplusplus +typedef int /* Unknown procedure type */ (*U_fp)(...); +typedef shortint (*J_fp)(...); +typedef integer (*I_fp)(...); +typedef real (*R_fp)(...); +typedef doublereal (*D_fp)(...), (*E_fp)(...); +typedef /* Complex */ VOID (*C_fp)(...); +typedef /* Double Complex */ VOID (*Z_fp)(...); +typedef logical (*L_fp)(...); +typedef shortlogical (*K_fp)(...); +typedef /* Character */ VOID (*H_fp)(...); +typedef /* Subroutine */ int (*S_fp)(...); +#else +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ VOID (*C_fp)(); +typedef /* Double Complex */ VOID (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ VOID (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +#endif +/* E_fp is for real functions when -R is not specified */ +typedef VOID C_f; /* complex function */ +typedef VOID H_f; /* character function */ +typedef VOID Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +/* undef any lower-case symbols that your C compiler predefines, e.g.: */ + +#ifndef Skip_f2c_Undefs +#undef cray +#undef gcos +#undef mc68010 +#undef mc68020 +#undef mips +#undef pdp11 +#undef sgi +#undef sparc +#undef sun +#undef sun2 +#undef sun3 +#undef sun4 +#undef u370 +#undef u3b +#undef u3b2 +#undef u3b5 +#undef unix +#undef vax +#endif +#endif diff --git a/linphone/lpc10-1.5/f2clib.c b/linphone/lpc10-1.5/f2clib.c new file mode 100644 index 000000000..6bd8cdfb3 --- /dev/null +++ b/linphone/lpc10-1.5/f2clib.c @@ -0,0 +1,82 @@ +/* + +$Log: f2clib.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:10 jaf + * Initial revision + * + +*/ + +/* + * f2clib.c + * + * SCCS ID: @(#)f2clib.c 1.2 96/05/19 + */ + +#include "f2c.h" + +#ifdef KR_headers +integer pow_ii(ap, bp) integer *ap, *bp; +#else +integer pow_ii(integer *ap, integer *bp) +#endif +{ + integer pow, x, n; + unsigned long u; + + x = *ap; + n = *bp; + + if (n <= 0) { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return x == 0 ? 1/x : 0; + n = -n; + } + u = n; + for(pow = 1; ; ) + { + if(u & 01) + pow *= x; + if(u >>= 1) + x *= x; + else + break; + } + return(pow); + } + + + +#ifdef KR_headers +double r_sign(a,b) real *a, *b; +#else +double r_sign(real *a, real *b) +#endif +{ +double x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} + + + +#ifdef KR_headers +double floor(); +integer i_nint(x) real *x; +#else +#undef abs +#include "math.h" +integer i_nint(real *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/linphone/lpc10-1.5/ham84.c b/linphone/lpc10-1.5/ham84.c new file mode 100644 index 000000000..0b2ab86d5 --- /dev/null +++ b/linphone/lpc10-1.5/ham84.c @@ -0,0 +1,114 @@ +/* + +$Log: ham84.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:07 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int ham84_(integer *input, integer *output, integer *errcnt); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ***************************************************************** */ + +/* HAM84 Version 45G */ + +/* $Log: ham84.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:07 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/21 15:26:00 jaf */ +/* Put comment header in standard form. */ + +/* Revision 1.2 1996/03/13 22:00:13 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:47:04 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Hamming 8,4 Decoder - can correct 1 out of seven bits */ +/* and can detect up to two errors. */ + +/* Input: */ +/* INPUT - Seven bit data word, 4 bits parameter and */ +/* 4 bits parity information */ +/* Input/Output: */ +/* ERRCNT - Sums errors detected by Hamming code */ +/* Output: */ +/* OUTPUT - 4 corrected parameter bits */ + +/* This subroutine is entered with an eight bit word in INPUT. The 8th */ +/* bit is parity and is stripped off. The remaining 7 bits address the */ +/* hamming 8,4 table and the output OUTPUT from the table gives the 4 */ +/* bits of corrected data. If bit 4 is set, no error was detected. */ +/* ERRCNT is the number of errors counted. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int ham84_(integer *input, integer *output, integer *errcnt) +{ + /* Initialized data */ + + static integer dactab[128] = { 16,0,0,3,0,5,14,7,0,9,14,11,14,13,30,14,0, + 9,2,7,4,7,7,23,9,25,10,9,12,9,14,7,0,5,2,11,5,21,6,5,8,11,11,27, + 12,5,14,11,2,1,18,2,12,5,2,7,12,9,2,11,28,12,12,15,0,3,3,19,4,13, + 6,3,8,13,10,3,13,29,14,13,4,1,10,3,20,4,4,7,10,9,26,10,4,13,10,15, + 8,1,6,3,6,5,22,6,24,8,8,11,8,13,6,15,1,17,2,1,4,1,6,15,8,1,10,15, + 12,15,15,31 }; + + integer i__, j, parity; + +/* Arguments */ +/* Parameters/constants */ +/* Local variables that need not be saved */ +/* Determine parity of input word */ + parity = *input & 255; + parity ^= parity / 16; + parity ^= parity / 4; + parity ^= parity / 2; + parity &= 1; + i__ = dactab[*input & 127]; + *output = i__ & 15; + j = i__ & 16; + if (j != 0) { +/* No errors detected in seven bits */ + if (parity != 0) { + ++(*errcnt); + } + } else { +/* One or two errors detected */ + ++(*errcnt); + if (parity == 0) { +/* Two errors detected */ + ++(*errcnt); + *output = -1; + } + } + return 0; +} /* ham84_ */ + diff --git a/linphone/lpc10-1.5/hp100.c b/linphone/lpc10-1.5/hp100.c new file mode 100644 index 000000000..51ce4665c --- /dev/null +++ b/linphone/lpc10-1.5/hp100.c @@ -0,0 +1,157 @@ +/* + +$Log: hp100.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:28:05 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:32:04 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int hp100_(real *speech, integer *start, integer *end, + struct lpc10_encoder_state *st); +extern int inithp100_(void); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* HP100 Version 55 */ + +/* $Log: hp100.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:28:05 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:32:04 jaf + * Initial revision + * */ +/* Revision 1.6 1996/03/15 16:45:25 jaf */ +/* Rearranged a few comments. */ + +/* Revision 1.5 1996/03/14 23:20:54 jaf */ +/* Added comments about when INITHP100 should be used. */ + +/* Revision 1.4 1996/03/14 23:08:08 jaf */ +/* Added an entry named INITHP100 that initializes the local state of */ +/* subroutine HP100. */ + +/* Revision 1.3 1996/03/14 22:09:20 jaf */ +/* Comments added explaining which of the local variables of this */ +/* subroutine need to be saved from one invocation to the next, and which */ +/* do not. */ + +/* Revision 1.2 1996/02/12 15:05:54 jaf */ +/* Added lots of comments explaining why I changed one line, which was a */ +/* declaration with initializations. */ + +/* Revision 1.1 1996/02/07 14:47:12 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* 100 Hz High Pass Filter */ + +/* Jan 92 - corrected typo (1.937148 to 1.935715), */ +/* rounded coefficients to 7 places, */ +/* corrected and merged gain (.97466**4), */ +/* merged numerator into first two sections. */ + +/* Input: */ +/* start, end - Range of samples to filter */ +/* Input/Output: */ +/* speech(end) - Speech data. */ +/* Indices start through end are read and modified. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITHP100. */ +/* Subroutine */ int hp100_(real *speech, integer *start, integer *end, + struct lpc10_encoder_state *st) +{ + /* Temporary local copies of variables in lpc10_encoder_state. + I've only created these because it might cause the loop below + to execute a bit faster to access local variables, rather than + variables in the lpc10_encoder_state structure. It is just a + guess that it will be faster. */ + + real z11; + real z21; + real z12; + real z22; + + /* System generated locals */ + integer i__1; + + /* Local variables */ + integer i__; + real si, err; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Local state */ + /* Parameter adjustments */ + if (speech) { + --speech; + } + + /* Function Body */ + + z11 = st->z11; + z21 = st->z21; + z12 = st->z12; + z22 = st->z22; + + i__1 = *end; + for (i__ = *start; i__ <= i__1; ++i__) { + si = speech[i__]; + err = si + z11 * 1.859076f - z21 * .8648249f; + si = err - z11 * 2.f + z21; + z21 = z11; + z11 = err; + err = si + z12 * 1.935715f - z22 * .9417004f; + si = err - z12 * 2.f + z22; + z22 = z12; + z12 = err; + speech[i__] = si * .902428f; + } + + st->z11 = z11; + st->z21 = z21; + st->z12 = z12; + st->z22 = z22; + + return 0; +} /* hp100_ */ diff --git a/linphone/lpc10-1.5/invert.c b/linphone/lpc10-1.5/invert.c new file mode 100644 index 000000000..19cbb71ab --- /dev/null +++ b/linphone/lpc10-1.5/invert.c @@ -0,0 +1,175 @@ +/* + +$Log: invert.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:32:00 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int invert_(integer *order, real *phi, real *psi, real *rc); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* **************************************************************** */ + +/* INVERT Version 45G */ + +/* $Log: invert.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:00 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/18 20:52:47 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:51:32 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Eliminated a comment from the original, describing a local array X */ +/* that appeared nowhere in the code. */ + +/* Revision 1.1 1996/02/07 14:47:20 jaf */ +/* Initial revision */ + + +/* **************************************************************** */ + +/* Invert a covariance matrix using Choleski decomposition method. */ + +/* Input: */ +/* ORDER - Analysis order */ +/* PHI(ORDER,ORDER) - Covariance matrix */ +/* Indices (I,J) read, where ORDER .GE. I .GE. J .GE. 1.*/ +/* All other indices untouched. */ +/* PSI(ORDER) - Column vector to be predicted */ +/* Indices 1 through ORDER read. */ +/* Output: */ +/* RC(ORDER) - Pseudo reflection coefficients */ +/* Indices 1 through ORDER written, and then possibly read. +*/ +/* Internal: */ +/* V(ORDER,ORDER) - Temporary matrix */ +/* Same indices written as read from PHI. */ +/* Many indices may be read and written again after */ +/* initially being copied from PHI, but all indices */ +/* are written before being read. */ + +/* NOTE: Temporary matrix V is not needed and may be replaced */ +/* by PHI if the original PHI values do not need to be preserved. */ + +/* Subroutine */ int invert_(integer *order, real *phi, real *psi, real *rc) +{ + /* System generated locals */ + integer phi_dim1, phi_offset, i__1, i__2, i__3; + real r__1, r__2; + + /* Local variables */ + real save; + integer i__, j, k; + real v[100] /* was [10][10] */; + +/* Arguments */ +/* $Log: invert.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:32:00 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Parameters/constants */ +/* Local variables that need not be saved */ +/* Decompose PHI into V * D * V' where V is a triangular matrix whose */ +/* main diagonal elements are all 1, V' is the transpose of V, and */ +/* D is a vector. Here D(n) is stored in location V(n,n). */ + /* Parameter adjustments */ + --rc; + --psi; + phi_dim1 = *order; + phi_offset = phi_dim1 + 1; + phi -= phi_offset; + + /* Function Body */ + i__1 = *order; + for (j = 1; j <= i__1; ++j) { + i__2 = *order; + for (i__ = j; i__ <= i__2; ++i__) { + v[i__ + j * 10 - 11] = phi[i__ + j * phi_dim1]; + } + i__2 = j - 1; + for (k = 1; k <= i__2; ++k) { + save = v[j + k * 10 - 11] * v[k + k * 10 - 11]; + i__3 = *order; + for (i__ = j; i__ <= i__3; ++i__) { + v[i__ + j * 10 - 11] -= v[i__ + k * 10 - 11] * save; + } + } +/* Compute intermediate results, which are similar to RC's */ + if ((r__1 = v[j + j * 10 - 11], abs(r__1)) < 1e-10f) { + goto L100; + } + rc[j] = psi[j]; + i__2 = j - 1; + for (k = 1; k <= i__2; ++k) { + rc[j] -= rc[k] * v[j + k * 10 - 11]; + } + v[j + j * 10 - 11] = 1.f / v[j + j * 10 - 11]; + rc[j] *= v[j + j * 10 - 11]; +/* Computing MAX */ +/* Computing MIN */ + r__2 = rc[j]; + r__1 = min(r__2,.999f); + rc[j] = max(r__1,-.999f); + } + return 0; +/* Zero out higher order RC's if algorithm terminated early */ +L100: + i__1 = *order; + for (i__ = j; i__ <= i__1; ++i__) { + rc[i__] = 0.f; + } +/* Back substitute for PC's (if needed) */ +/* 110 DO J = ORDER,1,-1 */ +/* PC(J) = RC(J) */ +/* DO I = 1,J-1 */ +/* PC(J) = PC(J) - PC(I)*V(J,I) */ +/* END DO */ +/* END DO */ + return 0; +} /* invert_ */ + diff --git a/linphone/lpc10-1.5/irc2pc.c b/linphone/lpc10-1.5/irc2pc.c new file mode 100644 index 000000000..df563735e --- /dev/null +++ b/linphone/lpc10-1.5/irc2pc.c @@ -0,0 +1,133 @@ +/* + +$Log: irc2pc.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:56 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int irc2pc_(real *rc, real *pc, integer *order, real *gprime, real *g2pass); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ***************************************************************** */ + +/* IRC2PC Version 48 */ + +/* $Log: irc2pc.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:56 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/20 15:47:19 jaf */ +/* Added comments about which indices of array arguments are read or */ +/* written. */ + +/* Revision 1.2 1996/03/14 16:59:04 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:47:27 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Convert Reflection Coefficients to Predictor Coeficients */ + +/* Inputs: */ +/* RC - Reflection coefficients */ +/* Indices 1 through ORDER read. */ +/* ORDER - Number of RC's */ +/* GPRIME - Excitation modification gain */ +/* Outputs: */ +/* PC - Predictor coefficients */ +/* Indices 1 through ORDER written. */ +/* Indices 1 through ORDER-1 are read after being written. */ +/* G2PASS - Excitation modification sharpening factor */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int irc2pc_(real *rc, real *pc, integer *order, real *gprime, + real *g2pass) +{ + /* System generated locals */ + integer i__1, i__2; + + /* Builtin functions */ + double sqrt(doublereal); + + /* Local variables */ + real temp[10]; + integer i__, j; + +/* Arguments */ +/* $Log: irc2pc.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:56 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + --pc; + --rc; + + /* Function Body */ + *g2pass = 1.f; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + *g2pass *= 1.f - rc[i__] * rc[i__]; + } + *g2pass = *gprime * sqrt(*g2pass); + pc[1] = rc[1]; + i__1 = *order; + for (i__ = 2; i__ <= i__1; ++i__) { + i__2 = i__ - 1; + for (j = 1; j <= i__2; ++j) { + temp[j - 1] = pc[j] - rc[i__] * pc[i__ - j]; + } + i__2 = i__ - 1; + for (j = 1; j <= i__2; ++j) { + pc[j] = temp[j - 1]; + } + pc[i__] = rc[i__]; + } + return 0; +} /* irc2pc_ */ + diff --git a/linphone/lpc10-1.5/ivfilt.c b/linphone/lpc10-1.5/ivfilt.c new file mode 100644 index 000000000..18e229b7d --- /dev/null +++ b/linphone/lpc10-1.5/ivfilt.c @@ -0,0 +1,118 @@ +/* + +$Log: ivfilt.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:53 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer *nsamp, real *ivrc); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* IVFILT Version 48 */ + +/* $Log: ivfilt.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:53 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/15 21:36:29 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 00:01:00 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:47:34 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* 2nd order inverse filter, speech is decimated 4:1 */ + +/* Input: */ +/* LEN - Length of speech buffers */ +/* NSAMP - Number of samples to filter */ +/* LPBUF - Low pass filtered speech buffer */ +/* Indices LEN-NSAMP-7 through LEN read. */ +/* Output: */ +/* IVBUF - Inverse filtered speech buffer */ +/* Indices LEN-NSAMP+1 through LEN written. */ +/* IVRC - Inverse filter reflection coefficients (for voicing) */ +/* Indices 1 and 2 both written (also read, but only after writing). +*/ + +/* This subroutine has no local state. */ + +/* Subroutine */ int ivfilt_(real *lpbuf, real *ivbuf, integer *len, integer * + nsamp, real *ivrc) +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + integer i__, j, k; + real r__[3], pc1, pc2; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Local state */ +/* None */ +/* Calculate Autocorrelations */ + /* Parameter adjustments */ + --ivbuf; + --lpbuf; + --ivrc; + + /* Function Body */ + for (i__ = 1; i__ <= 3; ++i__) { + r__[i__ - 1] = 0.f; + k = i__ - 1 << 2; + i__1 = *len; + for (j = (i__ << 2) + *len - *nsamp; j <= i__1; j += 2) { + r__[i__ - 1] += lpbuf[j] * lpbuf[j - k]; + } + } +/* Calculate predictor coefficients */ + pc1 = 0.f; + pc2 = 0.f; + ivrc[1] = 0.f; + ivrc[2] = 0.f; + if (r__[0] > 1e-10f) { + ivrc[1] = r__[1] / r__[0]; + ivrc[2] = (r__[2] - ivrc[1] * r__[1]) / (r__[0] - ivrc[1] * r__[1]); + pc1 = ivrc[1] - ivrc[1] * ivrc[2]; + pc2 = ivrc[2]; + } +/* Inverse filter LPBUF into IVBUF */ + i__1 = *len; + for (i__ = *len + 1 - *nsamp; i__ <= i__1; ++i__) { + ivbuf[i__] = lpbuf[i__] - pc1 * lpbuf[i__ - 4] - pc2 * lpbuf[i__ - 8]; + } + return 0; +} /* ivfilt_ */ + diff --git a/linphone/lpc10-1.5/lpc10.h b/linphone/lpc10-1.5/lpc10.h new file mode 100644 index 000000000..4ece9f07f --- /dev/null +++ b/linphone/lpc10-1.5/lpc10.h @@ -0,0 +1,228 @@ +/* + +$Log: lpc10.h,v $ +Revision 1.1.1.1 2001/11/19 19:50:13 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:47:31 jaf + * Initial revision + * + +*/ + +#ifndef __LPC10_H__ +#define __LPC10_H__ + +#define LPC10_SAMPLES_PER_FRAME 180 +#define LPC10_BITS_IN_COMPRESSED_FRAME 54 + + +/* + + The "#if defined"'s in this file are by no means intended to be + complete. They are what Nautilus uses, which has been successfully + compiled under DOS with the Microsoft C compiler, and under a few + versions of Unix with the GNU C compiler. + + */ + + +typedef short INT16; +typedef int INT32; + + +#if defined(__MSDOS__) || defined(MSDOS) +typedef int INT16; +typedef long INT32; +#endif + + + +/* The initial values for every member of this structure is 0, except + where noted in comments. */ + +/* These two lines are copied from f2c.h. There should be a more + elegant way of doing this than having the same declarations in two + files. */ + +typedef float real; +typedef INT32 integer; +typedef INT32 logical; +typedef INT16 shortint; + +struct lpc10_encoder_state { + /* State used only by function hp100 */ + real z11; + real z21; + real z12; + real z22; + + /* State used by function analys */ + real inbuf[540], pebuf[540]; + real lpbuf[696], ivbuf[312]; + real bias; + integer osbuf[10]; /* no initial value necessary */ + integer osptr; /* initial value 1 */ + integer obound[3]; + integer vwin[6] /* was [2][3] */; /* initial value vwin[4] = 307; vwin[5] = 462; */ + integer awin[6] /* was [2][3] */; /* initial value awin[4] = 307; awin[5] = 462; */ + integer voibuf[8] /* was [2][4] */; + real rmsbuf[3]; + real rcbuf[30] /* was [10][3] */; + real zpre; + + + /* State used by function onset */ + real n; + real d__; /* initial value 1.f */ + real fpc; /* no initial value necessary */ + real l2buf[16]; + real l2sum1; + integer l2ptr1; /* initial value 1 */ + integer l2ptr2; /* initial value 9 */ + integer lasti; /* no initial value necessary */ + logical hyst; /* initial value FALSE_ */ + + /* State used by function voicin */ + real dither; /* initial value 20.f */ + real snr; + real maxmin; + real voice[6] /* was [2][3] */; /* initial value is probably unnecessary */ + integer lbve, lbue, fbve, fbue; + integer ofbue, sfbue; + integer olbue, slbue; + /* Initial values: + lbve = 3000; + fbve = 3000; + fbue = 187; + ofbue = 187; + sfbue = 187; + lbue = 93; + olbue = 93; + slbue = 93; + snr = (real) (fbve / fbue << 6); + */ + + /* State used by function dyptrk */ + real s[60]; + integer p[120] /* was [60][2] */; + integer ipoint; + real alphax; + + /* State used by function chanwr */ + integer isync; + +}; + + +struct lpc10_decoder_state { + + /* State used by function decode */ + integer iptold; /* initial value 60 */ + logical first; /* initial value TRUE_ */ + integer ivp2h; + integer iovoic; + integer iavgp; /* initial value 60 */ + integer erate; + integer drc[30] /* was [3][10] */; + integer dpit[3]; + integer drms[3]; + + /* State used by function synths */ + real buf[360]; + integer buflen; /* initial value 180 */ + + /* State used by function pitsyn */ + integer ivoico; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + integer ipito; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + real rmso; /* initial value 1.f */ + real rco[10]; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + integer jsamp; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + logical first_pitsyn; /* initial value TRUE_ */ + + /* State used by function bsynz */ + integer ipo; + real exc[166]; + real exc2[166]; + real lpi1; + real lpi2; + real lpi3; + real hpi1; + real hpi2; + real hpi3; + real rmso_bsynz; + + /* State used by function random */ + integer j; /* initial value 2 */ + integer k; /* initial value 5 */ + shortint y[5]; /* initial value { -21161,-8478,30892,-10216,16950 } */ + + /* State used by function deemp */ + real dei1; + real dei2; + real deo1; + real deo2; + real deo3; + +}; + + + +/* + + Calling sequence: + + Call create_lpc10_encoder_state(), which returns a pointer to an + already initialized lpc10_encoder_state structure. + + lpc10_encode reads indices 0 through (LPC10_SAMPLES_PER_FRAME-1) of + array speech[], and writes indices 0 through + (LPC10_BITS_IN_COMPRESSED_FRAME-1) of array bits[], and both reads + and writes the lpc10_encoder_state structure contents. The + lpc10_encoder_state structure should *not* be initialized for every + frame of encoded speech. Once at the beginning of execution, done + automatically for you by create_lpc10_encoder_state(), is enough. + + init_lpc10_encoder_state() reinitializes the lpc10_encoder_state + structure. This might be useful if you are finished processing one + sound sample, and want to reuse the same lpc10_encoder_state + structure to process another sound sample. There might be other + uses as well. + + Note that the comments in the lpc10/lpcenc.c file imply that indices + 1 through 180 of array speech[] are read. These comments were + written for the Fortran version of the code, before it was + automatically converted to C by the conversion program f2c. f2c + seems to use the convention that the pointers to arrays passed as + function arguments point to the first index used in the Fortran + code, whatever index that might be (usually 1), and then it modifies + the pointer inside of the function, like so: + + if (speech) { + --speech; + } + + So that the code can access the first value at index 1 and the last + at index 180. This makes the translated C code "closer" to the + original Fortran code. + + The calling sequence for the decoder is similar to the encoder. The + only significant difference is that the array bits[] is read + (indices 0 through (LPC10_BITS_IN_COMPRESSED_FRAME-1)), and the + array speech[] is written (indices 0 through + (LPC10_SAMPLES_PER_FRAME-1)). + + */ + +struct lpc10_encoder_state * create_lpc10_encoder_state (); +void init_lpc10_encoder_state (struct lpc10_encoder_state *st); +int lpc10_encode (real *speech, INT32 *bits, struct lpc10_encoder_state *st); + +struct lpc10_decoder_state * create_lpc10_decoder_state (); +void init_lpc10_decoder_state (struct lpc10_decoder_state *st); +int lpc10_decode (INT32 *bits, real *speech, struct lpc10_decoder_state *st); + +#endif /* __LPC10_H__ */ diff --git a/linphone/lpc10-1.5/lpc10_wrapper.c b/linphone/lpc10-1.5/lpc10_wrapper.c new file mode 100644 index 000000000..333b81f89 --- /dev/null +++ b/linphone/lpc10-1.5/lpc10_wrapper.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include "lpc10_wrapper.h" +#include + +/* the public codec_info_t*/ + +struct codec_info LPC10codec_info= +{ + "LPC10-1.5", + LPC10_SAMPLES_PER_FRAME*2, /* size in bytes of the uncompressed frame*/ + ((LPC10_BITS_IN_COMPRESSED_FRAME/8) + 1), /* 7 bytes */ /* size in bytes of compressed frame*/ + 2400, /* bit rate*/ + {{ + 8000 + }}, /* audio sampling freq*/ + LPC10codec_new, /* codec constructor*/ + 115, /* payload type */ + "lpc10-15/8000/1", /*description */ + CODEC_AUDIO, /* type*/ + 0, /*usable, set later*/ + 1 /*usable for user, default value*/ +}; + +/* The return value of each of these calls is the same as that + returned by fread/fwrite, which should be the number of samples + successfully read/written, not the number of bytes. */ + +static int +read_16bit_samples(INT16 int16samples[], float speech[], int n) +{ + int i; + + /* Convert 16 bit integer samples to floating point values in the + range [-1,+1]. */ + + for (i = 0; i < n; i++) { + speech[i] = ((float) int16samples[i]) / 32768.0; + } + + return (n); +} + + + +static int +write_16bit_samples(INT16 int16samples[], float speech[], int n) +{ + int i; + float real_sample; + + /* Convert floating point samples in range [-1,+1] to 16 bit + integers. */ + for (i = 0; i < n; i++) { + real_sample = 32768.0 * speech[i]; + if (real_sample < -32768.0) { + int16samples[i] = -32768; + } else if (real_sample > 32767.0) { + int16samples[i] = 32767; + } else { + int16samples[i] = real_sample; + } + } + return (n); +} + +/* + +Write the bits in bits[0] through bits[len-1] to file f, in "packed" +format. + +bits is expected to be an array of len integer values, where each +integer is 0 to represent a 0 bit, and any other value represents a 1 +bit. This bit string is written to the file f in the form of several +8 bit characters. If len is not a multiple of 8, then the last +character is padded with 0 bits -- the padding is in the least +significant bits of the last byte. The 8 bit characters are "filled" +in order from most significant bit to least significant. + +*/ + +static void +write_bits(unsigned char *data, INT32 *bits, int len) +{ + int i; /* generic loop variable */ + unsigned char mask; /* The next bit position within the + variable "data" to place the next + bit. */ + + + /* Fill in the array bits. + * The first compressed output bit will be the most significant + * bit of the byte, so initialize mask to 0x80. The next byte of + * compressed data is initially 0, and the desired bits will be + * turned on below. + */ + mask = 0x80; + *data = 0; + + for (i = 0; i < len; i++) { + /* Turn on the next bit of output data, if necessary. */ + if (bits[i]) { + (*data) |= mask; + } + /* + * If the byte data is full, determined by mask becoming 0, + * then write the byte to the output file, and reinitialize + * data and mask for the next output byte. Also add the byte + * if (i == len-1), because if len is not a multiple of 8, + * then mask won't yet be 0. */ + mask >>= 1; + if ((mask == 0) || (i == len-1)) { + data++; + *data = 0; + mask = 0x80; + } + } +} + + + +/* + +Read bits from file f into bits[0] through bits[len-1], in "packed" +format. + +Read ceiling(len/8) characters from file f, if that many are available +to read, otherwise read to the end of the file. The first character's +8 bits, in order from MSB to LSB, are used to fill bits[0] through +bits[7]. The second character's bits are used to fill bits[8] through +bits[15], and so on. If ceiling(len/8) characters are available to +read, and len is not a multiple of 8, then some of the least +significant bits of the last character read are completely ignored. +Every entry of bits[] that is modified is changed to either a 0 or a +1. + +The number of bits successfully read is returned, and is always in the +range 0 to len, inclusive. If it is less than len, it will always be +a multiple of 8. + +*/ + +static int +read_bits(unsigned char *data, INT32 *bits, int len) +{ + int i,ind=0; /* generic loop variable */ + int c=0; + + /* Unpack the array bits into coded_frame. */ + for (i = 0; i < len; i++) { + if ((i % 8) == 0) { + c = (int)(data[ind]); + ind++; + } + if (c & (0x80 >> (i & 7))) { + bits[i] = 1; + } else { + bits[i] = 0; + } + } + return (len); +} + + + + +Codec *LPC10codec_new() +{ + LPC10Codec *obj; + + obj=(LPC10Codec*)malloc(sizeof(LPC10Codec)); + obj->baseclass._getinfo=&wlpc10_getinfo; + obj->baseclass._encode=&wlpc10_encode; + obj->baseclass._decode=&wlpc10_decode; + obj->baseclass._destroy=&wlpc10_destroy; + + obj->enc = create_lpc10_encoder_state(); + if (obj->enc == NULL) { + fprintf(stderr, "Couldn't allocate %d bytes for encoder state.\n", + sizeof(struct lpc10_encoder_state)); + return(NULL); + } + obj->dec = create_lpc10_decoder_state(); + if (obj->dec == NULL) { + fprintf(stderr, "Couldn't allocate %d bytes for decoder state.\n", + sizeof(struct lpc10_decoder_state)); + return(NULL); + } + return((Codec*)obj); +} + + + + +void wlpc10_getinfo(Codec *codec, struct codec_info *info) +{ + memcpy(info,&LPC10codec_info,sizeof(struct codec_info)); +} +void wlpc10_encode(Codec *codec, char *frame, char *data) +{ + float speech[LPC10_SAMPLES_PER_FRAME]; + INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + LPC10Codec *obj=(LPC10Codec*)codec; /* we should make a few check to see if this codec is a LPC10...*/ + + read_16bit_samples((INT16*)frame, speech, LPC10_SAMPLES_PER_FRAME); + lpc10_encode(speech, bits, obj->enc); + write_bits(data, bits, LPC10_BITS_IN_COMPRESSED_FRAME); +} + +void wlpc10_decode(Codec *codec,char *data, char *frame) +{ + float speech[LPC10_SAMPLES_PER_FRAME]; + INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + LPC10Codec *obj=(LPC10Codec*)codec; /* we should make a few check to see if this codec is a LPC10...*/ + + read_bits(data, bits, LPC10_BITS_IN_COMPRESSED_FRAME); + lpc10_decode(bits,speech, obj->dec); + write_16bit_samples((INT16*)frame, speech, LPC10_SAMPLES_PER_FRAME); +} + +void wlpc10_destroy(Codec *codec) +{ + LPC10Codec *obj=(LPC10Codec*)codec; /* we should make a few check to see if this codec is a LPC10...*/ + + free(obj->enc); + free(obj->dec); + free(obj); +} \ No newline at end of file diff --git a/linphone/lpc10-1.5/lpc10_wrapper.h b/linphone/lpc10-1.5/lpc10_wrapper.h new file mode 100644 index 000000000..73241b169 --- /dev/null +++ b/linphone/lpc10-1.5/lpc10_wrapper.h @@ -0,0 +1,34 @@ +#include "../console/codec.h" +#include "lpc10.h" + + +/* +int read_16bit_samples(INT16 int16samples[], float speech[], int n); +int write_16bit_samples(INT16 int16samples[], float speech[], int n); + + +void write_bits(unsigned char *data, INT32 *bits, int len); +int read_bits(unsigned char *data, INT32 *bits, int len); +*/ + +/* the following code has been added by Simon MORLAT to make lpc10 interface compatible with linphone*/ + +/*Class definition*/ + +typedef struct _LPC10Codec +{ + Codec baseclass; /* Codec must be the first element of the structure in order to have the object mechanism to work*/ + struct lpc10_encoder_state *enc; + struct lpc10_decoder_state *dec; +} LPC10Codec; + +/* this the constructor for derivate class LPC10Codec*/ +Codec *LPC10codec_new(); + +extern struct codec_info LPC10codec_info; + +/* these are the overrides for the base class 's functions*/ +void wlpc10_getinfo(Codec *codec,struct codec_info *info); +void wlpc10_encode(Codec *codec,char *frame, char *data); +void wlpc10_decode(Codec *codec,char *data, char *frame); +void wlpc10_destroy(Codec *codec); diff --git a/linphone/lpc10-1.5/lpcdec.c b/linphone/lpc10-1.5/lpcdec.c new file mode 100644 index 000000000..30cdba65b --- /dev/null +++ b/linphone/lpc10-1.5/lpcdec.c @@ -0,0 +1,273 @@ +/* + +$Log: lpcdec.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:30:11 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:48 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int lpcdec_(integer *bits, real *speech); +extern int initlpcdec_(void); +/* comlen contrl_ 12 */ +/*:ref: chanrd_ 14 5 4 4 4 4 4 */ +/*:ref: decode_ 14 7 4 4 4 4 4 6 6 */ +/*:ref: synths_ 14 6 4 4 6 6 6 4 */ +/*:ref: initdecode_ 14 0 */ +/*:ref: initsynths_ 14 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* Table of constant values */ + +static integer c__10 = 10; + +/* ***************************************************************** */ + +/* $Log: lpcdec.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:30:11 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:48 jaf + * Initial revision + * */ +/* Revision 1.1 1996/03/28 00:03:00 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Decode 54 bits to one frame of 180 speech samples. */ + +/* Input: */ +/* BITS - 54 encoded bits, stored 1 per array element. */ +/* Indices 1 through 53 read (SYNC bit ignored). */ +/* Output: */ +/* SPEECH - Speech encoded as real values in the range [-1,+1]. */ +/* Indices 1 through 180 written. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITLPCDEC. */ + +/* Subroutine */ int lpc10_decode(integer *bits, real *speech, + struct lpc10_decoder_state *st) +{ + integer irms, voice[2], pitch, ipitv; + extern /* Subroutine */ int decode_(integer *, integer *, integer *, + integer *, integer *, real *, real *, struct lpc10_decoder_state *); + real rc[10]; + extern /* Subroutine */ int chanrd_(integer *, integer *, integer *, + integer *, integer *), synths_(integer *, + integer *, real *, real *, real *, integer *, + struct lpc10_decoder_state *); + integer irc[10], len; + real rms; + +/* $Log: lpcdec.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:30:11 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:48 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments */ +/* $Log: lpcdec.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:30:11 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:48 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Local variables that need not be saved */ +/* Uncoded speech parameters */ +/* Coded speech parameters */ +/* Others */ +/* Local state */ +/* None */ + /* Parameter adjustments */ + if (bits) { + --bits; + } + if (speech) { + --speech; + } + + /* Function Body */ + + chanrd_(&c__10, &ipitv, &irms, irc, &bits[1]); + decode_(&ipitv, &irms, irc, voice, &pitch, &rms, rc, st); + synths_(voice, &pitch, &rms, rc, &speech[1], &len, st); + return 0; +} /* lpcdec_ */ diff --git a/linphone/lpc10-1.5/lpcenc.c b/linphone/lpc10-1.5/lpcenc.c new file mode 100644 index 000000000..7805a0e8c --- /dev/null +++ b/linphone/lpc10-1.5/lpcenc.c @@ -0,0 +1,163 @@ +/* + +$Log: lpcenc.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:31:21 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:44 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int lpcenc_(real *speech, integer *bits); +extern int initlpcenc_(void); +/*:ref: prepro_ 14 2 6 4 */ +/*:ref: analys_ 14 5 6 4 4 6 6 */ +/*:ref: encode_ 14 7 4 4 6 6 4 4 4 */ +/*:ref: chanwr_ 14 5 4 4 4 4 4 */ +/*:ref: initprepro_ 14 0 */ +/*:ref: initanalys_ 14 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__180 = 180; +static integer c__10 = 10; + +/* ***************************************************************** */ + +/* $Log: lpcenc.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:31:21 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:44 jaf + * Initial revision + * */ +/* Revision 1.2 1996/03/28 00:01:22 jaf */ +/* Commented out some trace statements. */ + +/* Revision 1.1 1996/03/28 00:00:27 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Encode one frame of 180 speech samples to 54 bits. */ + +/* Input: */ +/* SPEECH - Speech encoded as real values in the range [-1,+1]. */ +/* Indices 1 through 180 read, and modified (by PREPRO). */ +/* Output: */ +/* BITS - 54 encoded bits, stored 1 per array element. */ +/* Indices 1 through 54 written. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITLPCENC. */ + +/* Subroutine */ int lpc10_encode(real *speech, integer *bits, + struct lpc10_encoder_state *st) +{ + integer irms, voice[2], pitch, ipitv; + real rc[10]; + extern /* Subroutine */ int encode_(integer *, integer *, real *, real *, + integer *, integer *, integer *), chanwr_(integer *, integer *, + integer *, integer *, integer *, struct lpc10_encoder_state *), + analys_(real *, integer *, + integer *, real *, real *, struct lpc10_encoder_state *), + prepro_(real *, integer *, struct lpc10_encoder_state *); + integer irc[10]; + real rms; + +/* Arguments */ +/* $Log: lpcenc.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:31:21 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Changed name of function from lpcenc_ to lpc10_encode, simply to make + * all lpc10 functions have more consistent naming with each other. + * + * Revision 1.1 1996/08/19 22:31:44 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Local variables that need not be saved */ +/* Uncoded speech parameters */ +/* Coded speech parameters */ +/* Local state */ +/* None */ + /* Parameter adjustments */ + if (speech) { + --speech; + } + if (bits) { + --bits; + } + + /* Function Body */ + prepro_(&speech[1], &c__180, st); + analys_(&speech[1], voice, &pitch, &rms, rc, st); + encode_(voice, &pitch, &rms, rc, &ipitv, &irms, irc); + chanwr_(&c__10, &ipitv, &irms, irc, &bits[1], st); + return 0; +} /* lpcenc_ */ diff --git a/linphone/lpc10-1.5/lpcini.c b/linphone/lpc10-1.5/lpcini.c new file mode 100644 index 000000000..6d88bfb75 --- /dev/null +++ b/linphone/lpc10-1.5/lpcini.c @@ -0,0 +1,399 @@ +/* + +$Log: lpcini.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:35:41 jaf + * Added functions for allocating and initializing lpc10_encoder_state + * and lpc10_decoder_state structures. + * + * Revision 1.1 1996/08/19 22:31:40 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int lpcini_(void); +/* comlen contrl_ 12 */ +/*:ref: initlpcenc_ 14 0 */ +/*:ref: initlpcdec_ 14 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +#include + +/* Common Block Declarations */ + +struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* ***************************************************************** */ + +/* $Log: lpcini.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:35:41 jaf + * Added functions for allocating and initializing lpc10_encoder_state + * and lpc10_decoder_state structures. + * + * Revision 1.1 1996/08/19 22:31:40 jaf + * Initial revision + * */ +/* Revision 1.1 1996/03/28 00:04:05 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Initialize COMMON block variables used by LPC-10 encoder and decoder, */ +/* and call initialization routines for both of them. */ + +/* Subroutine */ int lpcini_(void) +{ + +/* $Log: lpcini.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:35:41 jaf + * Added functions for allocating and initializing lpc10_encoder_state + * and lpc10_decoder_state structures. + * + * Revision 1.1 1996/08/19 22:31:40 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* $Log: lpcini.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:35:41 jaf + * Added functions for allocating and initializing lpc10_encoder_state + * and lpc10_decoder_state structures. + * + * Revision 1.1 1996/08/19 22:31:40 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ + contrl_1.order = 10; + contrl_1.lframe = 180; + contrl_1.corrp = TRUE_; + return 0; +} /* lpcini_ */ + + + +/* Allocate memory for, and initialize, the state that needs to be + kept from encoding one frame to the next for a single + LPC-10-compressed audio stream. Return 0 if malloc fails, + otherwise return pointer to new structure. */ + +struct lpc10_encoder_state * +create_lpc10_encoder_state() +{ + struct lpc10_encoder_state *st; + + st = (struct lpc10_encoder_state *) + malloc((unsigned) sizeof (struct lpc10_encoder_state)); + if (st != 0) { + init_lpc10_encoder_state(st); + } + return (st); +} + + + +void init_lpc10_encoder_state(struct lpc10_encoder_state *st) +{ + int i; + + lpcini_(); + + /* State used only by function hp100 */ + st->z11 = 0.0f; + st->z21 = 0.0f; + st->z12 = 0.0f; + st->z22 = 0.0f; + + /* State used by function analys */ + for (i = 0; i < 540; i++) { + st->inbuf[i] = 0.0f; + st->pebuf[i] = 0.0f; + } + for (i = 0; i < 696; i++) { + st->lpbuf[i] = 0.0f; + } + for (i = 0; i < 312; i++) { + st->ivbuf[i] = 0.0f; + } + st->bias = 0.0f; + /* integer osbuf[10]; /* no initial value necessary */ + st->osptr = 1; + for (i = 0; i < 3; i++) { + st->obound[i] = 0; + } + st->vwin[4] = 307; + st->vwin[5] = 462; + st->awin[4] = 307; + st->awin[5] = 462; + for (i = 0; i < 8; i++) { + st->voibuf[i] = 0; + } + for (i = 0; i < 3; i++) { + st->rmsbuf[i] = 0.0f; + } + for (i = 0; i < 30; i++) { + st->rcbuf[i] = 0.0f; + } + st->zpre = 0.0f; + + + /* State used by function onset */ + st->n = 0.0f; + st->d__ = 1.0f; + /* real fpc; /* no initial value necessary */ + for (i = 0; i < 16; i++) { + st->l2buf[i] = 0.0f; + } + st->l2sum1 = 0.0f; + st->l2ptr1 = 1; + st->l2ptr2 = 9; + /* integer lasti; /* no initial value necessary */ + st->hyst = FALSE_; + + /* State used by function voicin */ + st->dither = 20.0f; + st->maxmin = 0.0f; + for (i = 0; i < 6; i++) { + st->voice[i] = 0.0f; + } + st->lbve = 3000; + st->fbve = 3000; + st->fbue = 187; + st->ofbue = 187; + st->sfbue = 187; + st->lbue = 93; + st->olbue = 93; + st->slbue = 93; + st->snr = (real) (st->fbve / st->fbue << 6); + + /* State used by function dyptrk */ + for (i = 0; i < 60; i++) { + st->s[i] = 0.0f; + } + for (i = 0; i < 120; i++) { + st->p[i] = 0; + } + st->ipoint = 0; + st->alphax = 0.0f; + + /* State used by function chanwr */ + st->isync = 0; + +} + + + +/* Allocate memory for, and initialize, the state that needs to be + kept from decoding one frame to the next for a single + LPC-10-compressed audio stream. Return 0 if malloc fails, + otherwise return pointer to new structure. */ + +struct lpc10_decoder_state * +create_lpc10_decoder_state() +{ + struct lpc10_decoder_state *st; + + st = (struct lpc10_decoder_state *) + malloc((unsigned) sizeof (struct lpc10_decoder_state)); + if (st != 0) { + init_lpc10_decoder_state(st); + } + return (st); +} + + + +void init_lpc10_decoder_state(struct lpc10_decoder_state *st) +{ + int i; + + lpcini_(); + + /* State used by function decode */ + st->iptold = 60; + st->first = TRUE_; + st->ivp2h = 0; + st->iovoic = 0; + st->iavgp = 60; + st->erate = 0; + for (i = 0; i < 30; i++) { + st->drc[i] = 0; + } + for (i = 0; i < 3; i++) { + st->dpit[i] = 0; + st->drms[i] = 0; + } + + /* State used by function synths */ + for (i = 0; i < 360; i++) { + st->buf[i] = 0.0f; + } + st->buflen = 180; + + /* State used by function pitsyn */ + /* ivoico; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + /* ipito; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + st->rmso = 1.0f; + /* rco[10]; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + /* integer jsamp; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + st->first_pitsyn = TRUE_; + + /* State used by function bsynz */ + st->ipo = 0; + for (i = 0; i < 166; i++) { + st->exc[i] = 0.0f; + st->exc2[i] = 0.0f; + } + st->lpi1 = 0.0f; + st->lpi2 = 0.0f; + st->lpi3 = 0.0f; + st->hpi1 = 0.0f; + st->hpi2 = 0.0f; + st->hpi3 = 0.0f; + st->rmso_bsynz = 0.0f; + + /* State used by function random */ + st->j = 2; + st->k = 5; + st->y[0] = (shortint) -21161; + st->y[1] = (shortint) -8478; + st->y[2] = (shortint) 30892; + st->y[3] = (shortint) -10216; + st->y[4] = (shortint) 16950; + + /* State used by function deemp */ + st->dei1 = 0.0f; + st->dei2 = 0.0f; + st->deo1 = 0.0f; + st->deo2 = 0.0f; + st->deo3 = 0.0f; +} diff --git a/linphone/lpc10-1.5/lpfilt.c b/linphone/lpc10-1.5/lpfilt.c new file mode 100644 index 000000000..218140c2e --- /dev/null +++ b/linphone/lpc10-1.5/lpfilt.c @@ -0,0 +1,113 @@ +/* + +$Log: lpfilt.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:35 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer *nsamp); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* *********************************************************************** */ + +/* LPFILT Version 55 */ + +/* $Log: lpfilt.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:35 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/15 16:53:49 jaf */ +/* Just put comment header in standard form. */ + +/* Revision 1.2 1996/03/12 23:58:06 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:47:44 jaf */ +/* Initial revision */ + + +/* *********************************************************************** */ + +/* 31 Point Equiripple FIR Low-Pass Filter */ +/* Linear phase, delay = 15 samples */ + +/* Passband: ripple = 0.25 dB, cutoff = 800 Hz */ +/* Stopband: atten. = 40. dB, cutoff = 1240 Hz */ + +/* Inputs: */ +/* LEN - Length of speech buffers */ +/* NSAMP - Number of samples to filter */ +/* INBUF - Input speech buffer */ +/* Indices len-nsamp-29 through len are read. */ +/* Output: */ +/* LPBUF - Low passed speech buffer (must be different array than INBUF) */ +/* Indices len+1-nsamp through len are written. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int lpfilt_(real *inbuf, real *lpbuf, integer *len, integer * + nsamp) +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + integer j; + real t; + +/* Arguments */ +/* Parameters/constants */ +/* Local variables that need not be saved */ +/* Local state */ +/* None */ + /* Parameter adjustments */ + --lpbuf; + --inbuf; + + /* Function Body */ + i__1 = *len; + for (j = *len + 1 - *nsamp; j <= i__1; ++j) { + t = (inbuf[j] + inbuf[j - 30]) * -.0097201988f; + t += (inbuf[j - 1] + inbuf[j - 29]) * -.0105179986f; + t += (inbuf[j - 2] + inbuf[j - 28]) * -.0083479648f; + t += (inbuf[j - 3] + inbuf[j - 27]) * 5.860774e-4f; + t += (inbuf[j - 4] + inbuf[j - 26]) * .0130892089f; + t += (inbuf[j - 5] + inbuf[j - 25]) * .0217052232f; + t += (inbuf[j - 6] + inbuf[j - 24]) * .0184161253f; + t += (inbuf[j - 7] + inbuf[j - 23]) * 3.39723e-4f; + t += (inbuf[j - 8] + inbuf[j - 22]) * -.0260797087f; + t += (inbuf[j - 9] + inbuf[j - 21]) * -.0455563702f; + t += (inbuf[j - 10] + inbuf[j - 20]) * -.040306855f; + t += (inbuf[j - 11] + inbuf[j - 19]) * 5.029835e-4f; + t += (inbuf[j - 12] + inbuf[j - 18]) * .0729262903f; + t += (inbuf[j - 13] + inbuf[j - 17]) * .1572008878f; + t += (inbuf[j - 14] + inbuf[j - 16]) * .2247288674f; + t += inbuf[j - 15] * .250535965f; + lpbuf[j] = t; + } + return 0; +} /* lpfilt_ */ + diff --git a/linphone/lpc10-1.5/median.c b/linphone/lpc10-1.5/median.c new file mode 100644 index 000000000..b6ee59aff --- /dev/null +++ b/linphone/lpc10-1.5/median.c @@ -0,0 +1,77 @@ +/* + +$Log: median.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:31 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern integer median_(integer *d1, integer *d2, integer *d3); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* MEDIAN Version 45G */ + +/* $Log: median.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:31 jaf + * Initial revision + * */ +/* Revision 1.2 1996/03/14 22:30:22 jaf */ +/* Just rearranged the comments and local variable declarations a bit. */ + +/* Revision 1.1 1996/02/07 14:47:53 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Find median of three values */ + +/* Input: */ +/* D1,D2,D3 - Three input values */ +/* Output: */ +/* MEDIAN - Median value */ + +integer median_(integer *d1, integer *d2, integer *d3) +{ + /* System generated locals */ + integer ret_val; + +/* Arguments */ + ret_val = *d2; + if (*d2 > *d1 && *d2 > *d3) { + ret_val = *d1; + if (*d3 > *d1) { + ret_val = *d3; + } + } else if (*d2 < *d1 && *d2 < *d3) { + ret_val = *d1; + if (*d3 < *d1) { + ret_val = *d3; + } + } + return ret_val; +} /* median_ */ + diff --git a/linphone/lpc10-1.5/mload.c b/linphone/lpc10-1.5/mload.c new file mode 100644 index 000000000..004a05897 --- /dev/null +++ b/linphone/lpc10-1.5/mload.c @@ -0,0 +1,151 @@ +/* + +$Log: mload.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:25 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int mload_(integer *order, integer *awins, integer *awinf, real *speech, real *phi, real *psi); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ***************************************************************** */ + +/* MLOAD Version 48 */ + +/* $Log: mload.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:25 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/27 23:59:51 jaf */ +/* Added some more accurate comments about which indices of the argument */ +/* array SPEECH are read. I thought that this might be the cause of a */ +/* problem I've been having, but it isn't. */ + +/* Revision 1.4 1996/03/26 19:16:53 jaf */ +/* Commented out the code at the end that copied the lower triangular */ +/* half of PHI into the upper triangular half (making the resulting */ +/* matrix symmetric). The upper triangular half was never used by later */ +/* code in subroutine ANALYS. */ + +/* Revision 1.3 1996/03/18 21:16:00 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:47:41 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:48:01 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Load a covariance matrix. */ + +/* Input: */ +/* ORDER - Analysis order */ +/* AWINS - Analysis window start */ +/* AWINF - Analysis window finish */ +/* SPEECH(AWINF) - Speech buffer */ +/* Indices MIN(AWINS, AWINF-(ORDER-1)) through */ +/* MAX(AWINF, AWINS+(ORDER-1)) read. */ +/* As long as (AWINF-AWINS) .GE. (ORDER-1), */ +/* this is just indices AWINS through AWINF. */ +/* Output: */ +/* PHI(ORDER,ORDER) - Covariance matrix */ +/* Lower triangular half and diagonal written, and read.*/ +/* Upper triangular half untouched. */ +/* PSI(ORDER) - Prediction vector */ +/* Indices 1 through ORDER written, */ +/* and most are read after that. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int mload_(integer *order, integer *awins, integer *awinf, + real *speech, real *phi, real *psi) +{ + /* System generated locals */ + integer phi_dim1, phi_offset, i__1, i__2; + + /* Local variables */ + integer c__, i__, r__, start; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Load first column of triangular covariance matrix PHI */ + /* Parameter adjustments */ + --psi; + phi_dim1 = *order; + phi_offset = phi_dim1 + 1; + phi -= phi_offset; + --speech; + + /* Function Body */ + start = *awins + *order; + i__1 = *order; + for (r__ = 1; r__ <= i__1; ++r__) { + phi[r__ + phi_dim1] = 0.f; + i__2 = *awinf; + for (i__ = start; i__ <= i__2; ++i__) { + phi[r__ + phi_dim1] += speech[i__ - 1] * speech[i__ - r__]; + } + } +/* Load last element of vector PSI */ + psi[*order] = 0.f; + i__1 = *awinf; + for (i__ = start; i__ <= i__1; ++i__) { + psi[*order] += speech[i__] * speech[i__ - *order]; + } +/* End correct to get additional columns of PHI */ + i__1 = *order; + for (r__ = 2; r__ <= i__1; ++r__) { + i__2 = r__; + for (c__ = 2; c__ <= i__2; ++c__) { + phi[r__ + c__ * phi_dim1] = phi[r__ - 1 + (c__ - 1) * phi_dim1] - + speech[*awinf + 1 - r__] * speech[*awinf + 1 - c__] + + speech[start - r__] * speech[start - c__]; + } + } +/* End correct to get additional elements of PSI */ + i__1 = *order - 1; + for (c__ = 1; c__ <= i__1; ++c__) { + psi[c__] = phi[c__ + 1 + phi_dim1] - speech[start - 1] * speech[start + - 1 - c__] + speech[*awinf] * speech[*awinf - c__]; + } +/* Copy lower triangular section into upper (why bother?) */ +/* I'm commenting this out, since the upper triangular half of PHI +*/ +/* is never used by later code, unless a sufficiently high level of +*/ +/* tracing is turned on. */ +/* DO R = 1,ORDER */ +/* DO C = 1,R-1 */ +/* PHI(C,R) = PHI(R,C) */ +/* END DO */ +/* END DO */ + return 0; +} /* mload_ */ + diff --git a/linphone/lpc10-1.5/onset.c b/linphone/lpc10-1.5/onset.c new file mode 100644 index 000000000..e1b97a043 --- /dev/null +++ b/linphone/lpc10-1.5/onset.c @@ -0,0 +1,306 @@ +/* + +$Log: onset.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:37:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:31:18 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static real c_b2 = 1.f; + +/* ****************************************************************** */ + +/* ONSET Version 49 */ + +/* $Log: onset.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:37:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:31:18 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/15 16:41:01 jaf */ +/* Just rearranged INITONSET assignment orders to be consistent with */ +/* order of DATA statements in ONSET. */ + +/* Revision 1.4 1996/03/15 15:48:27 jaf */ +/* Changed some comments, and only reordered the DATA statements (their */ +/* meaning wasn't changed). */ + +/* Revision 1.3 1996/03/14 23:53:06 jaf */ +/* Added an entry INITONSET that reinitializes the local state variables */ +/* of subroutine ONSET. */ + +/* Rearranged quite a few comments, adding more explaining which */ +/* arguments were inputs, and how the modified ones can be changed. */ + +/* Revision 1.2 1996/03/12 23:53:00 jaf */ +/* Lots of comments added about the local state of this subroutine that */ +/* must be saved from one invocation to the next. */ + +/* One constant 180 replaced with LFRAME, which should be "more general", */ +/* even though it would probably require many more changes than this to */ +/* get this coder to work for other frame sizes. */ + +/* Revision 1.1 1996/02/07 14:48:09 jaf */ +/* Initial revision */ + + +/* ****************************************************************** */ + +/* Floating point version */ + + +/* Detection of onsets in (or slightly preceding) the futuremost frame */ +/* of speech. */ + + +/* Input: */ +/* PEBUF(SBUFL:SBUFH) - Preemphasized speech */ +/* Indices SBUFH-LFRAME through SBUFH are read. */ +/* OSLEN - Maximum number of onsets that can be stored in OSBUF. */ +/* SBUFL, SBUFH - Range of PEBUF */ +/* LFRAME - length of a frame, in samples */ +/* Input/Output: */ +/* OSBUF(OSLEN) - Buffer which holds sorted indexes of onsets */ +/* Indices A through B are modified, where A */ +/* is the original value of OSPTR, and B is the final */ +/* value of OSPTR-1. B is at most OSLEN. */ +/* OSPTR - Free pointer into OSBUF */ +/* Initial value should be .LE. OSLEN+1. */ +/* If so, final value grows by one for each new onset */ +/* found, and final value will be .LE. OSLEN+1. */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this subroutine, or */ +/* reinitialize its state for any other reason, call the ENTRY INITONSET. */ + +/* Subroutine */ int onset_(real *pebuf, integer *osbuf, integer * + osptr, integer *oslen, integer *sbufl, integer *sbufh, integer * + lframe, struct lpc10_encoder_state *st) +{ + /* Initialized data */ + + real *n; + real *d__; + real *l2buf; + real *l2sum1; + integer *l2ptr1; + integer *l2ptr2; + logical *hyst; + + /* System generated locals */ + integer pebuf_offset, i__1; + real r__1; + + /* Builtin functions */ + double r_sign(real *, real *); + + /* Local variables */ + integer i__; + integer *lasti; + real l2sum2; + real *fpc; + +/* Arguments */ +/* $Log: onset.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:37:55 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:31:18 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Parameters/constants */ +/* Parameters for onset detection algorithm: */ +/* L2 Threshold for filtered slope of FPC (function of L2WID!) */ +/* L2LAG Lag due to both filters which compute filtered slope of FPC */ +/* L2WID Width of the filter which computes the slope of FPC */ +/* OSHYST The number of samples of slope(FPC) which must be below */ +/* the threshold before a new onset may be declared. */ +/* Local variables that need not be saved */ +/* Local state */ +/* Variables */ +/* N, D Numerator and denominator of prediction filters */ +/* FPC Current prediction coefs */ +/* L2BUF, L2SUM1, L2SUM2 State of slope filter */ +/* The only "significant" change I've made is to change L2SUM2 out +*/ +/* of the list of local variables that need to be saved, since it */ +/* didn't need to be. */ +/* L2SUM1 need not be, but avoiding saving it would require a small +*/ +/* change to the body of the code. See comments below for an */ +/* example of how the code could be changed to avoid saving L2SUM1. +*/ +/* FPC and LASTI are saved from one invocation to the next, but */ +/* they are not given initial values. This is acceptable, because +*/ +/* FPC will be assigned a value the first time that this function */ +/* is called after D is initialized to 1, since the formula to */ +/* change D will not change it to 0 in one step, and the IF (D */ +/* .NE. 0) statement will execute its THEN part, initializing FPC. +*/ + +/* LASTI's value will not be used until HYST is .TRUE., and */ +/* whenever HYST is changed from its initial value of .FALSE., */ +/* LASTI is assigned a value. */ +/* In a C version of this coder, it would be nice if all of these */ +/* saved things, in this and all other subroutines, could be stored +*/ +/* in a single struct lpc10_coder_state_t, initialized with a call +*/ +/* to a function like lpc10_init(&lpc10_coder_state). In this way, +*/ +/* a program that used these functions could conveniently alternate +*/ +/* coding more than one distinct audio stream. */ + + n = &(st->n); + d__ = &(st->d__); + fpc = &(st->fpc); + l2buf = &(st->l2buf[0]); + l2sum1 = &(st->l2sum1); + l2ptr1 = &(st->l2ptr1); + l2ptr2 = &(st->l2ptr2); + lasti = &(st->lasti); + hyst = &(st->hyst); + + /* Parameter adjustments */ + if (osbuf) { + --osbuf; + } + if (pebuf) { + pebuf_offset = *sbufl; + pebuf -= pebuf_offset; + } + + /* Function Body */ + +/* The following line subtracted a hard-coded "180" from LASTI, */ +/* instead of using a variable like LFRAME or a constant like */ +/* MAXFRM. I changed it to LFRAME, for "generality". */ + if (*hyst) { + *lasti -= *lframe; + } + i__1 = *sbufh; + for (i__ = *sbufh - *lframe + 1; i__ <= i__1; ++i__) { +/* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1. +*/ + *n = (pebuf[i__] * pebuf[i__ - 1] + (*n) * 63.f) / 64.f; +/* Computing 2nd power */ + r__1 = pebuf[i__ - 1]; + *d__ = (r__1 * r__1 + (*d__) * 63.f) / 64.f; + if ((*d__) != 0.f) { + if (abs(*n) > (*d__)) { + *fpc = r_sign(&c_b2, n); + } else { + *fpc = (*n) / (*d__); + } + } +/* Filter FPC */ +/* In order to allow L2SUM1 not to be saved from one invocation +of */ +/* this subroutine to the next, one could change the sequence of + */ +/* assignments below, up to the IF statement, to the following. + In */ +/* addition, the initial value of L2PTR2 should be changed to */ +/* L2WID/2 instead of L2WID/2+1. */ + +/* L2SUM1 = L2BUF(L2PTR2) */ +/* L2PTR2 = MOD(L2PTR2,L2WID)+1 */ +/* L2SUM1 = L2SUM1 - L2BUF(L2PTR2) + FPC */ +/* L2BUF(L2PTR2) = L2SUM1 */ + +/* * The following lines didn't change from the original: */ +/* L2SUM2 = L2BUF(L2PTR1) */ +/* L2BUF(L2PTR1) = FPC */ +/* L2PTR1 = MOD(L2PTR1,L2WID)+1 */ + + l2sum2 = l2buf[*l2ptr1 - 1]; + *l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc; + l2buf[*l2ptr2 - 1] = *l2sum1; + l2buf[*l2ptr1 - 1] = *fpc; + *l2ptr1 = *l2ptr1 % 16 + 1; + *l2ptr2 = *l2ptr2 % 16 + 1; + if ((r__1 = *l2sum1 - l2sum2, abs(r__1)) > 1.7f) { + if (! (*hyst)) { +/* Ignore if buffer full */ + if (*osptr <= *oslen) { + osbuf[*osptr] = i__ - 9; + ++(*osptr); + } + *hyst = TRUE_; + } + *lasti = i__; +/* After one onset detection, at least OSHYST sample times m +ust go */ +/* by before another is allowed to occur. */ + } else if ((*hyst) && i__ - *lasti >= 10) { + *hyst = FALSE_; + } + } + return 0; +} /* onset_ */ diff --git a/linphone/lpc10-1.5/pitsyn.c b/linphone/lpc10-1.5/pitsyn.c new file mode 100644 index 000000000..a4765a7bb --- /dev/null +++ b/linphone/lpc10-1.5/pitsyn.c @@ -0,0 +1,556 @@ +/* + +$Log: pitsyn.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:40:12 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:31:12 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv, integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio, struct lpc10_decoder_state *st); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ***************************************************************** */ + +/* PITSYN Version 53 */ + +/* $Log: pitsyn.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:40:12 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:31:12 jaf + * Initial revision + * */ +/* Revision 1.2 1996/03/25 18:49:07 jaf */ +/* Added commments about which indices of array arguments are read or */ +/* written. */ + +/* Rearranged local variable declarations to indicate which need to be */ +/* saved from one invocation to the next. Added entry INITPITSYN to */ +/* reinitialize local state variables, if desired. */ + +/* Added lots of comments about proving that the maximum number of pitch */ +/* periods (NOUT) that can be returned is 16. The call to STOP that */ +/* could happen if NOUT got too large was removed as a result. */ + +/* Also proved that the total number of samples returned from N calls, */ +/* each with identical values of LFRAME, will always be in the range */ +/* N*LFRAME-MAXPIT+1 to N*LFRAME. */ + +/* Revision 1.1 1996/02/07 14:48:18 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* Synthesize a single pitch epoch */ + +/* Input: */ +/* ORDER - Synthesis order (number of RC's) */ +/* VOICE - Half frame voicing decisions */ +/* Indices 1 through 2 read. */ +/* LFRAME - Length of speech buffer */ +/* Input/Output: */ +/* PITCH - Pitch */ +/* This value should be in the range MINPIT (20) to MAXPIT */ +/* (156), inclusive. */ +/* PITCH can be modified under some conditions. */ +/* RMS - Energy (can be modified) */ +/* RMS is changed to 1 if the value passed in is less than 1. */ +/* RC - Reflection coefficients */ +/* Indices 1 through ORDER can be temporarily overwritten with */ +/* RCO, and then replaced with original values, under some */ +/* conditions. */ +/* Output: */ +/* IVUV - Pitch epoch voicing decisions */ +/* Indices (I) of IVUV, IPITI, and RMSI are written, */ +/* and indices (J,I) of RCI are written, */ +/* where I ranges from 1 to NOUT, and J ranges from 1 to ORDER. */ +/* IPITI - Pitch epoch length */ +/* RMSI - Pitch epoch energy */ +/* RCI - Pitch epoch RC's */ +/* NOUT - Number of pitch periods in this frame */ +/* This is at least 0, at least 1 if MAXPIT .LT. LFRAME (this */ +/* is currently true on every call), and can never be more than */ +/* (LFRAME+MAXPIT-1)/PITCH, which is currently 16 with */ +/* LFRAME=180, MAXPIT=156, and PITCH .GE. 20, as SYNTHS */ +/* guarantees when it calls this subroutine. */ +/* RATIO - Previous to present energy ratio */ +/* Always assigned a value. */ + +/* Subroutine */ int pitsyn_(integer *order, integer *voice, + integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv, + integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio, + struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + real *rmso; + logical *first; + + /* System generated locals */ + integer rci_dim1, rci_offset, i__1, i__2; + real r__1; + + /* Builtin functions */ + double log(doublereal), exp(doublereal); + + /* Local variables */ + real alrn, alro, yarc[10], prop; + integer i__, j, vflag, jused, lsamp; + integer *jsamp; + real slope; + integer *ipito; + real uvpit; + integer ip, nl, ivoice; + integer *ivoico; + integer istart; + real *rco; + real xxy; + +/* Arguments */ +/* $Log: pitsyn.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:40:12 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:31:12 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Local variables that need not be saved */ +/* LSAMP is initialized in the IF (FIRST) THEN clause, but it is */ +/* not used the first time through, and it is given a value before +*/ +/* use whenever FIRST is .FALSE., so it appears unnecessary to */ +/* assign it a value when FIRST is .TRUE. */ +/* Local state */ +/* FIRST - .TRUE. only on first call to PITSYN. */ +/* IVOICO - Previous VOICE(2) value. */ +/* IPITO - Previous PITCH value. */ +/* RMSO - Previous RMS value. */ +/* RCO - Previous RC values. */ + +/* JSAMP - If this routine is called N times with identical values of */ +/* LFRAME, then the total length of all pitch periods returned */ +/* is always N*LFRAME-JSAMP, and JSAMP is always in the range 0 +*/ +/* to MAXPIT-1 (see below for why this is so). Thus JSAMP is */ +/* the number of samples "left over" from the previous call to */ +/* PITSYN, that haven't been "used" in a pitch period returned */ +/* from this subroutine. Every time this subroutine is called, +*/ +/* it returns pitch periods with a total length of at most */ +/* LFRAME+JSAMP. */ + +/* IVOICO, IPITO, RCO, and JSAMP need not be assigned an initial value */ +/* with a DATA statement, because they are always initialized on the */ +/* first call to PITSYN. */ + +/* FIRST and RMSO should be initialized with DATA statements, because */ +/* even on the first call, they are used before being initialized. */ + /* Parameter adjustments */ + if (rc) { + --rc; + } + if (rci) { + rci_dim1 = *order; + rci_offset = rci_dim1 + 1; + rci -= rci_offset; + } + if (voice) { + --voice; + } + if (ivuv) { + --ivuv; + } + if (ipiti) { + --ipiti; + } + if (rmsi) { + --rmsi; + } + + /* Function Body */ + ivoico = &(st->ivoico); + ipito = &(st->ipito); + rmso = &(st->rmso); + rco = &(st->rco[0]); + jsamp = &(st->jsamp); + first = &(st->first_pitsyn); + + if (*rms < 1.f) { + *rms = 1.f; + } + if (*rmso < 1.f) { + *rmso = 1.f; + } + uvpit = 0.f; + *ratio = *rms / (*rmso + 8.f); + if (*first) { + lsamp = 0; + ivoice = voice[2]; + if (ivoice == 0) { + *pitch = *lframe / 4; + } + *nout = *lframe / *pitch; + *jsamp = *lframe - *nout * *pitch; + +/* SYNTHS only calls this subroutine with PITCH in the range +20 */ +/* to 156. LFRAME = MAXFRM = 180, so NOUT is somewhere in th +e */ +/* range 1 to 9. */ + +/* JSAMP is "LFRAME mod PITCH", so it is in the range 0 to */ +/* (PITCH-1), or 0 to MAXPIT-1=155, after the first call. */ + + i__1 = *nout; + for (i__ = 1; i__ <= i__1; ++i__) { + i__2 = *order; + for (j = 1; j <= i__2; ++j) { + rci[j + i__ * rci_dim1] = rc[j]; + } + ivuv[i__] = ivoice; + ipiti[i__] = *pitch; + rmsi[i__] = *rms; + } + *first = FALSE_; + } else { + vflag = 0; + lsamp = *lframe + *jsamp; + slope = (*pitch - *ipito) / (real) lsamp; + *nout = 0; + jused = 0; + istart = 1; + if (voice[1] == *ivoico && voice[2] == voice[1]) { + if (voice[2] == 0) { +/* SSUV - - 0 , 0 , 0 */ + *pitch = *lframe / 4; + *ipito = *pitch; + if (*ratio > 8.f) { + *rmso = *rms; + } + } +/* SSVC - - 1 , 1 , 1 */ + slope = (*pitch - *ipito) / (real) lsamp; + ivoice = voice[2]; + } else { + if (*ivoico != 1) { + if (*ivoico == voice[1]) { +/* UV2VC2 - - 0 , 0 , 1 */ + nl = lsamp - *lframe / 4; + } else { +/* UV2VC1 - - 0 , 1 , 1 */ + nl = lsamp - *lframe * 3 / 4; + } + ipiti[1] = nl / 2; + ipiti[2] = nl - ipiti[1]; + ivuv[1] = 0; + ivuv[2] = 0; + rmsi[1] = *rmso; + rmsi[2] = *rmso; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + rci[i__ + rci_dim1] = rco[i__ - 1]; + rci[i__ + (rci_dim1 << 1)] = rco[i__ - 1]; + rco[i__ - 1] = rc[i__]; + } + slope = 0.f; + *nout = 2; + *ipito = *pitch; + jused = nl; + istart = nl + 1; + ivoice = 1; + } else { + if (*ivoico != voice[1]) { +/* VC2UV1 - - 1 , 0 , 0 */ + lsamp = *lframe / 4 + *jsamp; + } else { +/* VC2UV2 - - 1 , 1 , 0 */ + lsamp = *lframe * 3 / 4 + *jsamp; + } + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + yarc[i__ - 1] = rc[i__]; + rc[i__] = rco[i__ - 1]; + } + ivoice = 1; + slope = 0.f; + vflag = 1; + } + } +/* Here is the value of most variables that are used below, depending +on */ +/* the values of IVOICO, VOICE(1), and VOICE(2). VOICE(1) and VOICE(2 +) */ +/* are input arguments, and IVOICO is the value of VOICE(2) on the */ +/* previous call (see notes for the IF (NOUT .NE. 0) statement near th +e */ +/* end). Each of these three values is either 0 or 1. These three */ +/* values below are given as 3-bit long strings, in the order IVOICO, +*/ +/* VOICE(1), and VOICE(2). It appears that the code above assumes tha +t */ +/* the bit sequences 010 and 101 never occur, but I wonder whether a +*/ +/* large enough number of bit errors in the channel could cause such a + */ +/* thing to happen, and if so, could that cause NOUT to ever go over 1 +1? */ + +/* Note that all of the 180 values in the table are really LFRAME, but + */ +/* 180 has fewer characters, and it makes the table a little more */ +/* concrete. If LFRAME is ever changed, keep this in mind. Similarly +, */ +/* 135's are 3*LFRAME/4, and 45's are LFRAME/4. If LFRAME is not a */ +/* multiple of 4, then the 135 for NL-JSAMP is actually LFRAME-LFRAME/ +4, */ +/* and the 45 for NL-JSAMP is actually LFRAME-3*LFRAME/4. */ + +/* Note that LSAMP-JSAMP is given as the variable. This was just for +*/ +/* brevity, to avoid adding "+JSAMP" to all of the column entries. */ +/* Similarly for NL-JSAMP. */ + +/* Variable | 000 001 011,010 111 110 100,101 */ +/* ------------+-------------------------------------------------- */ +/* ISTART | 1 NL+1 NL+1 1 1 1 */ +/* LSAMP-JSAMP | 180 180 180 180 135 45 */ +/* IPITO | 45 PITCH PITCH oldPITCH oldPITCH oldPITCH */ +/* SLOPE | 0 0 0 seebelow 0 0 */ +/* JUSED | 0 NL NL 0 0 0 */ +/* PITCH | 45 PITCH PITCH PITCH PITCH PITCH */ +/* NL-JSAMP | -- 135 45 -- -- -- */ +/* VFLAG | 0 0 0 0 1 1 */ +/* NOUT | 0 2 2 0 0 0 */ +/* IVOICE | 0 1 1 1 1 1 */ + +/* while_loop | once once once once twice twice */ + +/* ISTART | -- -- -- -- JUSED+1 JUSED+1 */ +/* LSAMP-JSAMP | -- -- -- -- 180 180 */ +/* IPITO | -- -- -- -- oldPITCH oldPITCH */ +/* SLOPE | -- -- -- -- 0 0 */ +/* JUSED | -- -- -- -- ?? ?? */ +/* PITCH | -- -- -- -- PITCH PITCH */ +/* NL-JSAMP | -- -- -- -- -- -- */ +/* VFLAG | -- -- -- -- 0 0 */ +/* NOUT | -- -- -- -- ?? ?? */ +/* IVOICE | -- -- -- -- 0 0 */ + + +/* UVPIT is always 0.0 on the first pass through the DO WHILE (.TRUE.) + */ +/* loop below. */ + +/* The only possible non-0 value of SLOPE (in column 111) is */ +/* (PITCH-IPITO)/FLOAT(LSAMP) */ + +/* Column 101 is identical to 100. Any good properties we can prove +*/ +/* for 100 will also hold for 101. Similarly for 010 and 011. */ + +/* SYNTHS calls this subroutine with PITCH restricted to the range 20 +to */ +/* 156. IPITO is similarly restricted to this range, after the first +*/ +/* call. IP below is also restricted to this range, given the */ +/* definitions of IPITO, SLOPE, UVPIT, and that I is in the range ISTA +RT */ +/* to LSAMP. */ + + while(TRUE_) { + +/* JUSED is the total length of all pitch periods curr +ently */ +/* in the output arrays, in samples. */ + +/* An invariant of the DO I = ISTART,LSAMP loop below, + under */ +/* the condition that IP is always in the range 1 thro +ugh */ +/* MAXPIT, is: */ + +/* (I - MAXPIT) .LE. JUSED .LE. (I-1) */ + +/* Note that the final value of I is LSAMP+1, so that +after */ +/* the DO loop is complete, we know: */ + +/* (LSAMP - MAXPIT + 1) .LE. JUSED .LE. LSAMP */ + + i__1 = lsamp; + for (i__ = istart; i__ <= i__1; ++i__) { + r__1 = *ipito + slope * i__; + ip = r__1 + .5f; + if (uvpit != 0.f) { + ip = uvpit; + } + if (ip <= i__ - jused) { + ++(*nout); + +/* The following check is no longer nece +ssary, now that */ +/* we can prove that NOUT will never go +over 16. */ + +/* IF (NOUT .GT. 16) STOP 'PITSYN: too many epochs' +*/ + + ipiti[*nout] = ip; + *pitch = ip; + ivuv[*nout] = ivoice; + jused += ip; + prop = (jused - ip / 2) / (real) lsamp; + i__2 = *order; + for (j = 1; j <= i__2; ++j) { + alro = log((rco[j - 1] + 1) / (1 - rco[j - 1])); + alrn = log((rc[j] + 1) / (1 - rc[j])); + xxy = alro + prop * (alrn - alro); + xxy = exp(xxy); + rci[j + *nout * rci_dim1] = (xxy - 1) / (xxy + 1); + } + rmsi[*nout] = log(*rmso) + prop * (log(*rms) - log(*rmso)); + rmsi[*nout] = exp(rmsi[*nout]); + } + } + if (vflag != 1) { + goto L100; + } + +/* I want to prove what range UVPIT must lie in after +the */ +/* assignments to it below. To do this, I must determ +ine */ +/* what range (LSAMP-ISTART) must lie in, after the */ +/* assignments to ISTART and LSAMP below. */ + +/* Let oldLSAMP be the value of LSAMP at this point in + the */ +/* execution. This is 135+JSAMP in state 110, or 45+J +SAMP in */ +/* states 100 or 101. */ + +/* Given the loop invariant on JUSED above, we know th +at: */ + +/* (oldLSAMP - MAXPIT + 1) .LE. JUSED .LE. oldLSAMP */ + +/* ISTART is one more than this. */ + +/* Let newLSAMP be the value assigned to LSAMP below. + This */ +/* is 180+JSAMP. Thus (newLSAMP-oldLSAMP) is either 4 +5 or */ +/* 135, depending on the state. */ + +/* Thus, the range of newLSAMP-ISTART is: */ + +/* (newLSAMP-(oldLSAMP+1)) .LE. newLSAMP-ISTART */ +/* .LE. (newLSAMP-(oldLSAMP - MAXPIT + 2)) */ + +/* or: */ + +/* 46 .LE. newLSAMP-ISTART .LE. 133+MAXPIT .EQ. 289 */ + +/* Therefore, UVPIT is in the range 23 to 144 after th +e first */ +/* assignment to UVPIT below, and after the conditiona +l */ +/* assignment, it is in the range 23 to 90. */ + +/* The important thing is that it is in the range 20 t +o 156, */ +/* so that in the loop above, IP is always in this ran +ge. */ + + vflag = 0; + istart = jused + 1; + lsamp = *lframe + *jsamp; + slope = 0.f; + ivoice = 0; + uvpit = (real) ((lsamp - istart) / 2); + if (uvpit > 90.f) { + uvpit /= 2; + } + *rmso = *rms; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + rc[i__] = yarc[i__ - 1]; + rco[i__ - 1] = yarc[i__ - 1]; + } + } +L100: + *jsamp = lsamp - jused; + } +/* Given that the maximum pitch period MAXPIT .LT. LFRAME (this is +*/ +/* currently true on every call, since SYNTHS always sets */ +/* LFRAME=180), NOUT will always be .GE. 1 at this point. */ + if (*nout != 0) { + *ivoico = voice[2]; + *ipito = *pitch; + *rmso = *rms; + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + rco[i__ - 1] = rc[i__]; + } + } + return 0; +} /* pitsyn_ */ diff --git a/linphone/lpc10-1.5/placea.c b/linphone/lpc10-1.5/placea.c new file mode 100644 index 000000000..0336f7fa3 --- /dev/null +++ b/linphone/lpc10-1.5/placea.c @@ -0,0 +1,218 @@ +/* + +$Log: placea.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:07 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int placea_(integer *ipitch, integer *voibuf, integer *obound, integer *af, integer *vwin, integer *awin, integer *ewin, integer *lframe, integer *maxwin); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* *********************************************************************** */ + +/* PLACEA Version 48 */ + +/* $Log: placea.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:07 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/19 20:41:55 jaf */ +/* Added some conditions satisfied by the output values in EWIN. */ + +/* Revision 1.4 1996/03/19 20:24:17 jaf */ +/* Added some conditions satisfied by the output values in AWIN. */ + +/* Revision 1.3 1996/03/18 21:40:04 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:43:09 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:48:31 jaf */ +/* Initial revision */ + + +/* *********************************************************************** */ +/* Input: */ +/* IPITCH */ +/* VOIBUF */ +/* Indices (2,AF-2), (1,AF-1), (2,AF-1), (1,AF), and (2,AF) read.*/ +/* All other indices untouched. */ +/* OBOUND */ +/* AF */ +/* VWIN */ +/* Indices (1,AF) and (2,AF) read. */ +/* All other indices untouched. */ +/* LFRAME */ +/* MAXWIN */ +/* Input/Output: */ +/* AWIN */ +/* Index (1,AF-1) read. */ +/* Indices (1,AF) and (2,AF) written, and then read. */ +/* All other indices untouched. */ +/* In all cases (except possibly one), the final values will */ +/* satisfy the condition: AWIN(2,AF)-AWIN(1,AF)+1 = MAXWIN. */ +/* In that other case, */ +/* AWIN(1,AF)=VWIN(1,AF) and AWIN(2,AF)=VWIN(2,AF). */ +/* Output: */ +/* EWIN */ +/* Indices (1,AF) and (2,AF) written. */ +/* All other indices untouched. */ +/* In all cases, the final values will satisfy the condition: */ +/* AWIN(1,AF) .LE. EWIN(1,AF) .LE. EWIN(2,AF) .LE. AWIN(2,AF) */ +/* In other words, the energy window is a sub-window of */ +/* the analysis window. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int placea_(integer *ipitch, integer *voibuf, integer * + obound, integer *af, integer *vwin, integer *awin, integer *ewin, + integer *lframe, integer *maxwin) +{ + /* System generated locals */ + real r__1; + + /* Builtin functions */ + integer i_nint(real *); + + /* Local variables */ + logical allv, winv; + integer i__, j, k, l, hrange; + logical ephase; + integer lrange; + +/* Arguments */ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + ewin -= 3; + awin -= 3; + vwin -= 3; + --voibuf; + + /* Function Body */ + lrange = (*af - 2) * *lframe + 1; + hrange = *af * *lframe; +/* Place the Analysis window based on the voicing window */ +/* placement, onsets, tentative voicing decision, and pitch. */ + +/* Case 1: Sustained Voiced Speech */ +/* If the five most recent voicing decisions are */ +/* voiced, then the window is placed phase-synchronously with the */ +/* previous window, as close to the present voicing window if possible. +*/ +/* If onsets bound the voicing window, then preference is given to */ +/* a phase-synchronous placement which does not overlap these onsets. */ + +/* Case 2: Voiced Transition */ +/* If at least one voicing decision in AF is voicied, and there are no +*/ +/* onsets, then the window is placed as in case 1. */ + +/* Case 3: Unvoiced Speech or Onsets */ +/* If both voicing decisions in AF are unvoiced, or there are onsets, */ +/* then the window is placed coincident with the voicing window. */ + +/* Note: During phase-synchronous placement of windows, the length */ +/* is not altered from MAXWIN, since this would defeat the purpose */ +/* of phase-synchronous placement. */ +/* Check for case 1 and case 2 */ + allv = voibuf[(*af - 2 << 1) + 2] == 1; + allv = allv && voibuf[(*af - 1 << 1) + 1] == 1; + allv = allv && voibuf[(*af - 1 << 1) + 2] == 1; + allv = allv && voibuf[(*af << 1) + 1] == 1; + allv = allv && voibuf[(*af << 1) + 2] == 1; + winv = voibuf[(*af << 1) + 1] == 1 || voibuf[(*af << 1) + 2] == 1; + if (allv || winv && *obound == 0) { +/* APHASE: Phase synchronous window placement. */ +/* Get minimum lower index of the window. */ + i__ = (lrange + *ipitch - 1 - awin[(*af - 1 << 1) + 1]) / *ipitch; + i__ *= *ipitch; + i__ += awin[(*af - 1 << 1) + 1]; +/* L = the actual length of this frame's analysis window. */ + l = *maxwin; +/* Calculate the location where a perfectly centered window would star +t. */ + k = (vwin[(*af << 1) + 1] + vwin[(*af << 1) + 2] + 1 - l) / 2; +/* Choose the actual location to be the pitch multiple closest to this +. */ + r__1 = (real) (k - i__) / *ipitch; + awin[(*af << 1) + 1] = i__ + i_nint(&r__1) * *ipitch; + awin[(*af << 1) + 2] = awin[(*af << 1) + 1] + l - 1; +/* If there is an onset bounding the right of the voicing window and t +he */ +/* analysis window overlaps that, then move the analysis window backwa +rd */ +/* to avoid this onset. */ + if (*obound >= 2 && awin[(*af << 1) + 2] > vwin[(*af << 1) + 2]) { + awin[(*af << 1) + 1] -= *ipitch; + awin[(*af << 1) + 2] -= *ipitch; + } +/* Similarly for the left of the voicing window. */ + if ((*obound == 1 || *obound == 3) && awin[(*af << 1) + 1] < vwin[(* + af << 1) + 1]) { + awin[(*af << 1) + 1] += *ipitch; + awin[(*af << 1) + 2] += *ipitch; + } +/* If this placement puts the analysis window above HRANGE, then */ +/* move it backward an integer number of pitch periods. */ + while(awin[(*af << 1) + 2] > hrange) { + awin[(*af << 1) + 1] -= *ipitch; + awin[(*af << 1) + 2] -= *ipitch; + } +/* Similarly if the placement puts the analysis window below LRANGE. +*/ + while(awin[(*af << 1) + 1] < lrange) { + awin[(*af << 1) + 1] += *ipitch; + awin[(*af << 1) + 2] += *ipitch; + } +/* Make Energy window be phase-synchronous. */ + ephase = TRUE_; +/* Case 3 */ + } else { + awin[(*af << 1) + 1] = vwin[(*af << 1) + 1]; + awin[(*af << 1) + 2] = vwin[(*af << 1) + 2]; + ephase = FALSE_; + } +/* RMS is computed over an integer number of pitch periods in the analysis + */ +/*window. When it is not placed phase-synchronously, it is placed as clos +e*/ +/* as possible to onsets. */ + j = (awin[(*af << 1) + 2] - awin[(*af << 1) + 1] + 1) / *ipitch * *ipitch; + if (j == 0 || ! winv) { + ewin[(*af << 1) + 1] = vwin[(*af << 1) + 1]; + ewin[(*af << 1) + 2] = vwin[(*af << 1) + 2]; + } else if (! ephase && *obound == 2) { + ewin[(*af << 1) + 1] = awin[(*af << 1) + 2] - j + 1; + ewin[(*af << 1) + 2] = awin[(*af << 1) + 2]; + } else { + ewin[(*af << 1) + 1] = awin[(*af << 1) + 1]; + ewin[(*af << 1) + 2] = awin[(*af << 1) + 1] + j - 1; + } + return 0; +} /* placea_ */ + diff --git a/linphone/lpc10-1.5/placev.c b/linphone/lpc10-1.5/placev.c new file mode 100644 index 000000000..a385a75fa --- /dev/null +++ b/linphone/lpc10-1.5/placev.c @@ -0,0 +1,257 @@ +/* + +$Log: placev.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:31:02 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obound, integer *vwin, integer *af, integer *lframe, integer *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ****************************************************************** */ + +/* PLACEV Version 48 */ + +/* $Log: placev.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:31:02 jaf + * Initial revision + * */ +/* Revision 1.6 1996/03/19 20:42:19 jaf */ +/* Added some conditions satisfied by the output values in VWIN. */ + +/* Revision 1.5 1996/03/19 18:37:56 jaf */ +/* Strengthened the specification of which indices of VWIN are read and */ +/* written. */ + +/* Revision 1.4 1996/03/15 16:38:33 jaf */ +/* One tiny comment added. */ + +/* Revision 1.3 1996/03/15 16:36:13 jaf */ +/* Added comments giving In/Out status of arguments. */ + +/* Revision 1.2 1996/03/12 23:56:01 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:48:39 jaf */ +/* Initial revision */ + + +/* ****************************************************************** */ + +/* Input: */ +/* OSBUF Buffer which holds sorted indexes of onsets */ +/* I believe that only indices 1 through OSPTR-1 can be read. */ +/* OSLEN */ +/* OSPTR Free pointer into OSBUF */ +/* AF */ +/* LFRAME */ +/* MINWIN */ +/* MAXWIN */ +/* DVWINL */ +/* DVWINH (This argument is never used. Should it be?) */ +/* Input/Output: */ +/* VWIN Buffer of Voicing Window Positions (Modified) */ +/* Index (2,AF-1) is read. */ +/* Indices (1,AF) and (2,AF) are written, */ +/* and then possibly read. */ +/* All other indices are unused. */ +/* In all cases, the final values will satsify the condition:*/ +/* VWIN(2,AF)-VWIN(1,AF)+1 .LE. MAXWIN */ +/* I'm not certain yet, but they may also satisfy: */ +/* MINWIN .LE. VWIN(2,AF)-VWIN(1,AF)+1 */ +/* Output: */ +/* OBOUND This variable is set by this procedure and used */ +/* in placing analysis windows (PLACEA). Bit 1 */ +/* indicates whether an onset bounds the left side */ +/* of the voicing window, and bit 2 indicates whether */ +/* an onset bounds the right side of the voicing window. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int placev_(integer *osbuf, integer *osptr, integer *oslen, + integer *obound, integer *vwin, integer *af, integer *lframe, integer + *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh) +{ + /* System generated locals */ + integer i__1, i__2; + + /* Local variables */ + logical crit; + integer i__, q, osptr1, hrange, lrange; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Variables */ +/* LRANGE, HRANGE Range in which window is placed */ +/* OSPTR1 OSPTR excluding samples in 3F */ +/* Local state */ +/* None */ +/* Voicing Window Placement */ + +/* __________________ __________________ ______________ */ +/* | | | */ +/* | 1F | 2F | 3F ... */ +/* |__________________|__________________|______________ */ + +/* Previous | */ +/* Window | */ +/* ...________| */ + +/* | | */ +/* ------>| This window's placement range |<------ */ +/* | | */ + +/* There are three cases. Note that these are different from those */ +/* given in the LPC-10e phase 1 report. */ + +/* 1. If there are no onsets in this range, then the voicing window */ +/* is centered in the pitch window. If such a placement is not within +*/ +/* the window's placement range, then the window is placed in the left- +*/ +/* most portion of the placement range. Its length is always MAXWIN. */ + +/* 2. If the first onset is in 2F and there is sufficient room to place + */ +/* the window immediately before this onset, then the window is placed +*/ +/* there, and its length is set to the maximum possible under these */ +/* constraints. */ + +/* "Critical Region Exception": If there is another onset in 2F */ +/* such that a window can be placed between the two onsets, the */ +/* window is placed there (ie, as in case 3). */ + +/* 3. Otherwise, the window is placed immediately after the onset. The + */ +/* window's length */ +/* is the longest length that can fit in the range under these constraint +s,*/ +/* except that the window may be shortened even further to avoid overlapp +ing*/ +/* other onsets in the placement range. In any case, the window's length +*/ +/* is at least MINWIN. */ + +/* Note that the values of MINWIN and LFRAME must be chosen such */ +/* that case 2 = false implies case 3 = true. This means that */ +/* MINWIN <= LFRAME/2. If this were not the case, then a fourth case */ +/* would have to be added for when the window cannot fit either before +*/ +/* or after the onset. */ + +/* Note also that onsets which weren't in 2F last time may be in 1F this + */ +/* time, due to the filter delays in computing onsets. The result is tha +t*/ +/* occasionally a voicing window will overlap that onset. The only way +*/ +/* to circumvent this problem is to add more delay in processing input +*/ +/* speech. In the trade-off between delay and window-placement, window +*/ +/* placement lost. */ +/* Compute the placement range */ + /* Parameter adjustments */ + --osbuf; + vwin -= 3; + + /* Function Body */ +/* Computing MAX */ + i__1 = vwin[(*af - 1 << 1) + 2] + 1, i__2 = (*af - 2) * *lframe + 1; + lrange = max(i__1,i__2); + hrange = *af * *lframe; +/* Compute OSPTR1, so the following code only looks at relevant onsets. */ + for (osptr1 = *osptr - 1; osptr1 >= 1; --osptr1) { + if (osbuf[osptr1] <= hrange) { + goto L90; + } + } +L90: + ++osptr1; +/* Check for case 1 first (fast case): */ + if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) { +/* Computing MAX */ + i__1 = vwin[(*af - 1 << 1) + 2] + 1; + vwin[(*af << 1) + 1] = max(i__1,*dvwinl); + vwin[(*af << 1) + 2] = vwin[(*af << 1) + 1] + *maxwin - 1; + *obound = 0; + } else { +/* Search backward in OSBUF for first onset in range. */ +/* This code relies on the above check being performed first. */ + for (q = osptr1 - 1; q >= 1; --q) { + if (osbuf[q] < lrange) { + goto L100; + } + } +L100: + ++q; +/* Check for case 2 (placement before onset): */ +/* Check for critical region exception: */ + i__1 = osptr1 - 1; + for (i__ = q + 1; i__ <= i__1; ++i__) { + if (osbuf[i__] - osbuf[q] >= *minwin) { + crit = TRUE_; + goto L105; + } + } + crit = FALSE_; +L105: +/* Computing MAX */ + i__1 = (*af - 1) * *lframe, i__2 = lrange + *minwin - 1; + if (! crit && osbuf[q] > max(i__1,i__2)) { + vwin[(*af << 1) + 2] = osbuf[q] - 1; +/* Computing MAX */ + i__1 = lrange, i__2 = vwin[(*af << 1) + 2] - *maxwin + 1; + vwin[(*af << 1) + 1] = max(i__1,i__2); + *obound = 2; +/* Case 3 (placement after onset) */ + } else { + vwin[(*af << 1) + 1] = osbuf[q]; +L110: + ++q; + if (q >= osptr1) { + goto L120; + } + if (osbuf[q] > vwin[(*af << 1) + 1] + *maxwin) { + goto L120; + } + if (osbuf[q] < vwin[(*af << 1) + 1] + *minwin) { + goto L110; + } + vwin[(*af << 1) + 2] = osbuf[q] - 1; + *obound = 3; + return 0; +L120: +/* Computing MIN */ + i__1 = vwin[(*af << 1) + 1] + *maxwin - 1; + vwin[(*af << 1) + 2] = min(i__1,hrange); + *obound = 1; + } + } + return 0; +} /* placev_ */ + diff --git a/linphone/lpc10-1.5/preemp.c b/linphone/lpc10-1.5/preemp.c new file mode 100644 index 000000000..49bdab705 --- /dev/null +++ b/linphone/lpc10-1.5/preemp.c @@ -0,0 +1,132 @@ +/* + +$Log: preemp.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:30:58 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int preemp_(real *inbuf, real *pebuf, integer *nsamp, real *coef, real *z__); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ******************************************************************* */ + +/* PREEMP Version 55 */ + +/* $Log: preemp.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:30:58 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/14 23:16:29 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/11 23:23:34 jaf */ +/* Added a bunch of comments to an otherwise simple subroutine. */ + +/* Revision 1.1 1996/02/07 14:48:48 jaf */ +/* Initial revision */ + + +/* ******************************************************************* */ + +/* Preemphasize speech with a single-zero filter. */ +/* (When coef = .9375, preemphasis is as in LPC43.) */ + +/* Inputs: */ +/* NSAMP - Number of samples to filter */ +/* INBUF - Input speech buffer */ +/* Indices 1 through NSAMP are read. */ +/* COEF - Preemphasis coefficient */ +/* Input/Output: */ +/* Z - Filter state */ +/* Output: */ +/* PEBUF - Preemphasized speech buffer (can be equal to INBUF) */ +/* Indices 1 through NSAMP are modified. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int preemp_(real *inbuf, real *pebuf, integer *nsamp, real * + coef, real *z__) +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + real temp; + integer i__; + +/* Arguments */ +/* Local variables */ + +/* None of these need to have their values saved from one */ +/* invocation to the next. */ + +/* Logically, this subroutine computes the output sequence */ +/* pebuf(1:nsamp) defined by: */ + +/* pebuf(i) = inbuf(i) - coef * inbuf(i-1) */ + +/* where inbuf(0) is defined by the value of z given as input to */ +/* this subroutine. */ + +/* What is this filter's frequency response and phase response? */ + +/* Why is this filter applied to the speech? */ + +/* Could it be more efficient to apply multiple filters */ +/* simultaneously, by combining them into one equivalent filter? */ + +/* Are there ever cases when "factoring" one high-order filter into +*/ +/* multiple smaller-order filter actually reduces the number of */ +/* arithmetic operations needed to perform them? */ +/* When I first read this subroutine, I didn't understand why the */ +/* variable temp was used. It seemed that the statements in the do +*/ +/* loop could be replaced with the following: */ + +/* pebuf(i) = inbuf(i) - coef * z */ +/* z = inbuf(i) */ + +/* The reason for temp is so that even if pebuf and inbuf are the */ +/* same arrays in memory (i.e., they are aliased), then this */ +/* subroutine will still work correctly. I didn't realize this */ +/* until seeing the comment after PEBUF above that says "(can be */ +/* equal to INBUF)". */ + /* Parameter adjustments */ + --pebuf; + --inbuf; + + /* Function Body */ + i__1 = *nsamp; + for (i__ = 1; i__ <= i__1; ++i__) { + temp = inbuf[i__] - *coef * *z__; + *z__ = inbuf[i__]; + pebuf[i__] = temp; +/* L10: */ + } + return 0; +} /* preemp_ */ + diff --git a/linphone/lpc10-1.5/prepro.c b/linphone/lpc10-1.5/prepro.c new file mode 100644 index 000000000..403dd8379 --- /dev/null +++ b/linphone/lpc10-1.5/prepro.c @@ -0,0 +1,105 @@ +/* + +$Log: prepro.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:40:51 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:30:54 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int prepro_(real *speech, integer *length, + struct lpc10_encoder_state *st) +/*:ref: hp100_ 14 3 6 4 4 */ +/*:ref: inithp100_ 14 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; + +/* ********************************************************************* */ + +/* PREPRO Version 48 */ + +/* $Log: prepro.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:40:51 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:30:54 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/14 23:22:56 jaf */ +/* Added comments about when INITPREPRO should be used. */ + +/* Revision 1.2 1996/03/14 23:09:27 jaf */ +/* Added an entry named INITPREPRO that initializes the local state of */ +/* this subroutine, and those it calls (if any). */ + +/* Revision 1.1 1996/02/07 14:48:54 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Pre-process input speech: */ + +/* Inputs: */ +/* LENGTH - Number of SPEECH samples */ +/* Input/Output: */ +/* SPEECH(LENGTH) - Speech data. */ +/* Indices 1 through LENGTH are read and modified. */ + +/* This subroutine has no local state maintained from one call to the */ +/* next, but HP100 does. If you want to switch to using a new audio */ +/* stream for this filter, or reinitialize its state for any other */ +/* reason, call the ENTRY INITPREPRO. */ + +/* Subroutine */ int prepro_(real *speech, integer *length, + struct lpc10_encoder_state *st) +{ + extern /* Subroutine */ int hp100_(real *, integer *, integer *, struct lpc10_encoder_state *); + +/* Arguments */ +/* High Pass Filter at 100 Hz */ + /* Parameter adjustments */ + if (speech) { + --speech; + } + + /* Function Body */ + hp100_(&speech[1], &c__1, length, st); + return 0; +} /* prepro_ */ diff --git a/linphone/lpc10-1.5/random.c b/linphone/lpc10-1.5/random.c new file mode 100644 index 000000000..e83fff3eb --- /dev/null +++ b/linphone/lpc10-1.5/random.c @@ -0,0 +1,113 @@ +/* + +$Log: random.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:41:32 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:49 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern integer random_(struct lpc10_decoder_state *st); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************** */ + +/* RANDOM Version 49 */ + +/* $Log: random.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:41:32 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:49 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/20 16:13:54 jaf */ +/* Rearranged comments a little bit, and added comments explaining that */ +/* even though there is local state here, there is no need to create an */ +/* ENTRY for reinitializing it. */ + +/* Revision 1.2 1996/03/14 22:25:29 jaf */ +/* Just rearranged the comments and local variable declarations a bit. */ + +/* Revision 1.1 1996/02/07 14:49:01 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Pseudo random number generator based on Knuth, Vol 2, p. 27. */ + +/* Function Return: */ +/* RANDOM - Integer variable, uniformly distributed over -32768 to 32767 */ + +/* This subroutine maintains local state from one call to the next. */ +/* In the context of the LPC10 coder, there is no reason to reinitialize */ +/* this local state when switching between audio streams, because its */ +/* results are only used to generate noise for unvoiced frames. */ + +integer random_(struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + integer *j; + integer *k; + shortint *y; + + /* System generated locals */ + integer ret_val; + +/* Parameters/constants */ +/* Local state */ +/* The following is a 16 bit 2's complement addition, */ +/* with overflow checking disabled */ + + j = &(st->j); + k = &(st->k); + y = &(st->y[0]); + + y[*k - 1] += y[*j - 1]; + ret_val = y[*k - 1]; + --(*k); + if (*k <= 0) { + *k = 5; + } + --(*j); + if (*j <= 0) { + *j = 5; + } + return ret_val; +} /* random_ */ + diff --git a/linphone/lpc10-1.5/rcchk.c b/linphone/lpc10-1.5/rcchk.c new file mode 100644 index 000000000..008babb26 --- /dev/null +++ b/linphone/lpc10-1.5/rcchk.c @@ -0,0 +1,107 @@ +/* + +$Log: rcchk.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:30:41 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int rcchk_(integer *order, real *rc1f, real *rc2f); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************* */ + +/* RCCHK Version 45G */ + +/* $Log: rcchk.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:30:41 jaf + * Initial revision + * */ +/* Revision 1.4 1996/03/27 18:13:47 jaf */ +/* Commented out a call to subroutine ERROR. */ + +/* Revision 1.3 1996/03/18 15:48:53 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 16:55:22 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:49:08 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Check RC's, repeat previous frame's RC's if unstable */ + +/* Input: */ +/* ORDER - Number of RC's */ +/* RC1F - Previous frame's RC's */ +/* Indices 1 through ORDER may be read. */ +/* Input/Output: */ +/* RC2F - Present frame's RC's */ +/* Indices 1 through ORDER may be read, and written. */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int rcchk_(integer *order, real *rc1f, real *rc2f) +{ + /* System generated locals */ + integer i__1; + real r__1; + + /* Local variables */ + integer i__; + +/* Arguments */ +/* Local variables that need not be saved */ + /* Parameter adjustments */ + --rc2f; + --rc1f; + + /* Function Body */ + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + if ((r__1 = rc2f[i__], abs(r__1)) > .99f) { + goto L10; + } + } + return 0; +/* Note: In version embedded in other software, all calls to ERROR +*/ +/* should probably be removed. */ +L10: + +/* This call to ERROR is only needed for debugging purposes. */ + +/* CALL ERROR('RCCHK',2,I) */ + i__1 = *order; + for (i__ = 1; i__ <= i__1; ++i__) { + rc2f[i__] = rc1f[i__]; + } + return 0; +} /* rcchk_ */ + diff --git a/linphone/lpc10-1.5/synths.c b/linphone/lpc10-1.5/synths.c new file mode 100644 index 000000000..b126b8154 --- /dev/null +++ b/linphone/lpc10-1.5/synths.c @@ -0,0 +1,392 @@ +/* + +$Log: synths.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:42:59 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:33 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int synths_(integer *voice, integer *pitch, real *rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st); +/* comlen contrl_ 12 */ +/*:ref: pitsyn_ 14 12 4 4 4 6 6 4 4 4 6 6 4 6 */ +/*:ref: irc2pc_ 14 5 6 6 4 6 6 */ +/*:ref: bsynz_ 14 7 6 4 4 6 6 6 6 */ +/*:ref: deemp_ 14 2 6 4 */ +/*:ref: initpitsyn_ 14 0 */ +/*:ref: initbsynz_ 14 0 */ +/*:ref: initdeemp_ 14 0 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/* Table of constant values */ + +static real c_b2 = .7f; + +/* ***************************************************************** */ + +/* SYNTHS Version 54 */ + +/* $Log: synths.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:42:59 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:33 jaf + * Initial revision + * */ +/* Revision 1.5 1996/03/26 19:31:58 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.4 1996/03/25 19:41:01 jaf */ +/* Changed so that MAXFRM samples are always returned in the output array */ +/* SPEECH. */ + +/* This required delaying the returned samples by MAXFRM sample times, */ +/* and remembering any "left over" samples returned by PITSYN from one */ +/* call of SYNTHS to the next. */ + +/* Changed size of SPEECH from 2*MAXFRM to MAXFRM. Removed local */ +/* variable SOUT. Added local state variables BUF and BUFLEN. */ + +/* Revision 1.3 1996/03/25 19:20:10 jaf */ +/* Added comments about the range of possible return values for argument */ +/* K, and increased the size of the arrays filled in by PITSYN from 11 to */ +/* 16, as has been already done inside of PITSYN. */ + +/* Revision 1.2 1996/03/22 00:18:18 jaf */ +/* Added comments explaining meanings of input and output parameters, and */ +/* indicating which array indices can be read or written. */ + +/* Added entry INITSYNTHS, which does nothing except call the */ +/* corresponding initialization entries for subroutines PITSYN, BSYNZ, */ +/* and DEEMP. */ + +/* Revision 1.1 1996/02/07 14:49:44 jaf */ +/* Initial revision */ + + +/* ***************************************************************** */ + +/* The note below is from the distributed version of the LPC10 coder. */ +/* The version of the code below has been modified so that SYNTHS always */ +/* has a constant frame length output of MAXFRM. */ + +/* Also, BSYNZ and DEEMP need not be modified to work on variable */ +/* positions within an array. It is only necessary to pass the first */ +/* index desired as the array argument. What actually gets passed is the */ +/* address of that array position, which the subroutine treats as the */ +/* first index of the array. */ + +/* This technique is used in subroutine ANALYS when calling PREEMP, so it */ +/* appears that multiple people wrote different parts of this LPC10 code, */ +/* and that they didn't necessarily have equivalent knowledge of Fortran */ +/* (not surprising). */ + +/* NOTE: There is excessive buffering here, BSYNZ and DEEMP should be */ +/* changed to operate on variable positions within SOUT. Also, */ +/* the output length parameter is bogus, and PITSYN should be */ +/* rewritten to allow a constant frame length output. */ + +/* Input: */ +/* VOICE - Half frame voicing decisions */ +/* Indices 1 through 2 read. */ +/* Input/Output: */ +/* PITCH - Pitch */ +/* PITCH is restricted to range 20 to 156, inclusive, */ +/* before calling subroutine PITSYN, and then PITSYN */ +/* can modify it further under some conditions. */ +/* RMS - Energy */ +/* Only use is for debugging, and passed to PITSYN. */ +/* See comments there for how it can be modified. */ +/* RC - Reflection coefficients */ +/* Indices 1 through ORDER restricted to range -.99 to .99, */ +/* before calling subroutine PITSYN, and then PITSYN */ +/* can modify it further under some conditions. */ +/* Output: */ +/* SPEECH - Synthesized speech samples. */ +/* Indices 1 through the final value of K are written. */ +/* K - Number of samples placed into array SPEECH. */ +/* This is always MAXFRM. */ + +/* Subroutine */ int synths_(integer *voice, integer *pitch, real * + rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st) +{ + /* Initialized data */ + + real *buf; + integer *buflen; + + /* System generated locals */ + integer i__1; + real r__1, r__2; + + /* Local variables */ + real rmsi[16]; + integer nout, ivuv[16], i__, j; + extern /* Subroutine */ int deemp_(real *, integer *, struct lpc10_decoder_state *); + real ratio; + integer ipiti[16]; + extern /* Subroutine */ bsynz_(real *, integer *, + integer *, real *, real *, real *, real *, struct lpc10_decoder_state *), irc2pc_(real *, real * + , integer *, real *, real *); + real g2pass; + real pc[10]; + extern /* Subroutine */ int pitsyn_(integer *, integer *, integer *, real + *, real *, integer *, integer *, integer *, real *, real *, + integer *, real *, struct lpc10_decoder_state *); + real rci[160] /* was [10][16] */; + +/* $Log: synths.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:42:59 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:33 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:03:47 jaf */ +/* Removed definitions for any constants that were no longer used. */ + +/* Revision 1.2 1996/03/26 19:34:33 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:43:51 jaf */ +/* Initial revision */ + +/* LPC Configuration parameters: */ +/* Frame size, Prediction order, Pitch period */ +/* Arguments */ +/* $Log: synths.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:42:59 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_decoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_decoder_state(). + * + * Revision 1.1 1996/08/19 22:30:33 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Parameters/constants */ +/* Local variables that need not be saved */ +/* Local state */ +/* BUF is a buffer of speech samples that would have been returned +*/ +/* by the older version of SYNTHS, but the newer version doesn't, */ +/* so that the newer version can always return MAXFRM samples on */ +/* every call. This has the effect of delaying the return of */ +/* samples for one additional frame time. */ + +/* Indices 1 through BUFLEN contain samples that are left over from +*/ +/* the last call to SYNTHS. Given the way that PITSYN works, */ +/* BUFLEN should always be in the range MAXFRM-MAXPIT+1 through */ +/* MAXFRM, inclusive, after a call to SYNTHS is complete. */ + +/* On the first call to SYNTHS (or the first call after */ +/* reinitializing with the entry INITSYNTHS), BUFLEN is MAXFRM, and +*/ +/* a frame of silence is always returned. */ + /* Parameter adjustments */ + if (voice) { + --voice; + } + if (rc) { + --rc; + } + if (speech) { + --speech; + } + + /* Function Body */ + buf = &(st->buf[0]); + buflen = &(st->buflen); + +/* Computing MAX */ + i__1 = min(*pitch,156); + *pitch = max(i__1,20); + i__1 = contrl_1.order; + for (i__ = 1; i__ <= i__1; ++i__) { +/* Computing MAX */ +/* Computing MIN */ + r__2 = rc[i__]; + r__1 = min(r__2,.99f); + rc[i__] = max(r__1,-.99f); + } + pitsyn_(&contrl_1.order, &voice[1], pitch, rms, &rc[1], &contrl_1.lframe, + ivuv, ipiti, rmsi, rci, &nout, &ratio, st); + if (nout > 0) { + i__1 = nout; + for (j = 1; j <= i__1; ++j) { + +/* Add synthesized speech for pitch period J to the en +d of */ +/* BUF. */ + + irc2pc_(&rci[j * 10 - 10], pc, &contrl_1.order, &c_b2, &g2pass); + bsynz_(pc, &ipiti[j - 1], &ivuv[j - 1], &buf[*buflen], &rmsi[j - 1] + , &ratio, &g2pass, st); + deemp_(&buf[*buflen], &ipiti[j - 1], st); + *buflen += ipiti[j - 1]; + } + +/* Copy first MAXFRM samples from BUF to output array SPEECH +*/ +/* (scaling them), and then remove them from the beginning of + */ +/* BUF. */ + + for (i__ = 1; i__ <= 180; ++i__) { + speech[i__] = buf[i__ - 1] / 4096.f; + } + *k = 180; + *buflen += -180; + i__1 = *buflen; + for (i__ = 1; i__ <= i__1; ++i__) { + buf[i__ - 1] = buf[i__ + 179]; + } + } + return 0; +} /* synths_ */ diff --git a/linphone/lpc10-1.5/tbdm.c b/linphone/lpc10-1.5/tbdm.c new file mode 100644 index 000000000..845642845 --- /dev/null +++ b/linphone/lpc10-1.5/tbdm.c @@ -0,0 +1,176 @@ +/* + +$Log: tbdm.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:30:26 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int tbdm_(real *speech, integer *lpita, integer *tau, integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *mintau); +/*:ref: difmag_ 14 8 6 4 4 4 4 6 4 4 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* ********************************************************************** */ + +/* TBDM Version 49 */ + +/* $Log: tbdm.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:16 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:30:26 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/18 22:14:00 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 14:48:37 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:49:54 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/*TURBO DIFMAG: Compute High Resolution Average Magnitude Difference Function +*/ + +/* Note: There are several constants in here that appear to depend on a */ +/* particular TAU table. That's not a problem for the LPC10 coder, but */ +/* watch out if you change the contents of TAU in the subroutine ANALYS. */ + +/* Input: */ +/* SPEECH - Low pass filtered speech */ +/* Indices 1 through MAX+LPITA-1 are read, where: */ +/* MAX = (TAU(LTAU)-TAU(1))/2+1 */ +/* (If TAU(1) .LT. 39, then larger indices could be read */ +/* by the last call to DIFMAG below.) */ +/* LPITA - Length of speech buffer */ +/* TAU - Table of lags, sorted in increasing order. */ +/* Indices 1 through LTAU read. */ +/* LTAU - Number of lag values to compute */ +/* Output: */ +/* AMDF - Average Magnitude Difference for each lag in TAU */ +/* Indices 1 through LTAU written, and several might then be read.*/ +/* MINPTR - Index of minimum AMDF value */ +/* MAXPTR - Index of maximum AMDF value within +/- 1/2 octave of min */ +/* MINTAU - Lag corresponding to minimum AMDF value */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int tbdm_(real *speech, integer *lpita, integer *tau, + integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer * + mintau) +{ + /* System generated locals */ + integer i__1, i__2, i__3, i__4; + + /* Local variables */ + real amdf2[6]; + integer minp2, ltau2, maxp2, i__; + extern /* Subroutine */ int difmag_(real *, integer *, integer *, integer + *, integer *, real *, integer *, integer *); + integer minamd, ptr, tau2[6]; + +/* Arguments */ +/* REAL SPEECH(LPITA+TAU(LTAU)), AMDF(LTAU) */ +/* Stupid TOAST doesn't understand expressions */ +/* Local variables that need not be saved */ +/* Local state */ +/* None */ +/* Compute full AMDF using log spaced lags, find coarse minimum */ + /* Parameter adjustments */ + --speech; + --amdf; + --tau; + + /* Function Body */ + difmag_(&speech[1], lpita, &tau[1], ltau, &tau[*ltau], &amdf[1], minptr, + maxptr); + *mintau = tau[*minptr]; + minamd = amdf[*minptr]; +/* Build table containing all lags within +/- 3 of the AMDF minimum */ +/* excluding all that have already been computed */ + ltau2 = 0; + ptr = *minptr - 2; +/* Computing MAX */ + i__1 = *mintau - 3; +/* Computing MIN */ + i__3 = *mintau + 3, i__4 = tau[*ltau] - 1; + i__2 = min(i__3,i__4); + for (i__ = max(i__1,41); i__ <= i__2; ++i__) { + while(tau[ptr] < i__) { + ++ptr; + } + if (tau[ptr] != i__) { + ++ltau2; + tau2[ltau2 - 1] = i__; + } + } +/* Compute AMDF of the new lags, if there are any, and choose one */ +/* if it is better than the coarse minimum */ + if (ltau2 > 0) { + difmag_(&speech[1], lpita, tau2, <au2, &tau[*ltau], amdf2, &minp2, & + maxp2); + if (amdf2[minp2 - 1] < (real) minamd) { + *mintau = tau2[minp2 - 1]; + minamd = amdf2[minp2 - 1]; + } + } +/* Check one octave up, if there are any lags not yet computed */ + if (*mintau >= 80) { + i__ = *mintau / 2; + if ((i__ & 1) == 0) { + ltau2 = 2; + tau2[0] = i__ - 1; + tau2[1] = i__ + 1; + } else { + ltau2 = 1; + tau2[0] = i__; + } + difmag_(&speech[1], lpita, tau2, <au2, &tau[*ltau], amdf2, &minp2, & + maxp2); + if (amdf2[minp2 - 1] < (real) minamd) { + *mintau = tau2[minp2 - 1]; + minamd = amdf2[minp2 - 1]; + *minptr += -20; + } + } +/* Force minimum of the AMDF array to the high resolution minimum */ + amdf[*minptr] = (real) minamd; +/* Find maximum of AMDF within 1/2 octave of minimum */ +/* Computing MAX */ + i__2 = *minptr - 5; + *maxptr = max(i__2,1); +/* Computing MIN */ + i__1 = *minptr + 5; + i__2 = min(i__1,*ltau); + for (i__ = *maxptr + 1; i__ <= i__2; ++i__) { + if (amdf[i__] > amdf[*maxptr]) { + *maxptr = i__; + } + } + return 0; +} /* tbdm_ */ + diff --git a/linphone/lpc10-1.5/voicin.c b/linphone/lpc10-1.5/voicin.c new file mode 100644 index 000000000..0782404e7 --- /dev/null +++ b/linphone/lpc10-1.5/voicin.c @@ -0,0 +1,759 @@ +/* + +$Log: voicin.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:17 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.2 1996/08/20 20:45:00 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:30:14 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af, struct lpc10_encoder_state *st); +/* comlen contrl_ 12 */ +/*:ref: vparms_ 14 14 4 6 6 4 4 6 4 4 4 4 6 6 6 6 */ +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Common Block Declarations */ + +extern struct { + integer order, lframe; + logical corrp; +} contrl_; + +#define contrl_1 contrl_ + +/****************************************************************************/ + +/* VOICIN Version 52 */ + +/* $Log: voicin.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:17 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:45:00 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:30:14 jaf + * Initial revision + * */ +/* Revision 1.10 1996/03/29 17:59:14 jaf */ +/* Avoided using VALUE(9), although it shouldn't affect the function of */ +/* the code at all, because it was always multiplied by VDC(9,SNRL), */ +/* which is 0 for all values of SNRL. Still, if VALUE(9) had an initial */ +/* value of IEEE NaN, it might cause trouble (I don't know how IEEE */ +/* defines Nan * 0. It should either be NaN or 0.) */ + +/* Revision 1.9 1996/03/29 17:54:46 jaf */ +/* Added a few comments about the accesses made to argument array VOIBUF */ +/* and the local saved array VOICE. */ + +/* Revision 1.8 1996/03/27 18:19:54 jaf */ +/* Added an assignment to VSTATE that does not affect the function of the */ +/* program at all. The only reason I put it in was so that the tracing */ +/* statements at the end, when enabled, will print a consistent value for */ +/* VSTATE when HALF .EQ. 1, rather than a garbage value that could change */ +/* from one call to the next. */ + +/* Revision 1.7 1996/03/26 20:00:06 jaf */ +/* Removed the inclusion of the file "vcomm.fh", and put its contents */ +/* into this file. It was included nowhere else but here. */ + +/* Revision 1.6 1996/03/26 19:38:09 jaf */ +/* Commented out trace statements. */ + +/* Revision 1.5 1996/03/19 20:43:45 jaf */ +/* Added comments about which indices of OBOUND and VOIBUF can be */ +/* accessed, and whether they are read or written. VOIBUF is fairly */ +/* messy. */ + +/* Revision 1.4 1996/03/19 15:00:58 jaf */ +/* Moved the DATA statements for the *VDC* variables later, as it is */ +/* apparently illegal to have DATA statements before local variable */ +/* declarations. */ + +/* Revision 1.3 1996/03/19 00:10:49 jaf */ +/* Heavily commented the local variables that are saved from one */ +/* invocation to the next, and how the local variable FIRST is used to */ +/* avoid the need to assign most of them initial values with DATA */ +/* statements. */ + +/* A few should be initialized, but aren't. I've guessed initial values */ +/* for two of these, SFBUE and SLBUE, and I've convinced myself that for */ +/* VOICE, the effects of uninitialized values will die out after 2 or 3 */ +/* frame times. It would still be good to choose initial values for */ +/* these, but I don't know what reasonable values would be (0 comes to */ +/* mind). */ + +/* Revision 1.2 1996/03/13 16:09:28 jaf */ +/* Comments added explaining which of the local variables of this */ +/* subroutine need to be saved from one invocation to the next, and which */ +/* do not. */ + +/* WARNING! Some of them that should are never given initial values in */ +/* this code. Hopefully, Fortran 77 defines initial values for them, but */ +/* even so, giving them explicit initial values is preferable. */ + +/* WARNING! VALUE(9) is used, but never assigned a value. It should */ +/* probably be eliminated from the code. */ + +/* Revision 1.1 1996/02/07 14:50:28 jaf */ +/* Initial revision */ + + +/****************************************************************************/ + +/* Voicing Detection (VOICIN) makes voicing decisions for each half */ +/* frame of input speech. Tentative voicing decisions are made two frames*/ +/* in the future (2F) for each half frame. These decisions are carried */ +/* through one frame in the future (1F) to the present (P) frame where */ +/* they are examined and smoothed, resulting in the final voicing */ +/* decisions for each half frame. */ +/* The voicing parameter (signal measurement) column vector (VALUE) */ +/* is based on a rectangular window of speech samples determined by the */ +/* window placement algorithm. The voicing parameter vector contains the*/ +/* AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*/ +/* measures, reflection coefficients, and prediction gains. The voicing */ +/* window is placed to avoid contamination of the voicing parameter vector*/ +/* with speech onsets. */ +/* The input signal is then classified as unvoiced (including */ +/* silence) or voiced. This decision is made by a linear discriminant */ +/* function consisting of a dot product of the voicing decision */ +/* coefficient (VDC) row vector with the measurement column vector */ +/* (VALUE). The VDC vector is 2-dimensional, each row vector is optimized*/ +/* for a particular signal-to-noise ratio (SNR). So, before the dot */ +/* product is performed, the SNR is estimated to select the appropriate */ +/* VDC vector. */ +/* The smoothing algorithm is a modified median smoother. The */ +/* voicing discriminant function is used by the smoother to determine how*/ +/* strongly voiced or unvoiced a signal is. The smoothing is further */ +/* modified if a speech onset and a voicing decision transition occur */ +/* within one half frame. In this case, the voicing decision transition */ +/* is extended to the speech onset. For transmission purposes, there are*/ +/* constraints on the duration and transition of voicing decisions. The */ +/* smoother takes these constraints into account. */ +/* Finally, the energy estimates are updated along with the dither */ +/* threshold used to calculate the zero crossing rate (ZC). */ + +/* Inputs: */ +/* VWIN - Voicing window limits */ +/* The indices read of arrays VWIN, INBUF, LPBUF, and BUFLIM */ +/* are the same as those read by subroutine VPARMS. */ +/* INBUF - Input speech buffer */ +/* LPBUF - Low-pass filtered speech buffer */ +/* BUFLIM - INBUF and LPBUF limits */ +/* HALF - Present analysis half frame number */ +/* MINAMD - Minimum value of the AMDF */ +/* MAXAMD - Maximum value of the AMDF */ +/* MINTAU - Pointer to the lag of the minimum AMDF value */ +/* IVRC(2) - Inverse filter's RC's */ +/* Only index 2 of array IVRC read under normal operation. */ +/* (Index 1 is also read when debugging is turned on.) */ +/* OBOUND - Onset boundary descriptions */ +/* Indices 1 through 3 read if (HALF .NE. 1), otherwise untouched. +*/ +/* AF - The analysis frame number */ +/* Output: */ +/* VOIBUF(2,0:AF) - Buffer of voicing decisions */ +/* Index (HALF,3) written. */ +/* If (HALF .EQ. 1), skip down to "Read (HALF,3)" below. */ +/* Indices (1,2), (2,1), (1,2), and (2,2) read. */ +/* One of the following is then done: */ +/* read (1,3) and possibly write (1,2) */ +/* read (1,3) and write (1,2) or (2,2) */ +/* write (2,1) */ +/* write (2,1) or (1,2) */ +/* read (1,0) and (1,3) and then write (2,2) or (1,1) */ +/* no reads or writes on VOIBUF */ +/* Finally, read (HALF,3) */ +/* Internal: */ +/* QS - Ratio of preemphasized to full-band energies */ +/* RC1 - First reflection coefficient */ +/* AR_B - Product of the causal forward and reverse pitch prediction gain +s*/ +/* AR_F - Product of the noncausal forward and rev. pitch prediction gain +s*/ +/* ZC - Zero crossing rate */ +/* DITHER - Zero crossing threshold level */ +/* MAXMIN - AMDF's 1 octave windowed maximum-to-minimum ratio */ +/* MINPTR - Location of minimum AMDF value */ +/* NVDC - Number of elements in each VDC vector */ +/* NVDCL - Number of VDC vectors */ +/* VDCL - SNR values corresponding to the set of VDC's */ +/* VDC - 2-D voicing decision coefficient vector */ +/* VALUE(9) - Voicing Parameters */ +/* VOICE(2,3)- History of LDA results */ +/* On every call when (HALF .EQ. 1), VOICE(*,I+1) is */ +/* shifted back to VOICE(*,I), for I=1,2. */ +/* VOICE(HALF,3) is written on every call. */ +/* Depending on several conditions, one or more of */ +/* (1,1), (1,2), (2,1), and (2,2) might then be read. */ +/* LBE - Ratio of low-band instantaneous to average energies */ +/* FBE - Ratio of full-band instantaneous to average energies */ +/* LBVE - Low band voiced energy */ +/* LBUE - Low band unvoiced energy */ +/* FBVE - Full band voiced energy */ +/* FBUE - Full band unvoiced energy */ +/* OFBUE - Previous full-band unvoiced energy */ +/* OLBUE - Previous low-band unvoiced energy */ +/* REF - Reference energy for initialization and DITHER threshold */ +/* SNR - Estimate of signal-to-noise ratio */ +/* SNR2 - Estimate of low-band signal-to-noise ratio */ +/* SNRL - SNR level number */ +/* OT - Onset transition present */ +/* VSTATE - Decimal interpretation of binary voicing classifications */ +/* FIRST - First call flag */ + +/* This subroutine maintains local state from one call to the next. If */ +/* you want to switch to using a new audio stream for this filter, or */ +/* reinitialize its state for any other reason, call the ENTRY */ +/* INITVOICIN. */ + +/* Subroutine */ int voicin_(integer *vwin, real *inbuf, real * + lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, + integer *mintau, real *ivrc, integer *obound, integer *voibuf, + integer *af, struct lpc10_encoder_state *st) +{ + /* Initialized data */ + + real *dither; + static real vdc[100] /* was [10][10] */ = { 0.f,1714.f,-110.f, + 334.f,-4096.f,-654.f,3752.f,3769.f,0.f,1181.f,0.f,874.f,-97.f, + 300.f,-4096.f,-1021.f,2451.f,2527.f,0.f,-500.f,0.f,510.f,-70.f, + 250.f,-4096.f,-1270.f,2194.f,2491.f,0.f,-1500.f,0.f,500.f,-10.f, + 200.f,-4096.f,-1300.f,2e3f,2e3f,0.f,-2e3f,0.f,500.f,0.f,0.f, + -4096.f,-1300.f,2e3f,2e3f,0.f,-2500.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f }; + static integer nvdcl = 5; + static real vdcl[10] = { 600.f,450.f,300.f,200.f,0.f,0.f,0.f,0.f,0.f,0.f } + ; + + /* System generated locals */ + integer inbuf_offset, lpbuf_offset, i__1, i__2; + real r__1, r__2; + + /* Builtin functions */ + integer i_nint(real *); + double sqrt(doublereal); + + /* Local variables */ + real ar_b__, ar_f__; + integer *lbve, *lbue, *fbve, *fbue; + integer snrl, i__; + integer *ofbue, *sfbue; + real *voice; + integer *olbue, *slbue; + real value[9]; + integer zc; + logical ot; + real qs; + real *maxmin; + integer vstate; + real rc1; + extern /* Subroutine */ int vparms_(integer *, real *, real *, integer *, + integer *, real *, integer *, integer *, integer *, integer *, + real *, real *, real *, real *); + integer fbe, lbe; + real *snr; + real snr2; + +/* Global Variables: */ +/* Arguments */ +/* $Log: voicin.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:17 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.2 1996/08/20 20:45:00 jaf + * Removed all static local variables that were SAVE'd in the Fortran + * code, and put them in struct lpc10_encoder_state that is passed as an + * argument. + * + * Removed init function, since all initialization is now done in + * init_lpc10_encoder_state(). + * + * Revision 1.1 1996/08/19 22:30:14 jaf + * Initial revision + * */ +/* Revision 1.3 1996/03/29 22:05:55 jaf */ +/* Commented out the common block variables that are not needed by the */ +/* embedded version. */ + +/* Revision 1.2 1996/03/26 19:34:50 jaf */ +/* Added comments indicating which constants are not needed in an */ +/* application that uses the LPC-10 coder. */ + +/* Revision 1.1 1996/02/07 14:44:09 jaf */ +/* Initial revision */ + +/* LPC Processing control variables: */ + +/* *** Read-only: initialized in setup */ + +/* Files for Speech, Parameter, and Bitstream Input & Output, */ +/* and message and debug outputs. */ + +/* Here are the only files which use these variables: */ + +/* lpcsim.f setup.f trans.f error.f vqsetup.f */ + +/* Many files which use fdebug are not listed, since it is only used in */ +/* those other files conditionally, to print trace statements. */ +/* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* LPC order, Frame size, Quantization rate, Bits per frame, */ +/* Error correction */ +/* Subroutine SETUP is the only place where order is assigned a value, */ +/* and that value is 10. It could increase efficiency 1% or so to */ +/* declare order as a constant (i.e., a Fortran PARAMETER) instead of as +*/ +/* a variable in a COMMON block, since it is used in many places in the */ +/* core of the coding and decoding routines. Actually, I take that back. +*/ +/* At least when compiling with f2c, the upper bound of DO loops is */ +/* stored in a local variable before the DO loop begins, and then that is +*/ +/* compared against on each iteration. */ +/* Similarly for lframe, which is given a value of MAXFRM in SETUP. */ +/* Similarly for quant, which is given a value of 2400 in SETUP. quant */ +/* is used in only a few places, and never in the core coding and */ +/* decoding routines, so it could be eliminated entirely. */ +/* nbits is similar to quant, and is given a value of 54 in SETUP. */ +/* corrp is given a value of .TRUE. in SETUP, and is only used in the */ +/* subroutines ENCODE and DECODE. It doesn't affect the speed of the */ +/* coder significantly whether it is .TRUE. or .FALSE., or whether it is +*/ +/* a constant or a variable, since it is only examined once per frame. */ +/* Leaving it as a variable that is set to .TRUE. seems like a good */ +/* idea, since it does enable some error-correction capability for */ +/* unvoiced frames, with no change in the coding rate, and no noticeable +*/ +/* quality difference in the decoded speech. */ +/* integer quant, nbits */ +/* *** Read/write: variables for debugging, not needed for LPC algorithm +*/ + +/* Current frame, Unstable frames, Output clip count, Max onset buffer, +*/ +/* Debug listing detail level, Line count on listing page */ + +/* nframe is not needed for an embedded LPC10 at all. */ +/* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */ +/* ERROR, which is only called from RCCHK. When LPC10 is embedded into */ +/* an application, I would recommend removing the call to ERROR in RCCHK, +*/ +/* and remove ERROR and nunsfm completely. */ +/* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in +*/ +/* sread.f. When LPC10 is embedded into an application, one might want */ +/* to cause it to be incremented in a routine that takes the output of */ +/* SYNTHS and sends it to an audio device. It could be optionally */ +/* displayed, for those that might want to know what it is. */ +/* maxosp is never initialized to 0 in SETUP, although it probably should +*/ +/* be, and it is updated in subroutine ANALYS. I doubt that its value */ +/* would be of much interest to an application in which LPC10 is */ +/* embedded. */ +/* listl and lincnt are not needed for an embedded LPC10 at all. */ +/* integer nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */ +/* common /contrl/ quant, nbits */ +/* common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */ +/* Parameters/constants */ +/* Voicing coefficient and Linear Discriminant Analysis variables: +*/ +/* Max number of VDC's and VDC levels */ +/* The following are not Fortran PARAMETER's, but they are */ +/* initialized with DATA statements, and never modified. */ +/* Actual number of VDC's and levels */ +/* Local variables that need not be saved */ +/* Note: */ + +/* VALUE(1) through VALUE(8) are assigned values, but VALUE(9) */ +/* never is. Yet VALUE(9) is read in the loop that begins "DO I = +*/ +/* 1, 9" below. I believe that this doesn't cause any problems in +*/ +/* this subroutine, because all VDC(9,*) array elements are 0, and +*/ +/* this is what is multiplied by VALUE(9) in all cases. Still, it +*/ +/* would save a multiplication to change the loop to "DO I = 1, 8". +*/ +/* Local state */ +/* WARNING! */ + +/* VOICE, SFBUE, and SLBUE should be saved from one invocation to */ +/* the next, but they are never given an initial value. */ + +/* Does Fortran 77 specify some default initial value, like 0, or */ +/* is it undefined? If it is undefined, then this code should be */ +/* corrected to specify an initial value. */ + +/* For VOICE, note that it is "shifted" in the statement that */ +/* begins "IF (HALF .EQ. 1) THEN" below. Also, uninitialized */ +/* values in the VOICE array can only affect entries in the VOIBUF +*/ +/* array that are for the same frame, or for an older frame. Thus +*/ +/* the effects of uninitialized values in VOICE cannot linger on */ +/* for more than 2 or 3 frame times. */ + +/* For SFBUE and SLBUE, the effects of uninitialized values can */ +/* linger on for many frame times, because their previous values */ +/* are exponentially decayed. Thus it is more important to choose +*/ +/* initial values for these variables. I would guess that a */ +/* reasonable initial value for SFBUE is REF/16, the same as used */ +/* for FBUE and OFBUE. Similarly, SLBUE can be initialized to */ +/* REF/32, the same as for LBUE and OLBUE. */ + +/* These guessed initial values should be validated by re-running */ +/* the modified program on some audio samples. */ + +/* Declare and initialize filters: */ + + dither = (&st->dither); + snr = (&st->snr); + maxmin = (&st->maxmin); + voice = (&st->voice[0]); + lbve = (&st->lbve); + lbue = (&st->lbue); + fbve = (&st->fbve); + fbue = (&st->fbue); + ofbue = (&st->ofbue); + olbue = (&st->olbue); + sfbue = (&st->sfbue); + slbue = (&st->slbue); + + /* Parameter adjustments */ + if (vwin) { + --vwin; + } + if (buflim) { + --buflim; + } + if (inbuf) { + inbuf_offset = buflim[1]; + inbuf -= inbuf_offset; + } + if (lpbuf) { + lpbuf_offset = buflim[3]; + lpbuf -= lpbuf_offset; + } + if (ivrc) { + --ivrc; + } + if (obound) { + --obound; + } + if (voibuf) { + --voibuf; + } + + /* Function Body */ + +/* The following variables are saved from one invocation to the */ +/* next, but are not initialized with DATA statements. This is */ +/* acceptable, because FIRST is initialized ot .TRUE., and the */ +/* first time that this subroutine is then called, they are all */ +/* given initial values. */ + +/* SNR */ +/* LBVE, LBUE, FBVE, FBUE, OFBUE, OLBUE */ + +/* MAXMIN is initialized on the first call, assuming that HALF */ +/* .EQ. 1 on first call. This is how ANALYS calls this subroutine. +*/ + +/* Voicing Decision Parameter vector (* denotes zero coefficient): */ + +/* * MAXMIN */ +/* LBE/LBVE */ +/* ZC */ +/* RC1 */ +/* QS */ +/* IVRC2 */ +/* aR_B */ +/* aR_F */ +/* * LOG(LBE/LBVE) */ +/* Define 2-D voicing decision coefficient vector according to the voicin +g*/ +/* parameter order above. Each row (VDC vector) is optimized for a speci +fic*/ +/* SNR. The last element of the vector is the constant. */ +/* E ZC RC1 Qs IVRC2 aRb aRf c */ + +/* The VOICE array contains the result of the linear discriminant functio +n*/ +/* (analog values). The VOIBUF array contains the hard-limited binary +*/ +/* voicing decisions. The VOICE and VOIBUF arrays, according to FORTRAN + */ +/* memory allocation, are addressed as: */ + +/* (half-frame number, future-frame number) */ + +/* | Past | Present | Future1 | Future2 | */ +/* | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | ---> time */ + +/* Update linear discriminant function history each frame: */ + if (*half == 1) { + voice[0] = voice[2]; + voice[1] = voice[3]; + voice[2] = voice[4]; + voice[3] = voice[5]; + *maxmin = *maxamd / max(*minamd,1.f); + } +/* Calculate voicing parameters twice per frame: */ + vparms_(&vwin[1], &inbuf[inbuf_offset], &lpbuf[lpbuf_offset], &buflim[1], + half, dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b__, & + ar_f__); +/* Estimate signal-to-noise ratio to select the appropriate VDC vector. +*/ +/* The SNR is estimated as the running average of the ratio of the */ +/* running average full-band voiced energy to the running average */ +/* full-band unvoiced energy. SNR filter has gain of 63. */ + r__1 = (*snr + *fbve / (real) max(*fbue,1)) * 63 / 64.f; + *snr = (real) i_nint(&r__1); + snr2 = *snr * *fbue / max(*lbue,1); +/* Quantize SNR to SNRL according to VDCL thresholds. */ + snrl = 1; + i__1 = nvdcl - 1; + for (snrl = 1; snrl <= i__1; ++snrl) { + if (snr2 > vdcl[snrl - 1]) { + goto L69; + } + } +/* (Note: SNRL = NVDCL here) */ +L69: +/* Linear discriminant voicing parameters: */ + value[0] = *maxmin; + value[1] = (real) lbe / max(*lbve,1); + value[2] = (real) zc; + value[3] = rc1; + value[4] = qs; + value[5] = ivrc[2]; + value[6] = ar_b__; + value[7] = ar_f__; +/* Evaluation of linear discriminant function: */ + voice[*half + 3] = vdc[snrl * 10 - 1]; + for (i__ = 1; i__ <= 8; ++i__) { + voice[*half + 3] += vdc[i__ + snrl * 10 - 11] * value[i__ - 1]; + } +/* Classify as voiced if discriminant > 0, otherwise unvoiced */ +/* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */ + if (voice[*half + 3] > 0.f) { + voibuf[*half + 6] = 1; + } else { + voibuf[*half + 6] = 0; + } +/* Skip voicing decision smoothing in first half-frame: */ +/* Give a value to VSTATE, so that trace statements below will print +*/ +/* a consistent value from one call to the next when HALF .EQ. 1. */ +/* The value of VSTATE is not used for any other purpose when this is +*/ +/* true. */ + vstate = -1; + if (*half == 1) { + goto L99; + } +/* Voicing decision smoothing rules (override of linear combination): */ + +/* Unvoiced half-frames: At least two in a row. */ +/* -------------------- */ + +/* Voiced half-frames: At least two in a row in one frame. */ +/* ------------------- Otherwise at least three in a row. */ +/* (Due to the way transition frames are encoded) */ + +/* In many cases, the discriminant function determines how to smooth. */ +/* In the following chart, the decisions marked with a * may be overridden +.*/ + +/* Voicing override of transitions at onsets: */ +/* If a V/UV or UV/V voicing decision transition occurs within one-half +*/ +/* frame of an onset bounding a voicing window, then the transition is */ +/* moved to occur at the onset. */ + +/* P 1F */ +/* ----- ----- */ +/* 0 0 0 0 */ +/* 0 0 0* 1 (If there is an onset there) */ +/* 0 0 1* 0* (Based on 2F and discriminant distance) */ +/* 0 0 1 1 */ +/* 0 1* 0 0 (Always) */ +/* 0 1* 0* 1 (Based on discriminant distance) */ +/* 0* 1 1 0* (Based on past, 2F, and discriminant distance) */ +/* 0 1* 1 1 (If there is an onset there) */ +/* 1 0* 0 0 (If there is an onset there) */ +/* 1 0 0 1 */ +/* 1 0* 1* 0 (Based on discriminant distance) */ +/* 1 0* 1 1 (Always) */ +/* 1 1 0 0 */ +/* 1 1 0* 1* (Based on 2F and discriminant distance) */ +/* 1 1 1* 0 (If there is an onset there) */ +/* 1 1 1 1 */ + +/* Determine if there is an onset transition between P and 1F. */ +/* OT (Onset Transition) is true if there is an onset between */ +/* P and 1F but not after 1F. */ + ot = ((obound[1] & 2) != 0 || obound[2] == 1) && (obound[3] & 1) == 0; +/* Multi-way dispatch on voicing decision history: */ + vstate = (voibuf[3] << 3) + (voibuf[4] << 2) + (voibuf[5] << 1) + voibuf[ + 6]; + switch (vstate + 1) { + case 1: goto L99; + case 2: goto L1; + case 3: goto L2; + case 4: goto L99; + case 5: goto L4; + case 6: goto L5; + case 7: goto L6; + case 8: goto L7; + case 9: goto L8; + case 10: goto L99; + case 11: goto L10; + case 12: goto L11; + case 13: goto L99; + case 14: goto L13; + case 15: goto L14; + case 16: goto L99; + } +L1: + if (ot && voibuf[7] == 1) { + voibuf[5] = 1; + } + goto L99; +L2: + if (voibuf[7] == 0 || voice[2] < -voice[3]) { + voibuf[5] = 0; + } else { + voibuf[6] = 1; + } + goto L99; +L4: + voibuf[4] = 0; + goto L99; +L5: + if (voice[1] < -voice[2]) { + voibuf[4] = 0; + } else { + voibuf[5] = 1; + } + goto L99; +/* VOIBUF(2,0) must be 0 */ +L6: + if (voibuf[1] == 1 || voibuf[7] == 1 || voice[3] > voice[0]) { + voibuf[6] = 1; + } else { + voibuf[3] = 1; + } + goto L99; +L7: + if (ot) { + voibuf[4] = 0; + } + goto L99; +L8: + if (ot) { + voibuf[4] = 1; + } + goto L99; +L10: + if (voice[2] < -voice[1]) { + voibuf[5] = 0; + } else { + voibuf[4] = 1; + } + goto L99; +L11: + voibuf[4] = 1; + goto L99; +L13: + if (voibuf[7] == 0 && voice[3] < -voice[2]) { + voibuf[6] = 0; + } else { + voibuf[5] = 1; + } + goto L99; +L14: + if (ot && voibuf[7] == 0) { + voibuf[5] = 0; + } +/* GOTO 99 */ +L99: +/* Now update parameters: */ +/* ---------------------- */ + +/* During unvoiced half-frames, update the low band and full band unvoice +d*/ +/* energy estimates (LBUE and FBUE) and also the zero crossing */ +/* threshold (DITHER). (The input to the unvoiced energy filters is */ +/* restricted to be less than 10dB above the previous inputs of the */ +/* filters.) */ +/* During voiced half-frames, update the low-pass (LBVE) and all-pass */ +/* (FBVE) voiced energy estimates. */ + if (voibuf[*half + 6] == 0) { +/* Computing MIN */ + i__1 = fbe, i__2 = *ofbue * 3; + r__1 = (*sfbue * 63 + (min(i__1,i__2) << 3)) / 64.f; + *sfbue = i_nint(&r__1); + *fbue = *sfbue / 8; + *ofbue = fbe; +/* Computing MIN */ + i__1 = lbe, i__2 = *olbue * 3; + r__1 = (*slbue * 63 + (min(i__1,i__2) << 3)) / 64.f; + *slbue = i_nint(&r__1); + *lbue = *slbue / 8; + *olbue = lbe; + } else { + r__1 = (*lbve * 63 + lbe) / 64.f; + *lbve = i_nint(&r__1); + r__1 = (*fbve * 63 + fbe) / 64.f; + *fbve = i_nint(&r__1); + } +/* Set dither threshold to yield proper zero crossing rates in the */ +/* presence of low frequency noise and low level signal input. */ +/* NOTE: The divisor is a function of REF, the expected energies. */ +/* Computing MIN */ +/* Computing MAX */ + r__2 = sqrt((real) (*lbue * *lbve)) * 64 / 3000; + r__1 = max(r__2,1.f); + *dither = min(r__1,20.f); +/* Voicing decisions are returned in VOIBUF. */ + return 0; +} /* voicin_ */ diff --git a/linphone/lpc10-1.5/vparms.c b/linphone/lpc10-1.5/vparms.c new file mode 100644 index 000000000..63c25ea7a --- /dev/null +++ b/linphone/lpc10-1.5/vparms.c @@ -0,0 +1,243 @@ +/* + +$Log: vparms.c,v $ +Revision 1.1.1.1 2001/11/19 19:50:17 smorlat +First cvs. + +Revision 1.1.1.1 2001/08/08 21:29:08 simon +First import + + * Revision 1.1 1996/08/19 22:30:04 jaf + * Initial revision + * + +*/ + +#ifdef P_R_O_T_O_T_Y_P_E_S +extern int vparms_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *dither, integer *mintau, integer *zc, integer *lbe, integer *fbe, real *qs, real *rc1, real *ar_b__, real *ar_f__); +#endif + +/* -- translated by f2c (version 19951025). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static real c_b2 = 1.f; + +/* ********************************************************************* */ + +/* VPARMS Version 50 */ + +/* $Log: vparms.c,v $ +/* Revision 1.1.1.1 2001/11/19 19:50:17 smorlat +/* First cvs. +/* +/* Revision 1.1.1.1 2001/08/08 21:29:08 simon +/* First import +/* + * Revision 1.1 1996/08/19 22:30:04 jaf + * Initial revision + * */ +/* Revision 1.6 1996/03/29 18:01:16 jaf */ +/* Added some more comments about the range of INBUF and LPBUF that can */ +/* be read. Note that it is possible for index VWIN(2)+1 to be read from */ +/* INBUF, which might be outside of its defined range, although that will */ +/* require more careful checking. */ + +/* Revision 1.5 1996/03/19 00:02:02 jaf */ +/* I just noticed that the argument DITHER is modified inside of this */ +/* subroutine. Comments were added explaining the possible final values. */ + +/* Revision 1.4 1996/03/18 22:22:59 jaf */ +/* Finishing the job I said I did with the last check-in comments. */ + +/* Revision 1.3 1996/03/18 22:22:17 jaf */ +/* Just added a few comments about which array indices of the arguments */ +/* are used, and mentioning that this subroutine has no local state. */ + +/* Revision 1.2 1996/03/13 15:02:58 jaf */ +/* Comments added explaining that none of the local variables of this */ +/* subroutine need to be saved from one invocation to the next. */ + +/* Revision 1.1 1996/02/07 14:50:42 jaf */ +/* Initial revision */ + + +/* ********************************************************************* */ + +/* Calculate voicing parameters: */ + +/* Input: */ +/* VWIN - Voicing window limits */ +/* Indices 1 through 2 read. */ +/* INBUF - Input speech buffer */ +/* Indices START-1 through STOP read, */ +/* where START and STOP are defined in the code (only written once). +*/ +/* Note that STOP can be as large as VWIN(2)+1 ! */ +/* LPBUF - Low pass filtered speech */ +/* Indices START-MINTAU through STOP+MINTAU read, */ +/* where START and STOP are defined in the code (only written once). +*/ +/* BUFLIM - Array bounds for INBUF and LPBUF */ +/* Indices 1 through 4 read. */ +/* HALF - Half frame (1 or 2) */ +/* MINTAU - Lag corresponding to minimum AMDF value (pitch estimate) */ +/* Input/Output: */ +/* DITHER - Zero crossing threshold */ +/* The resulting value might be the negation of the input */ +/* value. It might always be the same as the input value, */ +/* if the DO loop below always executes an even number of times. */ +/* Output: (all of them are written on every call) */ +/* ZC - Zero crossing rate */ +/* LBE - Low band energy (sum of magnitudes - SM) */ +/* FBE - Full band energy (SM) */ +/* QS - Ratio of 6 dB/oct preemphasized energy to full band energy */ +/* RC1 - First reflection coefficient */ +/* AR_B - Product of the causal forward and reverse pitch */ +/* prediction gains */ +/* AR_F - Product of the noncausal forward and reverse pitch */ +/* prediction gains */ +/* Internal: */ +/* OLDSGN - Previous sign of dithered signal */ +/* VLEN - Length of voicing window */ +/* START - Lower address of current half of voicing window */ +/* STOP - Upper address of current half of voicing window */ +/* E_0 - Energy of LPF speech (sum of squares - SS) */ +/* E_B - Energy of LPF speech backward one pitch period (SS) */ +/* E_F - Energy of LPF speech forward one pitch period (SS) */ +/* R_B - Autocovariance of LPF speech backward one pitch period */ +/* R_F - Autocovariance of LPF speech forward one pitch period */ +/* LP_RMS - Energy of LPF speech (sum of magnitudes - SM) */ +/* AP_RMS - Energy of all-pass speech (SM) */ +/* E_PRE - Energy of 6dB preemphasized speech (SM) */ +/* E0AP - Energy of all-pass speech (SS) */ + +/* This subroutine has no local state. */ + +/* Subroutine */ int vparms_(integer *vwin, real *inbuf, real *lpbuf, integer + *buflim, integer *half, real *dither, integer *mintau, integer *zc, + integer *lbe, integer *fbe, real *qs, real *rc1, real *ar_b__, real * + ar_f__) +{ + /* System generated locals */ + integer inbuf_offset, lpbuf_offset, i__1; + real r__1, r__2; + + /* Builtin functions */ + double r_sign(real *, real *); + integer i_nint(real *); + + /* Local variables */ + integer vlen, stop, i__; + real e_pre__; + integer start; + real ap_rms__, e_0__, oldsgn, lp_rms__, e_b__, e_f__, r_b__, r_f__, e0ap; + +/* Arguments */ +/* Local variables that need not be saved */ +/* Calculate zero crossings (ZC) and several energy and correlation */ +/* measures on low band and full band speech. Each measure is taken */ +/* over either the first or the second half of the voicing window, */ +/* depending on the variable HALF. */ + /* Parameter adjustments */ + --vwin; + --buflim; + lpbuf_offset = buflim[3]; + lpbuf -= lpbuf_offset; + inbuf_offset = buflim[1]; + inbuf -= inbuf_offset; + + /* Function Body */ + lp_rms__ = 0.f; + ap_rms__ = 0.f; + e_pre__ = 0.f; + e0ap = 0.f; + *rc1 = 0.f; + e_0__ = 0.f; + e_b__ = 0.f; + e_f__ = 0.f; + r_f__ = 0.f; + r_b__ = 0.f; + *zc = 0; + vlen = vwin[2] - vwin[1] + 1; + start = vwin[1] + (*half - 1) * vlen / 2 + 1; + stop = start + vlen / 2 - 1; + +/* I'll use the symbol HVL in the table below to represent the value */ +/* VLEN/2. Note that if VLEN is odd, then HVL should be rounded down, */ +/* i.e., HVL = (VLEN-1)/2. */ + +/* HALF START STOP */ + +/* 1 VWIN(1)+1 VWIN(1)+HVL */ +/* 2 VWIN(1)+HVL+1 VWIN(1)+2*HVL */ + +/* Note that if VLEN is even and HALF is 2, then STOP will be */ +/* VWIN(1)+VLEN = VWIN(2)+1. That could be bad, if that index of INBUF */ +/* is undefined. */ + + r__1 = inbuf[start - 1] - *dither; + oldsgn = r_sign(&c_b2, &r__1); + i__1 = stop; + for (i__ = start; i__ <= i__1; ++i__) { + lp_rms__ += (r__1 = lpbuf[i__], abs(r__1)); + ap_rms__ += (r__1 = inbuf[i__], abs(r__1)); + e_pre__ += (r__1 = inbuf[i__] - inbuf[i__ - 1], abs(r__1)); +/* Computing 2nd power */ + r__1 = inbuf[i__]; + e0ap += r__1 * r__1; + *rc1 += inbuf[i__] * inbuf[i__ - 1]; +/* Computing 2nd power */ + r__1 = lpbuf[i__]; + e_0__ += r__1 * r__1; +/* Computing 2nd power */ + r__1 = lpbuf[i__ - *mintau]; + e_b__ += r__1 * r__1; +/* Computing 2nd power */ + r__1 = lpbuf[i__ + *mintau]; + e_f__ += r__1 * r__1; + r_f__ += lpbuf[i__] * lpbuf[i__ + *mintau]; + r_b__ += lpbuf[i__] * lpbuf[i__ - *mintau]; + r__1 = inbuf[i__] + *dither; + if (r_sign(&c_b2, &r__1) != oldsgn) { + ++(*zc); + oldsgn = -oldsgn; + } + *dither = -(*dither); + } +/* Normalized short-term autocovariance coefficient at unit sample delay + */ + *rc1 /= max(e0ap,1.f); +/* Ratio of the energy of the first difference signal (6 dB/oct preemphas +is)*/ +/* to the energy of the full band signal */ +/* Computing MAX */ + r__1 = ap_rms__ * 2.f; + *qs = e_pre__ / max(r__1,1.f); +/* aR_b is the product of the forward and reverse prediction gains, */ +/* looking backward in time (the causal case). */ + *ar_b__ = r_b__ / max(e_b__,1.f) * (r_b__ / max(e_0__,1.f)); +/* aR_f is the same as aR_b, but looking forward in time (non causal case +).*/ + *ar_f__ = r_f__ / max(e_f__,1.f) * (r_f__ / max(e_0__,1.f)); +/* Normalize ZC, LBE, and FBE to old fixed window length of 180. */ +/* (The fraction 90/VLEN has a range of .58 to 1) */ + r__2 = (real) (*zc << 1); + r__1 = r__2 * (90.f / vlen); + *zc = i_nint(&r__1); +/* Computing MIN */ + r__1 = lp_rms__ / 4 * (90.f / vlen); + i__1 = i_nint(&r__1); + *lbe = min(i__1,32767); +/* Computing MIN */ + r__1 = ap_rms__ / 4 * (90.f / vlen); + i__1 = i_nint(&r__1); + *fbe = min(i__1,32767); + return 0; +} /* vparms_ */ + diff --git a/linphone/m4/.cvsignore b/linphone/m4/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/m4/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/m4/Makefile.am b/linphone/m4/Makefile.am new file mode 100644 index 000000000..562029e7c --- /dev/null +++ b/linphone/m4/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST= $(shell cd $(srcdir) && ls *.m4) + diff --git a/linphone/m4/codeset.m4 b/linphone/m4/codeset.m4 new file mode 100644 index 000000000..223955b45 --- /dev/null +++ b/linphone/m4/codeset.m4 @@ -0,0 +1,21 @@ +# codeset.m4 serial 2 (gettext-0.16) +dnl Copyright (C) 2000-2002, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET); return !cs;], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/linphone/m4/exosip.m4 b/linphone/m4/exosip.m4 new file mode 100644 index 000000000..229687c80 --- /dev/null +++ b/linphone/m4/exosip.m4 @@ -0,0 +1,32 @@ +dnl -*- autoconf -*- +AC_DEFUN([LP_SETUP_EXOSIP],[ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([LP_CHECK_OSIP2]) + +dnl eXosip embeded stuff +EXOSIP_CFLAGS="$OSIP_CFLAGS -DOSIP_MT " +EXOSIP_LIBS="$OSIP_LIBS -leXosip2 " + +CPPFLAGS_save=$CPPFLAGS +CPPFLAGS=$OSIP_CFLAGS +AC_CHECK_HEADER([eXosip2/eXosip.h], ,AC_MSG_ERROR([Could not find eXosip2 headers !])) +CPPFLAGS=$CPPFLAGS_save + +dnl check for eXosip2 libs +LDFLAGS_save=$LDFLAGS +LDFLAGS=$OSIP_LIBS +LIBS_save=$LIBS +AC_CHECK_LIB([eXosip2],[eXosip_subscribe_remove], + [], + [AC_MSG_ERROR([Could not find eXosip2 library with version >= 3.0.2 !])], + [-losipparser2 -losip2 -lpthread]) +AC_CHECK_LIB([eXosip2],[eXosip_get_version], + [AC_DEFINE([HAVE_EXOSIP_GET_VERSION],[1],[Defined when eXosip_get_version is available])], + [], + [-losipparser2 -losip2 -lpthread]) +LIBS=$LIBS_save +LDFLAGS=$LDFLAGS_save + +AC_SUBST(EXOSIP_CFLAGS) +AC_SUBST(EXOSIP_LIBS) +]) diff --git a/linphone/m4/gettext.m4 b/linphone/m4/gettext.m4 new file mode 100644 index 000000000..91c345e99 --- /dev/null +++ b/linphone/m4/gettext.m4 @@ -0,0 +1,419 @@ +# gettext.m4 serial 59 (gettext-0.16.1) +dnl Copyright (C) 1995-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2006. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_included_intl], + ifelse([$1], [external], + ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), + [yes])) + define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_TRY_LINK([#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *);], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv. + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *);], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLOBJS= + if test "$USE_INCLUDED_LIBINTL" = yes; then + INTLOBJS="\$(GETTOBJS)" + fi + AC_SUBST(INTLOBJS) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for special options needed on MacOS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in MacOS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + gt_cv_func_CFPreferencesCopyAppValue, + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include ], + [CFPreferencesCopyAppValue(NULL, NULL)], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1, + [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in MacOS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent, + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include ], [CFLocaleCopyCurrent();], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1, + [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/linphone/m4/glibc2.m4 b/linphone/m4/glibc2.m4 new file mode 100644 index 000000000..e8f5bfe6e --- /dev/null +++ b/linphone/m4/glibc2.m4 @@ -0,0 +1,30 @@ +# glibc2.m4 serial 1 +dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Test for the GNU C Library, version 2.0 or newer. +# From Bruno Haible. + +AC_DEFUN([gt_GLIBC2], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2 or newer, + ac_cv_gnu_library_2, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2=yes, + ac_cv_gnu_library_2=no) + ] + ) + AC_SUBST(GLIBC2) + GLIBC2="$ac_cv_gnu_library_2" + ] +) diff --git a/linphone/m4/glibc21.m4 b/linphone/m4/glibc21.m4 new file mode 100644 index 000000000..d95fd9861 --- /dev/null +++ b/linphone/m4/glibc21.m4 @@ -0,0 +1,30 @@ +# glibc21.m4 serial 3 +dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([gl_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) diff --git a/linphone/m4/iconv.m4 b/linphone/m4/iconv.m4 new file mode 100644 index 000000000..654c41589 --- /dev/null +++ b/linphone/m4/iconv.m4 @@ -0,0 +1,101 @@ +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/linphone/m4/ilbc.m4 b/linphone/m4/ilbc.m4 new file mode 100644 index 000000000..465f8506d --- /dev/null +++ b/linphone/m4/ilbc.m4 @@ -0,0 +1,33 @@ +AC_DEFUN([LP_CHECK_ILBC],[ + +AC_ARG_WITH( ilbc, + [ --with-ilbc Set prefix where ilbc headers and libs can be found (ex:/usr, /usr/local, none to disable ilbc support) [default=/usr] ], + [ ilbc_prefix=${withval}],[ ilbc_prefix="/usr" ]) + +if test "$ilbc_prefix" = "none" ; then + AC_MSG_NOTICE([iLBC codec support disabled. ]) +else + ILBC_CFLAGS=" -I${ilbc_prefix}/include/ilbc" + ILBC_LIBS="-L${ilbc_prefix}/lib -lilbc -lm" + CPPFLAGS_save=$CPPFLAGS + CPPFLAGS=$ILBC_CFLAGS + LDFLAGS_save=$LDFLAGS + LDFLAGS=$ILBC_LIBS + AC_CHECK_HEADERS(iLBC_decode.h,[AC_CHECK_LIB(ilbc,iLBC_decode,ilbc_found=yes,ilbc_found=no) + ],ilbc_found=no) + + CPPFLAGS=$CPPFLAGS_save + LDFLAGS=$LDFLAGS_save + + if test "$ilbc_found" = "no" ; then + AC_MSG_WARN([Could not find ilbc headers or libs. Please install ilbc package from http://www.linphone.org if you want iLBC codec support in linphone.]) + ILBC_CFLAGS= + ILBC_LIBS= + else + AC_DEFINE(HAVE_ILBC,1,[Defined when we have ilbc codec lib]) + AC_SUBST(ILBC_CFLAGS) + AC_SUBST(ILBC_LIBS) + fi +fi + +]) diff --git a/linphone/m4/intdiv0.m4 b/linphone/m4/intdiv0.m4 new file mode 100644 index 000000000..b8d78176a --- /dev/null +++ b/linphone/m4/intdiv0.m4 @@ -0,0 +1,70 @@ +# intdiv0.m4 serial 1 (gettext-0.11.3) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gt_INTDIV0], +[ + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], + gt_cv_int_divbyzero_sigfpe, + [ + AC_TRY_RUN([ +#include +#include + +static void +#ifdef __cplusplus +sigfpe_handler (int sig) +#else +sigfpe_handler (sig) int sig; +#endif +{ + /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ + exit (sig != SIGFPE); +} + +int x = 1; +int y = 0; +int z; +int nan; + +int main () +{ + signal (SIGFPE, sigfpe_handler); +/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ +#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) + signal (SIGTRAP, sigfpe_handler); +#endif +/* Linux/SPARC yields signal SIGILL. */ +#if defined (__sparc__) && defined (__linux__) + signal (SIGILL, sigfpe_handler); +#endif + + z = x / y; + nan = y / y; + exit (1); +} +], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, + [ + # Guess based on the CPU. + case "$host_cpu" in + alpha* | i[34567]86 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; + esac + ]) + ]) + case "$gt_cv_int_divbyzero_sigfpe" in + *yes) value=1;; + *) value=0;; + esac + AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, + [Define if integer division by zero raises signal SIGFPE.]) +]) diff --git a/linphone/m4/intl.m4 b/linphone/m4/intl.m4 new file mode 100644 index 000000000..dcefb118c --- /dev/null +++ b/linphone/m4/intl.m4 @@ -0,0 +1,259 @@ +# intl.m4 serial 3 (gettext-0.16) +dnl Copyright (C) 1995-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2006. + +AC_PREREQ(2.52) + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([gt_GLIBC2])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([gl_VISIBILITY])dnl + AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl + AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl + AC_REQUIRE([gt_TYPE_LONGDOUBLE])dnl + AC_REQUIRE([gt_TYPE_WCHAR_T])dnl + AC_REQUIRE([gt_TYPE_WINT_T])dnl + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gt_TYPE_INTMAX_T]) + AC_REQUIRE([gt_PRINTF_POSIX]) + AC_REQUIRE([gl_GLIBC21])dnl + AC_REQUIRE([gl_XSIZE])dnl + AC_REQUIRE([gt_INTL_MACOSX])dnl + + AC_CHECK_TYPE([ptrdiff_t], , + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) + AC_CHECK_HEADERS([stddef.h stdlib.h string.h]) + AC_CHECK_FUNCS([asprintf fwprintf putenv setenv setlocale snprintf wcslen]) + + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). + gt_CHECK_DECL(_snprintf, [#include ]) + gt_CHECK_DECL(_snwprintf, [#include ]) + + dnl Use the *_unlocked functions only if they are declared. + dnl (because some of them were defined without being declared in Solaris + dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built + dnl on Solaris 2.5.1 to run on Solaris 2.6). + dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. + gt_CHECK_DECL(getc_unlocked, [#include ]) + + case $gt_cv_func_printf_posix in + *yes) HAVE_POSIX_PRINTF=1 ;; + *) HAVE_POSIX_PRINTF=0 ;; + esac + AC_SUBST([HAVE_POSIX_PRINTF]) + if test "$ac_cv_func_asprintf" = yes; then + HAVE_ASPRINTF=1 + else + HAVE_ASPRINTF=0 + fi + AC_SUBST([HAVE_ASPRINTF]) + if test "$ac_cv_func_snprintf" = yes; then + HAVE_SNPRINTF=1 + else + HAVE_SNPRINTF=0 + fi + AC_SUBST([HAVE_SNPRINTF]) + if test "$ac_cv_func_wprintf" = yes; then + HAVE_WPRINTF=1 + else + HAVE_WPRINTF=0 + fi + AC_SUBST([HAVE_WPRINTF]) + + AM_LANGINFO_CODESET + gt_LC_MESSAGES + + dnl Compilation on mingw and Cygwin needs special Makefile rules, because + dnl 1. when we install a shared library, we must arrange to export + dnl auxiliary pointer variables for every exported variable, + dnl 2. when we install a shared library and a static library simultaneously, + dnl the include file specifies __declspec(dllimport) and therefore we + dnl must arrange to define the auxiliary pointer variables for the + dnl exported variables _also_ in the static library. + if test "$enable_shared" = yes; then + case "$host_os" in + cygwin*) is_woe32dll=yes ;; + *) is_woe32dll=no ;; + esac + else + is_woe32dll=no + fi + WOE32DLL=$is_woe32dll + AC_SUBST([WOE32DLL]) + + dnl Rename some macros and functions used for locking. + AH_BOTTOM([ +#define __libc_lock_t gl_lock_t +#define __libc_lock_define gl_lock_define +#define __libc_lock_define_initialized gl_lock_define_initialized +#define __libc_lock_init gl_lock_init +#define __libc_lock_lock gl_lock_lock +#define __libc_lock_unlock gl_lock_unlock +#define __libc_lock_recursive_t gl_recursive_lock_t +#define __libc_lock_define_recursive gl_recursive_lock_define +#define __libc_lock_define_initialized_recursive gl_recursive_lock_define_initialized +#define __libc_lock_init_recursive gl_recursive_lock_init +#define __libc_lock_lock_recursive gl_recursive_lock_lock +#define __libc_lock_unlock_recursive gl_recursive_lock_unlock +#define glthread_in_use libintl_thread_in_use +#define glthread_lock_init libintl_lock_init +#define glthread_lock_lock libintl_lock_lock +#define glthread_lock_unlock libintl_lock_unlock +#define glthread_lock_destroy libintl_lock_destroy +#define glthread_rwlock_init libintl_rwlock_init +#define glthread_rwlock_rdlock libintl_rwlock_rdlock +#define glthread_rwlock_wrlock libintl_rwlock_wrlock +#define glthread_rwlock_unlock libintl_rwlock_unlock +#define glthread_rwlock_destroy libintl_rwlock_destroy +#define glthread_recursive_lock_init libintl_recursive_lock_init +#define glthread_recursive_lock_lock libintl_recursive_lock_lock +#define glthread_recursive_lock_unlock libintl_recursive_lock_unlock +#define glthread_recursive_lock_destroy libintl_recursive_lock_destroy +#define glthread_once libintl_once +#define glthread_once_call libintl_once_call +#define glthread_once_singlethreaded libintl_once_singlethreaded +]) +]) + + +dnl Checks for the core files of the intl subdirectory: +dnl dcigettext.c +dnl eval-plural.h +dnl explodename.c +dnl finddomain.c +dnl gettextP.h +dnl gmo.h +dnl hash-string.h hash-string.c +dnl l10nflist.c +dnl libgnuintl.h.in (except the *printf stuff) +dnl loadinfo.h +dnl loadmsgcat.c +dnl localealias.c +dnl log.c +dnl plural-exp.h plural-exp.c +dnl plural.y +dnl Used by libglocale. +AC_DEFUN([gt_INTL_SUBDIR_CORE], +[ + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + AC_REQUIRE([gl_LOCK])dnl + + AC_TRY_LINK( + [int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }], + [], + [AC_DEFINE([HAVE_BUILTIN_EXPECT], 1, + [Define to 1 if the compiler understands __builtin_expect.])]) + + AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \ + stpcpy strcasecmp strdup strtoul tsearch argz_count argz_stringify \ + argz_next __fsetlocking]) + + dnl Use the *_unlocked functions only if they are declared. + dnl (because some of them were defined without being declared in Solaris + dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built + dnl on Solaris 2.5.1 to run on Solaris 2.6). + dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. + gt_CHECK_DECL(feof_unlocked, [#include ]) + gt_CHECK_DECL(fgets_unlocked, [#include ]) + + AM_ICONV + + dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOURCE is defined, + dnl and a _NL_LOCALE_NAME macro always. + AC_CACHE_CHECK([for NL_LOCALE_NAME macro], gt_cv_nl_locale_name, + [AC_TRY_LINK([#include +#include ], + [char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));], + gt_cv_nl_locale_name=yes, + gt_cv_nl_locale_name=no) + ]) + if test $gt_cv_nl_locale_name = yes; then + AC_DEFINE(HAVE_NL_LOCALE_NAME, 1, + [Define if you have and it defines the NL_LOCALE_NAME macro if _GNU_SOURCE is defined.]) + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +dnl gt_CHECK_DECL(FUNC, INCLUDES) +dnl Check whether a function is declared. +AC_DEFUN([gt_CHECK_DECL], +[ + AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1, + [AC_TRY_COMPILE([$2], [ +#ifndef $1 + char *p = (char *) $1; +#endif +], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)]) + if test $ac_cv_have_decl_$1 = yes; then + gt_value=1 + else + gt_value=0 + fi + AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], + [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) +]) diff --git a/linphone/m4/intldir.m4 b/linphone/m4/intldir.m4 new file mode 100644 index 000000000..7a28843f6 --- /dev/null +++ b/linphone/m4/intldir.m4 @@ -0,0 +1,19 @@ +# intldir.m4 serial 1 (gettext-0.16) +dnl Copyright (C) 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +AC_PREREQ(2.52) + +dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory. +AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], []) diff --git a/linphone/m4/intmax.m4 b/linphone/m4/intmax.m4 new file mode 100644 index 000000000..ce7a8a49d --- /dev/null +++ b/linphone/m4/intmax.m4 @@ -0,0 +1,33 @@ +# intmax.m4 serial 3 (gettext-0.16) +dnl Copyright (C) 2002-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether the system has the 'intmax_t' type, but don't attempt to +dnl find a replacement if it is lacking. + +AC_DEFUN([gt_TYPE_INTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, + [AC_TRY_COMPILE([ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif +], [intmax_t x = -1; + return !x;], + gt_cv_c_intmax_t=yes, + gt_cv_c_intmax_t=no)]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE(HAVE_INTMAX_T, 1, + [Define if you have the 'intmax_t' type in or .]) + fi +]) diff --git a/linphone/m4/inttypes-pri.m4 b/linphone/m4/inttypes-pri.m4 new file mode 100644 index 000000000..7c7f89401 --- /dev/null +++ b/linphone/m4/inttypes-pri.m4 @@ -0,0 +1,36 @@ +# inttypes-pri.m4 serial 4 (gettext-0.16) +dnl Copyright (C) 1997-2002, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ(2.52) + +# Define PRI_MACROS_BROKEN if exists and defines the PRI* +# macros to non-string values. This is the case on AIX 4.3.3. + +AC_DEFUN([gt_INTTYPES_PRI], +[ + AC_CHECK_HEADERS([inttypes.h]) + if test $ac_cv_header_inttypes_h = yes; then + AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], + gt_cv_inttypes_pri_broken, + [ + AC_TRY_COMPILE([#include +#ifdef PRId32 +char *p = PRId32; +#endif +], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) + ]) + fi + if test "$gt_cv_inttypes_pri_broken" = yes; then + AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, + [Define if exists and defines unusable PRI* macros.]) + PRI_MACROS_BROKEN=1 + else + PRI_MACROS_BROKEN=0 + fi + AC_SUBST([PRI_MACROS_BROKEN]) +]) diff --git a/linphone/m4/inttypes.m4 b/linphone/m4/inttypes.m4 new file mode 100644 index 000000000..779bcea05 --- /dev/null +++ b/linphone/m4/inttypes.m4 @@ -0,0 +1,25 @@ +# inttypes.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H if exists and doesn't clash with +# . + +AC_DEFUN([gt_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, + [ + AC_TRY_COMPILE( + [#include +#include ], + [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) + ]) + if test $gt_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, + [Define if exists and doesn't clash with .]) + fi +]) diff --git a/linphone/m4/inttypes_h.m4 b/linphone/m4/inttypes_h.m4 new file mode 100644 index 000000000..edc8ecb2d --- /dev/null +++ b/linphone/m4/inttypes_h.m4 @@ -0,0 +1,26 @@ +# inttypes_h.m4 serial 7 +dnl Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], gl_cv_header_inttypes_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1; return !i;], + gl_cv_header_inttypes_h=yes, + gl_cv_header_inttypes_h=no)]) + if test $gl_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/linphone/m4/isc-posix.m4 b/linphone/m4/isc-posix.m4 new file mode 100644 index 000000000..74dc8f26d --- /dev/null +++ b/linphone/m4/isc-posix.m4 @@ -0,0 +1,24 @@ +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) diff --git a/linphone/m4/lcmessage.m4 b/linphone/m4/lcmessage.m4 new file mode 100644 index 000000000..19aa77e4f --- /dev/null +++ b/linphone/m4/lcmessage.m4 @@ -0,0 +1,30 @@ +# lcmessage.m4 serial 4 (gettext-0.14.2) +dnl Copyright (C) 1995-2002, 2004-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995. + +# Check whether LC_MESSAGES is available in . + +AC_DEFUN([gt_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], gt_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + gt_cv_val_LC_MESSAGES=yes, gt_cv_val_LC_MESSAGES=no)]) + if test $gt_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi +]) diff --git a/linphone/m4/lib-ld.m4 b/linphone/m4/lib-ld.m4 new file mode 100644 index 000000000..96c4e2c33 --- /dev/null +++ b/linphone/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/linphone/m4/lib-link.m4 b/linphone/m4/lib-link.m4 new file mode 100644 index 000000000..f95b7ba88 --- /dev/null +++ b/linphone/m4/lib-link.m4 @@ -0,0 +1,644 @@ +# lib-link.m4 serial 9 (gettext-0.16) +dnl Copyright (C) 2001-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ(2.50) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" \ + && { test -f "$additional_libdir/lib$name.$shlibext" \ + || { test "$shlibext" = dll \ + && test -f "$additional_libdir/lib$name.dll.a"; }; }; then + found_dir="$additional_libdir" + if test -f "$additional_libdir/lib$name.$shlibext"; then + found_so="$additional_libdir/lib$name.$shlibext" + else + found_so="$additional_libdir/lib$name.dll.a" + fi + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" \ + && { test -f "$dir/lib$name.$shlibext" \ + || { test "$shlibext" = dll \ + && test -f "$dir/lib$name.dll.a"; }; }; then + found_dir="$dir" + if test -f "$dir/lib$name.$shlibext"; then + found_so="$dir/lib$name.$shlibext" + else + found_so="$dir/lib$name.dll.a" + fi + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/linphone/m4/lib-prefix.m4 b/linphone/m4/lib-prefix.m4 new file mode 100644 index 000000000..a8684e17e --- /dev/null +++ b/linphone/m4/lib-prefix.m4 @@ -0,0 +1,185 @@ +# lib-prefix.m4 serial 5 (gettext-0.15) +dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing +dnl the basename of the libdir, either "lib" or "lib64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. The current + dnl practice is that on a system supporting 32-bit and 64-bit instruction + dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit + dnl libraries go under $prefix/lib. We determine the compiler's default + dnl mode by looking at the compiler's library search path. If at least + dnl of its elements ends in /lib64 or points to a directory whose absolute + dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the + dnl default, namely "lib". + acl_libdirstem=lib + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi +]) diff --git a/linphone/m4/lock.m4 b/linphone/m4/lock.m4 new file mode 100644 index 000000000..0224f2ff8 --- /dev/null +++ b/linphone/m4/lock.m4 @@ -0,0 +1,311 @@ +# lock.m4 serial 6 (gettext-0.16) +dnl Copyright (C) 2005-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests for a multithreading library to be used. +dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, +dnl USE_PTH_THREADS, USE_WIN32_THREADS +dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use +dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with +dnl libtool). +dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for +dnl programs that really need multithread functionality. The difference +dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak +dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread". +dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for +dnl multithread-safe programs. + +AC_DEFUN([gl_LOCK_EARLY], +[ + AC_REQUIRE([gl_LOCK_EARLY_BODY]) +]) + +dnl The guts of gl_LOCK_EARLY. Needs to be expanded only once. + +AC_DEFUN([gl_LOCK_EARLY_BODY], +[ + dnl Ordering constraints: This macro modifies CPPFLAGS in a way that + dnl influences the result of the autoconf tests that test for *_unlocked + dnl declarations, on AIX 5 at least. Therefore it must come early. + AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl + AC_BEFORE([$0], [gl_ARGP])dnl + + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_GNU_SOURCE]) dnl needed for pthread_rwlock_t on glibc systems + dnl Check for multithreading. + AC_ARG_ENABLE(threads, +AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API]) +AC_HELP_STRING([--disable-threads], [build without multithread safety]), + [gl_use_threads=$enableval], + [case "$host_os" in + dnl Disable multithreading by default on OSF/1, because it interferes + dnl with fork()/exec(): When msgexec is linked with -lpthread, its child + dnl process gets an endless segmentation fault inside execvp(). + osf*) gl_use_threads=no ;; + *) gl_use_threads=yes ;; + esac + ]) + if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then + # For using : + case "$host_os" in + osf*) + # On OSF/1, the compiler needs the flag -D_REENTRANT so that it + # groks . cc also understands the flag -pthread, but + # we don't use it because 1. gcc-2.95 doesn't understand -pthread, + # 2. putting a flag into CPPFLAGS that has an effect on the linker + # causes the AC_TRY_LINK test below to succeed unexpectedly, + # leading to wrong values of LIBTHREAD and LTLIBTHREAD. + CPPFLAGS="$CPPFLAGS -D_REENTRANT" + ;; + esac + # Some systems optimize for single-threaded programs by default, and + # need special flags to disable these optimizations. For example, the + # definition of 'errno' in . + case "$host_os" in + aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; + solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; + esac + fi +]) + +dnl The guts of gl_LOCK. Needs to be expanded only once. + +AC_DEFUN([gl_LOCK_BODY], +[ + AC_REQUIRE([gl_LOCK_EARLY_BODY]) + gl_threads_api=none + LIBTHREAD= + LTLIBTHREAD= + LIBMULTITHREAD= + LTLIBMULTITHREAD= + if test "$gl_use_threads" != no; then + dnl Check whether the compiler and linker support weak declarations. + AC_MSG_CHECKING([whether imported symbols can be declared weak]) + gl_have_weak=no + AC_TRY_LINK([extern void xyzzy (); +#pragma weak xyzzy], [xyzzy();], [gl_have_weak=yes]) + AC_MSG_RESULT([$gl_have_weak]) + if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then + # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that + # it groks . It's added above, in gl_LOCK_EARLY_BODY. + AC_CHECK_HEADER(pthread.h, gl_have_pthread_h=yes, gl_have_pthread_h=no) + if test "$gl_have_pthread_h" = yes; then + # Other possible tests: + # -lpthreads (FSU threads, PCthreads) + # -lgthreads + gl_have_pthread= + # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist + # in libc. IRIX 6.5 has the first one in both libc and libpthread, but + # the second one only in libpthread, and lock.c needs it. + AC_TRY_LINK([#include ], + [pthread_mutex_lock((pthread_mutex_t*)0); + pthread_mutexattr_init((pthread_mutexattr_t*)0);], + [gl_have_pthread=yes]) + # Test for libpthread by looking for pthread_kill. (Not pthread_self, + # since it is defined as a macro on OSF/1.) + if test -n "$gl_have_pthread"; then + # The program links fine without libpthread. But it may actually + # need to link with libpthread in order to create multiple threads. + AC_CHECK_LIB(pthread, pthread_kill, + [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread + # On Solaris and HP-UX, most pthread functions exist also in libc. + # Therefore pthread_in_use() needs to actually try to create a + # thread: pthread_create from libc will fail, whereas + # pthread_create will actually create a thread. + case "$host_os" in + solaris* | hpux*) + AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], 1, + [Define if the pthread_in_use() detection is hard.]) + esac + ]) + else + # Some library is needed. Try libpthread and libc_r. + AC_CHECK_LIB(pthread, pthread_kill, + [gl_have_pthread=yes + LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread + LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread]) + if test -z "$gl_have_pthread"; then + # For FreeBSD 4. + AC_CHECK_LIB(c_r, pthread_kill, + [gl_have_pthread=yes + LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r + LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r]) + fi + fi + if test -n "$gl_have_pthread"; then + gl_threads_api=posix + AC_DEFINE([USE_POSIX_THREADS], 1, + [Define if the POSIX multithreading library can be used.]) + if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then + if test $gl_have_weak = yes; then + AC_DEFINE([USE_POSIX_THREADS_WEAK], 1, + [Define if references to the POSIX multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the + # pthread_rwlock_* functions. + AC_CHECK_TYPE([pthread_rwlock_t], + [AC_DEFINE([HAVE_PTHREAD_RWLOCK], 1, + [Define if the POSIX multithreading library has read/write locks.])], + [], + [#include ]) + # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro. + AC_TRY_COMPILE([#include ], + [#if __FreeBSD__ == 4 +error "No, in FreeBSD 4.0 recursive mutexes actually don't work." +#else +int x = (int)PTHREAD_MUTEX_RECURSIVE; +return !x; +#endif], + [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], 1, + [Define if the defines PTHREAD_MUTEX_RECURSIVE.])]) + fi + fi + fi + if test -z "$gl_have_pthread"; then + if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then + gl_have_solaristhread= + gl_save_LIBS="$LIBS" + LIBS="$LIBS -lthread" + AC_TRY_LINK([#include +#include ], + [thr_self();], + [gl_have_solaristhread=yes]) + LIBS="$gl_save_LIBS" + if test -n "$gl_have_solaristhread"; then + gl_threads_api=solaris + LIBTHREAD=-lthread + LTLIBTHREAD=-lthread + LIBMULTITHREAD="$LIBTHREAD" + LTLIBMULTITHREAD="$LTLIBTHREAD" + AC_DEFINE([USE_SOLARIS_THREADS], 1, + [Define if the old Solaris multithreading library can be used.]) + if test $gl_have_weak = yes; then + AC_DEFINE([USE_SOLARIS_THREADS_WEAK], 1, + [Define if references to the old Solaris multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + fi + fi + if test "$gl_use_threads" = pth; then + gl_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_LINKFLAGS(pth) + gl_have_pth= + gl_save_LIBS="$LIBS" + LIBS="$LIBS -lpth" + AC_TRY_LINK([#include ], [pth_self();], gl_have_pth=yes) + LIBS="$gl_save_LIBS" + if test -n "$gl_have_pth"; then + gl_threads_api=pth + LIBTHREAD="$LIBPTH" + LTLIBTHREAD="$LTLIBPTH" + LIBMULTITHREAD="$LIBTHREAD" + LTLIBMULTITHREAD="$LTLIBTHREAD" + AC_DEFINE([USE_PTH_THREADS], 1, + [Define if the GNU Pth multithreading library can be used.]) + if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then + if test $gl_have_weak = yes; then + AC_DEFINE([USE_PTH_THREADS_WEAK], 1, + [Define if references to the GNU Pth multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + else + CPPFLAGS="$gl_save_CPPFLAGS" + fi + fi + if test -z "$gl_have_pthread"; then + if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then + if { case "$host_os" in + mingw*) true;; + *) false;; + esac + }; then + gl_threads_api=win32 + AC_DEFINE([USE_WIN32_THREADS], 1, + [Define if the Win32 multithreading API can be used.]) + fi + fi + fi + fi + AC_MSG_CHECKING([for multithread API to use]) + AC_MSG_RESULT([$gl_threads_api]) + AC_SUBST(LIBTHREAD) + AC_SUBST(LTLIBTHREAD) + AC_SUBST(LIBMULTITHREAD) + AC_SUBST(LTLIBMULTITHREAD) +]) + +AC_DEFUN([gl_LOCK], +[ + AC_REQUIRE([gl_LOCK_EARLY]) + AC_REQUIRE([gl_LOCK_BODY]) + gl_PREREQ_LOCK +]) + +# Prerequisites of lib/lock.c. +AC_DEFUN([gl_PREREQ_LOCK], [ + AC_REQUIRE([AC_C_INLINE]) +]) + +dnl Survey of platforms: +dnl +dnl Platform Available Compiler Supports test-lock +dnl flavours option weak result +dnl --------------- --------- --------- -------- --------- +dnl Linux 2.4/glibc posix -lpthread Y OK +dnl +dnl GNU Hurd/glibc posix +dnl +dnl FreeBSD 5.3 posix -lc_r Y +dnl posix -lkse ? Y +dnl posix -lpthread ? Y +dnl posix -lthr Y +dnl +dnl FreeBSD 5.2 posix -lc_r Y +dnl posix -lkse Y +dnl posix -lthr Y +dnl +dnl FreeBSD 4.0,4.10 posix -lc_r Y OK +dnl +dnl NetBSD 1.6 -- +dnl +dnl OpenBSD 3.4 posix -lpthread Y OK +dnl +dnl MacOS X 10.[123] posix -lpthread Y OK +dnl +dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK +dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK +dnl +dnl HP-UX 11 posix -lpthread N (cc) OK +dnl Y (gcc) +dnl +dnl IRIX 6.5 posix -lpthread Y 0.5 +dnl +dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK +dnl +dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK +dnl -lpthread (gcc) Y +dnl +dnl Cygwin posix -lpthread Y OK +dnl +dnl Any of the above pth -lpth 0.0 +dnl +dnl Mingw win32 N OK +dnl +dnl BeOS 5 -- +dnl +dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is +dnl turned off: +dnl OK if all three tests terminate OK, +dnl 0.5 if the first test terminates OK but the second one loops endlessly, +dnl 0.0 if the first test already loops endlessly. diff --git a/linphone/m4/longdouble.m4 b/linphone/m4/longdouble.m4 new file mode 100644 index 000000000..25590f470 --- /dev/null +++ b/linphone/m4/longdouble.m4 @@ -0,0 +1,31 @@ +# longdouble.m4 serial 2 (gettext-0.15) +dnl Copyright (C) 2002-2003, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether the compiler supports the 'long double' type. +dnl Prerequisite: AC_PROG_CC + +dnl This file is only needed in autoconf <= 2.59. Newer versions of autoconf +dnl have a macro AC_TYPE_LONG_DOUBLE with identical semantics. + +AC_DEFUN([gt_TYPE_LONGDOUBLE], +[ + AC_CACHE_CHECK([for long double], gt_cv_c_long_double, + [if test "$GCC" = yes; then + gt_cv_c_long_double=yes + else + AC_TRY_COMPILE([ + /* The Stardent Vistra knows sizeof(long double), but does not support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + int array [2*(sizeof(long double) >= sizeof(double)) - 1]; + ], , + gt_cv_c_long_double=yes, gt_cv_c_long_double=no) + fi]) + if test $gt_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) + fi +]) diff --git a/linphone/m4/longlong.m4 b/linphone/m4/longlong.m4 new file mode 100644 index 000000000..3716c09f6 --- /dev/null +++ b/linphone/m4/longlong.m4 @@ -0,0 +1,48 @@ +# longlong.m4 serial 8 +dnl Copyright (C) 1999-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.60, but can be removed once we +# assume 2.61 everywhere. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), AC_TYPE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + typedef int a[((-9223372036854775807LL < 0 + && 0 < 9223372036854775807ll) + ? 1 : -1)]; + int i = 63;]], + [[long long int llmax = 9223372036854775807ll; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll));]])], + [ac_cv_type_long_long_int=yes], + [ac_cv_type_long_long_int=no])]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `long long int'.]) + fi +]) + +# This macro is obsolescent and should go away soon. +AC_DEFUN([gl_AC_TYPE_LONG_LONG], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + ac_cv_type_long_long=$ac_cv_type_long_long_int + if test $ac_cv_type_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, + [Define if you have the 'long long' type.]) + fi +]) diff --git a/linphone/m4/nls.m4 b/linphone/m4/nls.m4 new file mode 100644 index 000000000..7967cc2f9 --- /dev/null +++ b/linphone/m4/nls.m4 @@ -0,0 +1,31 @@ +# nls.m4 serial 3 (gettext-0.15) +dnl Copyright (C) 1995-2003, 2005-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ(2.50) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) +]) diff --git a/linphone/m4/ortp.m4 b/linphone/m4/ortp.m4 new file mode 100644 index 000000000..e0f36efd1 --- /dev/null +++ b/linphone/m4/ortp.m4 @@ -0,0 +1,16 @@ +AC_DEFUN([LP_CHECK_ORTP],[ + +ortp_pkgconfig=true + +PKG_CHECK_MODULES([ORTP], [ortp], , [ortp_pkgconfig=false]) + +if test $ortp_pkgconfig = false; then + AC_CHECK_HEADER([ortp/ortp.h], ,AC_MSG_ERROR([Could not find oRTP headers !])) + LIBS_save=$LIBS + AC_CHECK_LIB([ortp], [ortp_init], , AC_MSG_ERROR([Could not find oRTP library])) + ORTP_LIBS='-lortp' + LIBS=$LIBS_save +fi +AC_SUBST([ORTP_LIBS]) +AC_SUBST([ORTP_CFLAGS]) +]) diff --git a/linphone/m4/osip.m4 b/linphone/m4/osip.m4 new file mode 100644 index 000000000..2c6c99a0b --- /dev/null +++ b/linphone/m4/osip.m4 @@ -0,0 +1,54 @@ +dnl -*- autoconf -*- +AC_DEFUN([LP_CHECK_OSIP2],[ + +AC_ARG_WITH( osip, + [ --with-osip Set prefix where osip can be found (ex:/usr or /usr/local)[default=/usr] ], + [ osip_prefix=${withval}],[ osip_prefix=/usr ]) + +dnl FC6's compat-osip2 headers live into "/usr/include/osip2-2.2.2", +dnl while libraries are "/usr/lib/libosipparser2-2.2.2.so*". +AC_ARG_WITH( osip-version,dnl +AC_HELP_STRING([--with-osip-version=VERSION], + [Set osip legacy version @<:@empty@:>@]), + [osip_legacy_version="-${withval}"], + [osip_legacy_version=""]) + +osip_pkgconfig=true +osip_pkgconfig_file=libosip2 +if test -n "$osip_legacy_version"; then + osip_pkgconfig_file=libosip2${osip_legacy_version} +fi + +PKG_CHECK_MODULES(OSIP, $osip_pkgconfig_file >= 3.0.0, ,osip_pkgconfig=false) + +if test $osip_pkgconfig = false; then + + if test -z "$osip_legacy_version"; then + OSIP_CFLAGS="-I${osip_prefix}/include" + else + OSIP_CFLAGS="-I${osip_prefix}/include/osip2${osip_legacy_version}" + fi + +dnl check osip2 headers + CPPFLAGS_save=$CPPFLAGS + CPPFLAGS=$OSIP_CFLAGS + AC_CHECK_HEADER([osip2/osip.h], ,AC_MSG_ERROR([Could not find osip2 headers !])) + CPPFLAGS=$CPPFLAGS_save + +dnl check for osip2 libs + OSIP_LIBS="-L$osip_prefix/lib -losipparser2${osip_legacy_version}" + LDFLAGS_save=$LDFLAGS + LDFLAGS=$OSIP_LIBS + LIBS_save=$LIBS + AC_CHECK_LIB(osip2${osip_legacy_version},osip_init, , AC_MSG_ERROR([Could not find osip2 library !]),[-losipparser2${osip_legacy_version} -lpthread]) + AC_CHECK_LIB(osipparser2${osip_legacy_version},osip_message_init, , AC_MSG_ERROR([Could not find osipparser2 library !]),[-lpthread]) +dnl AC_CHECK_LIB adds osip2 & osipparser2 to LIBS + OSIP_LIBS=$LIBS + LDFLAGS=$LDFLAGS_save + LIBS=$LIBS_save +fi + +AC_SUBST(OSIP_CFLAGS) +AC_SUBST(OSIP_LIBS) + +]) diff --git a/linphone/m4/po.m4 b/linphone/m4/po.m4 new file mode 100644 index 000000000..00133ef36 --- /dev/null +++ b/linphone/m4/po.m4 @@ -0,0 +1,428 @@ +# po.m4 serial 13 (gettext-0.15) +dnl Copyright (C) 1995-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ(2.50) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + AC_REQUIRE([AM_NLS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; + *) MSGFMT_015=$MSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([MSGFMT_015]) +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Installation directories. + dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we + dnl have to define it here, so that it can be used in po/Makefile. + test -n "$localedir" || localedir='${datadir}/locale' + AC_SUBST([localedir]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat < "$ac_file.tmp" + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" < /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" < +#include +/* The string "%2$d %1$d", with dollar characters protected from the shell's + dollar expansion (possibly an autoconf bug). */ +static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; +static char buf[100]; +int main () +{ + sprintf (buf, format, 33, 55); + return (strcmp (buf, "55 33") != 0); +}], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no, + [ + AC_EGREP_CPP(notposix, [ +#if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ + notposix +#endif + ], gt_cv_func_printf_posix="guessing no", + gt_cv_func_printf_posix="guessing yes") + ]) + ]) + case $gt_cv_func_printf_posix in + *yes) + AC_DEFINE(HAVE_POSIX_PRINTF, 1, + [Define if your printf() function supports format strings with positions.]) + ;; + esac +]) diff --git a/linphone/m4/progtest.m4 b/linphone/m4/progtest.m4 new file mode 100644 index 000000000..a56365cd3 --- /dev/null +++ b/linphone/m4/progtest.m4 @@ -0,0 +1,92 @@ +# progtest.m4 serial 4 (gettext-0.14.2) +dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +AC_PREREQ(2.50) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) diff --git a/linphone/m4/readline.m4 b/linphone/m4/readline.m4 new file mode 100644 index 000000000..5293048ab --- /dev/null +++ b/linphone/m4/readline.m4 @@ -0,0 +1,37 @@ +################################################## +# Check for readline support. +################################################## + +AC_DEFUN([LP_CHECK_READLINE],[ + +AC_ARG_WITH( readline, + [ --with-readline Set prefix where gnu readline headers and libs can be found (ex:/usr, /usr/local) [default=/usr] ], + [ readline_prefix=${withval}],[ readline_prefix="/usr" ]) + +if test "$readline_prefix" != "/usr"; then + READLINE_CFLAGS="-I$readline_prefix/include" + READLINE_LIBS="-L$readline_prefix/lib" +fi + +CPPFLAGS_save=$CPPFLAGS +LIBS_save=$LIBS +CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" +LIBS="$LIBS $READLINE_LIBS" +AC_CHECK_HEADERS(readline.h readline/readline.h, readline_h_found=yes) +AC_CHECK_HEADERS(history.h readline/history.h) + +AC_CHECK_LIB(readline, readline, [readline_libs_found=yes],[],[-lncurses]) + +LIBS=$LIBS_save +CPPFLAGS=$CPPFLAGS_save + +if test "$readline_libs_found$readline_h_found" != "yesyes" ; then + AC_MSG_ERROR("Could not find libreadline headers or library") +fi + +READLINE_LIBS="$READLINE_LIBS -lreadline -lncurses" + + +AC_SUBST(READLINE_CFLAGS) +AC_SUBST(READLINE_LIBS) +]) diff --git a/linphone/m4/signed.m4 b/linphone/m4/signed.m4 new file mode 100644 index 000000000..048f59369 --- /dev/null +++ b/linphone/m4/signed.m4 @@ -0,0 +1,17 @@ +# signed.m4 serial 1 (gettext-0.10.40) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([bh_C_SIGNED], +[ + AC_CACHE_CHECK([for signed], bh_cv_c_signed, + [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) + if test $bh_cv_c_signed = no; then + AC_DEFINE(signed, , + [Define to empty if the C compiler doesn't support this keyword.]) + fi +]) diff --git a/linphone/m4/size_max.m4 b/linphone/m4/size_max.m4 new file mode 100644 index 000000000..bfba811eb --- /dev/null +++ b/linphone/m4/size_max.m4 @@ -0,0 +1,62 @@ +# size_max.m4 serial 5 +dnl Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_SIZE_MAX], +[ + AC_CHECK_HEADERS(stdint.h) + dnl First test whether the system already has SIZE_MAX. + AC_MSG_CHECKING([for SIZE_MAX]) + AC_CACHE_VAL([gl_cv_size_max], [ + gl_cv_size_max= + AC_EGREP_CPP([Found it], [ +#include +#if HAVE_STDINT_H +#include +#endif +#ifdef SIZE_MAX +Found it +#endif +], gl_cv_size_max=yes) + if test -z "$gl_cv_size_max"; then + dnl Define it ourselves. Here we assume that the type 'size_t' is not wider + dnl than the type 'unsigned long'. Try hard to find a definition that can + dnl be used in a preprocessor #if, i.e. doesn't contain a cast. + _AC_COMPUTE_INT([sizeof (size_t) * CHAR_BIT - 1], size_t_bits_minus_1, + [#include +#include ], size_t_bits_minus_1=) + _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, + [#include ], fits_in_uint=) + if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then + if test $fits_in_uint = 1; then + dnl Even though SIZE_MAX fits in an unsigned int, it must be of type + dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. + AC_TRY_COMPILE([#include + extern size_t foo; + extern unsigned long foo; + ], [], fits_in_uint=0) + fi + dnl We cannot use 'expr' to simplify this expression, because 'expr' + dnl works only with 'long' integers in the host environment, while we + dnl might be cross-compiling from a 32-bit platform to a 64-bit platform. + if test $fits_in_uint = 1; then + gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" + else + gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" + fi + else + dnl Shouldn't happen, but who knows... + gl_cv_size_max='((size_t)~(size_t)0)' + fi + fi + ]) + AC_MSG_RESULT([$gl_cv_size_max]) + if test "$gl_cv_size_max" != yes; then + AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max], + [Define as the maximum value of type 'size_t', if the system doesn't define it.]) + fi +]) diff --git a/linphone/m4/stdint_h.m4 b/linphone/m4/stdint_h.m4 new file mode 100644 index 000000000..db9a8ac4c --- /dev/null +++ b/linphone/m4/stdint_h.m4 @@ -0,0 +1,26 @@ +# stdint_h.m4 serial 6 +dnl Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], gl_cv_header_stdint_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1; return !i;], + gl_cv_header_stdint_h=yes, + gl_cv_header_stdint_h=no)]) + if test $gl_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/linphone/m4/uintmax_t.m4 b/linphone/m4/uintmax_t.m4 new file mode 100644 index 000000000..bf83ed746 --- /dev/null +++ b/linphone/m4/uintmax_t.m4 @@ -0,0 +1,30 @@ +# uintmax_t.m4 serial 9 +dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +AC_PREREQ(2.13) + +# Define uintmax_t to 'unsigned long' or 'unsigned long long' +# if it is not already defined in or . + +AC_DEFUN([gl_AC_TYPE_UINTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then + AC_REQUIRE([gl_AC_TYPE_UNSIGNED_LONG_LONG]) + test $ac_cv_type_unsigned_long_long = yes \ + && ac_type='unsigned long long' \ + || ac_type='unsigned long' + AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, + [Define to unsigned long or unsigned long long + if and don't define.]) + else + AC_DEFINE(HAVE_UINTMAX_T, 1, + [Define if you have the 'uintmax_t' type in or .]) + fi +]) diff --git a/linphone/m4/ulonglong.m4 b/linphone/m4/ulonglong.m4 new file mode 100644 index 000000000..9fae98e3a --- /dev/null +++ b/linphone/m4/ulonglong.m4 @@ -0,0 +1,48 @@ +# ulonglong.m4 serial 6 +dnl Copyright (C) 1999-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.60, but can be removed once we +# assume 2.61 everywhere. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[unsigned long long int ull = 18446744073709551615ULL; + typedef int a[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[unsigned long long int ullmax = 18446744073709551615ull; + return (ull << 63 | ull >> 63 | ull << i | ull >> i + | ullmax / ull | ullmax % ull);]])], + [ac_cv_type_unsigned_long_long_int=yes], + [ac_cv_type_unsigned_long_long_int=no])]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `unsigned long long int'.]) + fi +]) + +# This macro is obsolescent and should go away soon. +AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG], +[ + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + ac_cv_type_unsigned_long_long=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_unsigned_long_long = yes; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, + [Define if you have the 'unsigned long long' type.]) + fi +]) diff --git a/linphone/m4/video.m4 b/linphone/m4/video.m4 new file mode 100644 index 000000000..73cdf9fdc --- /dev/null +++ b/linphone/m4/video.m4 @@ -0,0 +1,89 @@ +AC_DEFUN([LP_CHECK_DEP],[ + dnl $1=dependency description + dnl $2=dependency short name, will be suffixed with _CFLAGS and _LIBS + dnl $3=headers's place + dnl $4=lib's place + dnl $5=header to check + dnl $6=lib to check + dnl $7=function to check in library + + NAME=$2 + dep_headersdir=$3 + dep_libsdir=$4 + dep_header=$5 + dep_lib=$6 + dep_funclib=$7 + other_libs=$8 + + if test "$dep_headersdir" != "/usr/include" ; then + eval ${NAME}_CFLAGS=\"-I$dep_headersdir \" + fi + eval ${NAME}_LIBS=\"-L$dep_libsdir -l$dep_lib\" + + CPPFLAGS_save=$CPPFLAGS + LDFLAGS_save=$LDFLAGS + CPPFLAGS="-I$dep_headersdir " + LDFLAGS="-L$dep_libsdir " + + AC_CHECK_HEADERS([$dep_header],[AC_CHECK_LIB([$dep_lib],[$dep_funclib],found=yes,found=no, [$other_libs]) + ],found=no) + + if test "$found" = "yes" ; then + eval ${NAME}_found=yes + AC_DEFINE([HAVE_${NAME}],1,[Defined when we have found $1]) + AC_SUBST(${NAME}_CFLAGS) + AC_SUBST(${NAME}_LIBS) + else + eval ${NAME}_found=no + eval ${NAME}_CFLAGS= + eval ${NAME}_LIBS= + fi + CPPFLAGS=$CPPFLAGS_save + LDFLAGS=$LDFLAGS_save + +]) + + +AC_DEFUN([LP_CHECK_VIDEO],[ + + dnl conditionnal build of video support + AC_ARG_ENABLE(video, + [ --enable-video Turn on video support compiling: not functionnal for the moment], + [case "${enableval}" in + yes) video=true ;; + no) video=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-video) ;; + esac],[video=false]) + + AC_ARG_WITH( ffmpeg, + [ --with-ffmpeg Sets the installation prefix of ffmpeg, needed for video support. [default=/usr] ], + [ ffmpegdir=${withval}],[ ffmpegdir=/usr ]) + + AC_ARG_WITH( sdl, + [ --with-sdl Sets the installation prefix of libSDL, needed for video support. [default=/usr] ], + [ libsdldir=${withval}],[ libsdldir=/usr ]) + + if test "$video" = "true"; then + + dnl test for ffmpeg presence + dnl LP_CHECK_DEP([ffmpeg],[FFMPEG],[${ffmpegdir}/include/ffmpeg],[${ffmpegdir}/lib],[avcodec.h],[avcodec],[avcodec_init], [-lavutils -lm]) + dnl if test "$FFMPEG_found" = "no" ; then + dnl AC_MSG_ERROR([Could not find ffmpeg headers and library. This is mandatory for video support]) + dnl fi + PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 50.0.0 ], , [ AC_MSG_ERROR([Could not find ffmpeg headers and library. This is mandatory for video support]) ]) + + LP_CHECK_DEP([SDL],[SDL],[${libsdldir}/include],[${libsdldir}/lib],[SDL/SDL.h],[SDL],[SDL_Init]) + if test "$SDL_found" = "no" ; then + AC_MSG_ERROR([Could not find libsdl headers and library. This is mandatory for video support]) + fi + + VIDEO_CFLAGS=" $FFMPEG_CFLAGS $SDL_CFLAGS" + VIDEO_LIBS=" $FFMPEG_LIBS $SDL_LIBS" + + AC_DEFINE(VIDEO_ENABLED,1,[Set when video support is enabled]) + + fi + + AC_SUBST(VIDEO_CFLAGS) + AC_SUBST(VIDEO_LIBS) +]) diff --git a/linphone/m4/visibility.m4 b/linphone/m4/visibility.m4 new file mode 100644 index 000000000..2ff6330aa --- /dev/null +++ b/linphone/m4/visibility.m4 @@ -0,0 +1,52 @@ +# visibility.m4 serial 1 (gettext-0.15) +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL(gl_cv_cc_visibility, [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + AC_TRY_COMPILE( + [extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void);], + [], + gl_cv_cc_visibility=yes, + gl_cv_cc_visibility=no) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/linphone/m4/wchar_t.m4 b/linphone/m4/wchar_t.m4 new file mode 100644 index 000000000..cde2129a9 --- /dev/null +++ b/linphone/m4/wchar_t.m4 @@ -0,0 +1,20 @@ +# wchar_t.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether has the 'wchar_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WCHAR_T], +[ + AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, + [AC_TRY_COMPILE([#include + wchar_t foo = (wchar_t)'\0';], , + gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) + if test $gt_cv_c_wchar_t = yes; then + AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) + fi +]) diff --git a/linphone/m4/wint_t.m4 b/linphone/m4/wint_t.m4 new file mode 100644 index 000000000..b8fff9c86 --- /dev/null +++ b/linphone/m4/wint_t.m4 @@ -0,0 +1,20 @@ +# wint_t.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether has the 'wint_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WINT_T], +[ + AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, + [AC_TRY_COMPILE([#include + wint_t foo = (wchar_t)'\0';], , + gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) + if test $gt_cv_c_wint_t = yes; then + AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) + fi +]) diff --git a/linphone/m4/xsize.m4 b/linphone/m4/xsize.m4 new file mode 100644 index 000000000..85bb721e4 --- /dev/null +++ b/linphone/m4/xsize.m4 @@ -0,0 +1,13 @@ +# xsize.m4 serial 3 +dnl Copyright (C) 2003-2004 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_XSIZE], +[ + dnl Prerequisites of lib/xsize.h. + AC_REQUIRE([gl_SIZE_MAX]) + AC_REQUIRE([AC_C_INLINE]) + AC_CHECK_HEADERS(stdint.h) +]) diff --git a/linphone/make_exosip.sh b/linphone/make_exosip.sh new file mode 100755 index 000000000..bff5fa33f --- /dev/null +++ b/linphone/make_exosip.sh @@ -0,0 +1,22 @@ +#!/bin/sh +#this script pickups eXosip files usefull for linphone and put them into exosip/ . +if test -z $1 ; then + echo "make_exosip.sh " + exit 1 +fi + +exosip_src=$1 +for file in $exosip_src/src/*.c ; do + echo "processing $file ..." + sed -e 's/eXosip\/eXosip.h/eXosip.h/' -e 's/eXosip\/eXosip_cfg.h/eXosip_cfg.h/' $file > exosip/`basename $file` +done +for file in $exosip_src/src/*.h ; do + echo "processing $file ..." + sed -e 's/eXosip\/eXosip.h/eXosip.h/' -e 's/eXosip\/eXosip_cfg.h/eXosip_cfg.h/' $file > exosip/`basename $file` +done +for file in $exosip_src/include/eXosip/*.h ; do + echo "processing $file ..." + sed -e 's/eXosip\/eXosip.h/eXosip.h/' -e 's/eXosip\/eXosip_cfg.h/eXosip_cfg.h/' $file > exosip/`basename $file` +done + +echo "Finished !" diff --git a/linphone/media_api/.cvsignore b/linphone/media_api/.cvsignore new file mode 100644 index 000000000..e99558847 --- /dev/null +++ b/linphone/media_api/.cvsignore @@ -0,0 +1,3 @@ +.deps +Makefile +Makefile.in diff --git a/linphone/media_api/DESIGN.txt b/linphone/media_api/DESIGN.txt new file mode 100644 index 000000000..f7c9cfc1f --- /dev/null +++ b/linphone/media_api/DESIGN.txt @@ -0,0 +1,135 @@ +MEDIA API DESIGN DRAFT +********************** + + +The objective of the media_api is to construct and run the necessary +processing on audio and video data flows for a given call (two party call) or +conference. +The media_api must support calls where callmember can be remote as well +local hosted, in other words the media_api can be used inside linphone as +well as in sip conferencing server. The api must support multiples way of +getting media data: from disk, from rtp, from soundcard... +The media_api is object oriented in C, and is based on the mediastreamer library +to deal with audio or video signals, and on glib for types and usefull routines. + +The api must provide object and methods that describes the call, and then functions +that executes the processing (using the mediastreamer) that is necessary for the +call described. + +Proposed API: + +************************************************************************ +object: MediaFlow +This object reprensent a media that is shared between all members of the call, +for example voice. +methods: +MediaFlow *media_flow_new(char *id_string,gint type,gint duplex); +type can be FLOW_AUDIO, FLOW_VIDEO. +if duplex is 1, it means that the media flow is used by every member in both +receiving and sending mode. +id_string is just a string to identify the flow. + +void media_flow_destroy(MediaFlow *flow); +destructor + +************************************************************************** +object: CallMember +This object reprensent a member of a call. +methods: +CallMember *call_member_new(); + +gint call_member_setup_flow(CallMember *member, MediaFlow *flow, + char *rx_endpoint, char *tx_endpoint); + This is the most important function of the API. It describes the way each + call member receives and send a given media flow. + The MediaFlow "flow" is added to the list of flows used by the member "member". + rx_endpoint is a string that described how data is received by the call member. + It should be an url, for example "rtp://213.21.54.127:7080". In this case it + means that data will be received on port 7080 at ip address 213.21.54.127. + tx_endpoint is a string that described how data is sent by the call member. + The role of url is very important. They can be: + "rtp://213.21.54.127:7080" + "file://tmp/media.out" -a file on disk + "oss://0" -souncard 0 using oss api + "alsa://0" -soundcard 0 using alsa api. + In order to work, the call member must be part of a BasicCall, as well as + the flow must be part of the BasicCall too (using basic_call_add_flow()) + This function may (on the backend) create a MediaEndpoint object that stores + the rx_endpoint and tx_endpoint parameter. This object is added to: + -the list of MediaEndpoint maintained by the member (list per member) + -the list of MediaEndpoint maintained by the flow (list per flow) + + +************************************************************************** +object: BasicCall +This object handles simple calls (two party calls). It defines inside itself +two CallMember objects. +method: +BasicCall *basic_call_new(); + +CallMember *basic_call_get_member(BasicCall *call, gint member_number); + Returns a member of a BasicCall according to a number. + +void basic_call_add_flow(BasicCall *call, MediaFlow *flow); + Adds a flow to the call's list of flow. + +gint basic_call_start_flow(BasicCall *call, MediaFlow *flow); + This function construct the mediastreamer processing chain necessary to make + the call running, if not done, and runs it using ms_start() + +gint basic_call_stop_flow(BasicCall *call, MediaFlow *flow); + +gint basic_call_start_all_flows(BasicCall *call); + +void basic_call_destroy(BasicCall *call); + Destroy all data used by the call: call members, call flows. + +************************************************************************** +object: ConferenceCall +This object handles conference call (which are quite much complicated than basic +calls). But this object should have the same method as the BasicCall object. + +******************************************************************* + EXAMPLE +******************************************************************* + +Two party call between call member A on machine "linphone.org" and call member B on machine "home.com". +The media_api is running on "home.com". + + A (on linphone.org) B (on home.com) + +------>(send to rtp://home.com:7080 MSRTPReceiver------>Decode----->(send to oss:/0) + +------<(recv on rtp://linphone.org:7020 MSRTPSender<--------Encode<-----(read on oss://0) + +This is how to setup this call using the media_api: +BasicCall *call; +CallMember *memberA,*memberB; +MediaFlow *flow; + +/* create a basic call*/ +call=basic_call_new(); +/* get a pointer to the pre-define members of the call */ +memberA=basic_call_get_member(call,0); +memberB=basic_call_get_member(call,1); + +/* create a media flow */ +flow=media_flow_new("voice",FLOW_AUDIO,1); +/* tell that the flow is used by the call */ +basic_call_add_flow(call,flow); +/* tell how each member uses the flow (how is the interface ?)*/ +call_member_setup_flow(memberA,flow,"rtp://linphone.org:7020","rtp://home.com:7080"); +/* note: it is not efficient to do name resolution at this stage: that's why in reality numeric ip address +should be given instead of host name */ +call_member_setup_flow(memberB,flow,"oss://0","oss://0"); + +/* start the flow */ +basic_call_start_flow(call,flow); + +In case where the media api is running on another host called "toto" (in a media translator application for example), + the only thing that would change is the url given to memberB: tx="rtp://home.com:8820" for example and + rx="rtp://toto:9522". + +In the sipomatic application (the test application I use to test linphone (it answers to call and plays +a short annoucement)), I would write rx="file://path_to_annoucement.raw" and tx="file://dev/null" instead of +"oss://0". diff --git a/linphone/media_api/Makefile.am b/linphone/media_api/Makefile.am new file mode 100644 index 000000000..38dcf063f --- /dev/null +++ b/linphone/media_api/Makefile.am @@ -0,0 +1,31 @@ +## Process this file with automake to produce Makefile.in +if BUILD_MEDIA_API + +#the media_api library is the only one we have to build here +lib_LTLIBRARIES=libmedia_api.la + +#definition of the sources of libmedia_api +libmedia_api_la_SOURCES= basiccall.c callmember.c mediaflow.c + +# libmedia_api needs libmediastreamer +libmedia_api_la_LIBADD=$(top_srcdir)/mediastreamer/libmediastreamer.la + +#the media_api test program +bin_PROGRAMS=apitest + +apitest_SOURCES= apitest.c +# the test program links to libmedia_api +apitest_LDADD=libmedia_api.la + +endif + +DEFS=@DEFS@ @SOUNDDEFS@ -DDEBUG -DG_LOG_DOMAIN=\"MediaApi\" + +INCLUDES=-I$(top_srcdir)/mediastreamer \ + -I$(top_srcdir)/speex \ + -I$(top_srcdir)/gsmlib \ + $(ORTP_CFLAGS) \ + -I$(top_srcdir)/lpc10-1.5 \ + -I$(top_srcdir)/ffmpeg + + diff --git a/linphone/media_api/apitest.c b/linphone/media_api/apitest.c new file mode 100644 index 000000000..cd4ac9e33 --- /dev/null +++ b/linphone/media_api/apitest.c @@ -0,0 +1,36 @@ +#include "basiccall.h" +#include +static int flag = 1; +void stop(int sign){ + flag = 0; +} + + +int main(){ + BasicCall *call; + char *id; + CallMember *memberA, *memberB; + MediaFlow *flow, *flow1; + + signal(SIGINT, stop); + call = basic_call_new(); + memberA = basic_call_get_member(call,MemberA); + memberB = basic_call_get_member(call,MemberB); + + id = "test_voice"; + printf("\n"); + flow = media_flow_new(id, MEDIA_FLOW_VOICE); + + basic_call_add_flow(call, flow); + + call_member_setup_flow(memberA, flow, "file://temp", "oss://0"); + call_member_setup_flow(memberB, flow, "oss://0", "oss://0"); + + media_flow_setup_fd(flow, memberA, memberB, MEDIA_FLOW_HALF_DUPLEX); + basic_call_start_flow(call, flow); + + while(flag){ + sleep(1); + } + +} diff --git a/linphone/media_api/apitest.h b/linphone/media_api/apitest.h new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/media_api/basiccall.c b/linphone/media_api/basiccall.c new file mode 100644 index 000000000..8a0044754 --- /dev/null +++ b/linphone/media_api/basiccall.c @@ -0,0 +1,170 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "basiccall.h" +#include "../mediastreamer/mscodec.h" + +#define ONESYNC 10 +#define MULTISYNC 20 + +BasicCall *basic_call_new(){ + BasicCall *bc = (BasicCall*) g_malloc(sizeof(BasicCall)); + api_trace("basic_call_new: creating a basic call"); + bc->memberA = call_member_new("memberA"); + bc->memberB = call_member_new("memberB"); + return bc; +} + +CallMember *basic_call_get_member(BasicCall *call, int member_nu){ + api_trace("basic_call_get_member: called for %d",member_nu); + if(member_nu == MemberA){ + return call->memberA; + } + else if(member_nu == MemberB){ + return call->memberB; + } +} + +void basic_call_add_flow(BasicCall *call, MediaFlow *flow){ + api_trace("basic_call_add_flow: called for %s",flow->id); + call->flows = g_list_append( call->flows, flow); + return 1; +} + +int find_mediaflow(gconstpointer llist, gconstpointer flow){ + //MediaFlow *mf = (MediaFlow *) ((BasicCallFlow*)llist)->mediaFlow; + if(((MediaFlow*)flow)->id == ((MediaFlow*)llist)->id){ + return 0; + } + return 1; +} + +int basic_call_start_flow(BasicCall *call, MediaFlow *flow){ + int i=0; + int syncFlag=0; + int nFlowDirections; + MSSync *sync; + Members *source, *destination; + FlowDirections *fd; + GList *elem, *selem; + GList *snd_read = NULL, *snd_write = NULL, *filter = NULL; + + //Commented by Sharat + //This is initialized in media_api.c + //when should these functions be really called? + //ms_init(); + //ortp_init(); + + api_trace("basic_call_start_flow: called for flow %s", flow->id); + + elem = g_list_find_custom( call->flows, flow, &find_mediaflow); + if(elem == NULL){ + api_error("basic_call_start_flow: Called for unregistered mediaflow %s", flow->id); + } + + nFlowDirections = g_list_length(flow->flowDirections); + if(flow->type == MEDIA_FLOW_VOICE){ + syncFlag = ONESYNC; + sync = ms_timer_new(); + } + else{ + syncFlag = MULTISYNC; + } + + for(i=0;i< nFlowDirections; i++){ + + if(syncFlag == MULTISYNC){ + sync = ms_timer_new(); + } + fd = (FlowDirections*)g_list_nth_data(flow->flowDirections,i); + source = fd->source; + destination = fd->destination; + + media_flow_start_fd(fd, sync); + if(fd->type == MEDIA_FLOW_DUPLEX){ + switch(source->tx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_read = g_list_append(snd_read, fd->recv); + } + switch(destination->rx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_write = g_list_append(snd_write, fd->play); + } + + switch(destination->tx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_read = g_list_append(snd_read, fd->read); + } + + switch(source->rx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_write = g_list_append(snd_write, fd->send); + } + + } + else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){ + + switch(source->tx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_read = g_list_append(snd_read, fd->recv); + } + switch(destination->rx_endpoint->protocol){ + case MEDIA_ALSA: + case MEDIA_OSS: + snd_write = g_list_append(snd_write, fd->play); + } + } + if(syncFlag == MULTISYNC){ + flow->sync = g_list_append(flow->sync, sync); + } + } + if(syncFlag == ONESYNC){ + ms_start(sync); + flow->sync = g_list_append(flow->sync, sync); + } + if(syncFlag == MULTISYNC){ + selem = flow->sync; + while(selem != NULL){ + ms_start(selem->data); + selem = g_list_next(selem); + } + } + filter = snd_read; + while(filter != NULL){ + ms_sound_read_start(MS_SOUND_READ((MSFilter*)filter->data)); + filter = g_list_next(filter); + } + + filter = snd_write; + while(filter != NULL){ + ms_sound_write_start(MS_SOUND_WRITE((MSFilter*)filter->data)); + filter = g_list_next(filter); + } + return 1; +} + +int basic_call_stop_flow(BasicCall *call, MediaFlow *flow){ + +} diff --git a/linphone/media_api/basiccall.h b/linphone/media_api/basiccall.h new file mode 100644 index 000000000..2351faccc --- /dev/null +++ b/linphone/media_api/basiccall.h @@ -0,0 +1,51 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "common.h" +#include "mediaflow.h" +#include "callmember.h" + +//other includes required to be done here +#define MemberA 1 +#define MemberB 2 + + +struct _BasicCall{ + CallMember *memberA, *memberB; + GList *flows; //linked list of MediaFlows +}; + +typedef struct _BasicCall BasicCall; + + +BasicCall *basic_call_new(); + +CallMember *basic_call_get_member(BasicCall *call, int member_nu); + +void basic_call_add_flow(BasicCall *call, MediaFlow *flow); + +int basic_call_start_flow(BasicCall *call, MediaFlow *flow); + +int basic_call_stop_flow(BasicCall *call, MediaFlow *flow); + +int basic_call_start_all_flows(BasicCall *call); + +int basic_call_destroy(BasicCall *call); + diff --git a/linphone/media_api/callmember.c b/linphone/media_api/callmember.c new file mode 100644 index 000000000..643ba7b7c --- /dev/null +++ b/linphone/media_api/callmember.c @@ -0,0 +1,153 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include "common.h" +#include "callmember.h" +#include "mediaflow.h" + + +CallMember *call_member_new(char *name){ + CallMember *member = (CallMember*) g_malloc(sizeof(CallMember)); + api_trace("call_member_new: creating %s", name); + member->name = name; + member->flows = NULL; + member->profile = NULL; + return member; +} + +int call_member_set_rtp_profile(CallMember *member, RtpProfile *profile){ + member->profile = profile; + return 1; +} + +int call_member_setup_flow(CallMember *member, MediaFlow *flow, char* rx, char *tx){ + Members *mem = (Members*) g_malloc(sizeof(Members)); + Flows *flows = (Flows*) g_malloc(sizeof(Flows)); + api_trace("call_member_setup_flow: setting up flow for: CallMember->%s , MediaFlow->%s", member->name, flow->id); + mem->member = member; + mem->rx_endpoint = parse_end_point(rx); + mem->tx_endpoint = parse_end_point(tx); + flow->members = g_list_append(flow->members, mem); + + flows->flow = flow; + flows->rx_endpoint = parse_end_point(rx); + flows->tx_endpoint = parse_end_point(tx); + member->flows = g_list_append(member->flows, flows); + return 1; +} + +EndPoint *parse_end_point(char *endpoint){ + EndPoint *result = (EndPoint*) g_malloc(sizeof(EndPoint)); + int i=0,len1,len2,len, tlen; + char *str2, temp[30], *host_str; + //api_trace("parse_end_point: parsing %s\n", endpoint); + result->pt = -1; + while(1){ + str2 = (char*) strpbrk(endpoint, ":"); + if(str2 == NULL){ + str2 = (char*) strpbrk(endpoint, ";"); + if(str2 == NULL){ + len = strlen(endpoint); + } + else{ + len1 = strlen(endpoint); + len2 = strlen(str2); + len = len1-len2; + } + } + else{ + len1 = strlen(endpoint); + len2 = strlen(str2); + len = len1-len2; + } + strncpy(temp,endpoint,len); + temp[len] = '\0'; + tlen = strlen(temp); + if((tlen >= 2)&&(temp[0] == '/')&&(temp[1] == '/')){ + host_str = remove_slash(temp); + } + switch(i){ + case 0: if(strcmp(temp,"rtp")==0){ + result->protocol=MEDIA_RTP; + } + else if(strcmp(temp,"oss")==0){ + result->protocol=MEDIA_OSS; + } + else if(strcmp(temp,"alsa")==0){ + result->protocol=MEDIA_ALSA; + } + else if(strcmp(temp,"file")==0){ + result->protocol=MEDIA_FILE; + } + break; + case 1: if(result->protocol==MEDIA_FILE){ + result->file=host_str; + } + else{ + result->host = host_str; + } + break; + case 2: result->port = to_digits(temp); + break; + case 3: result->pt = pt_digits(temp); + break; + default://result->options[result->nOptions++] = temp; + break; + } + if(str2 != NULL) endpoint = str2+1; + else break; + i++; + } + return result; +} + +int to_digits(char *str){ + int nu=0,a,len,i; + len = strlen(str); + for(i=0;i3)&&(str[0]=='p')&&(str[1]=='t')&&(str[2]=='=')){ + return to_digits(str+3); + } + else{ + api_warn("Wrong parameters passed in the endpoints"); + return 0; + //ERROR handling + } +} +char *remove_slash(char var[]){ + char *temp = (char*) g_malloc(10*sizeof(char)); + int len,i; + len=strlen(var); + for(i=2;i + +#define api_trace g_message +#define api_error g_error +#define api_warn g_warning + +#define MEDIA_FLOW_DUPLEX 1 +#define MEDIA_FLOW_HALF_DUPLEX 2 + +//Mediaflow type +#define MEDIA_FLOW_VIDEO 1 +#define MEDIA_FLOW_VOICE 2 + +//Mediaflow protocols +#define MEDIA_RTP 1 +#define MEDIA_OSS 2 +#define MEDIA_ALSA 3 +#define MEDIA_FILE 4 + +//Mediaflow codec function +#define MEDIA_API_DECODER 1 +#define MEDIA_API_ENCODER 2 + +#endif + + diff --git a/linphone/media_api/media_api.c b/linphone/media_api/media_api.c new file mode 100644 index 000000000..28ed3c1a3 --- /dev/null +++ b/linphone/media_api/media_api.c @@ -0,0 +1,69 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "media_api.h" + +/* non-standart payload types for oRTP */ +PayloadType lpc1015={ + PAYLOAD_AUDIO_PACKETIZED, + 8000, + 0, + NULL, + 0, + 2400, + "1015/8000/1" +}; + +PayloadType speex_nb={ + PAYLOAD_AUDIO_PACKETIZED, + 8000, + 0, + NULL, + 0, + 15000, + "speex/8000/1" +}; + +PayloadType speex_nb_lbr={ + PAYLOAD_AUDIO_PACKETIZED, + 8000, + 0, + NULL, + 0, + 8000, + "speex-lbr/8000/1" +}; + +void media_api_init() +{ + ortp_init(); + ortp_set_debug_file("oRTP",NULL); + rtp_profile_set_payload(&av_profile,115,&lpc1015); + rtp_profile_set_payload(&av_profile,110,&speex_nb); + rtp_profile_set_payload(&av_profile,111,&speex_nb_lbr); + rtp_profile_set_payload(&av_profile,101,&telephone_event); + ms_init(); + ms_speex_codec_init(); +#ifdef HAVE_AVCODEC + ms_AVCodec_init(); +#endif +} + + diff --git a/linphone/media_api/media_api.h b/linphone/media_api/media_api.h new file mode 100644 index 000000000..b7341fc4a --- /dev/null +++ b/linphone/media_api/media_api.h @@ -0,0 +1,69 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MEDIA_API_H +#define MEDIA_API_H + +/* some mediastreamer include files....*/ + +#include "ms.h" + +/* audio codecs ; all these header are not really required as we should use ms_codec_new..() to +create codec filters*/ +/*Commented by Sharath Udupa +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BUILD_FFMPEG +#include +#include */ +#endif + +/* some usefull filters of the mediastreamer */ +#include "mscopy.h" +#include "msfdispatcher.h" +#include "msqdispatcher.h" + +/* some synchronisation sources */ +#include +#include + +/* some streams sources and sinks */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + + + diff --git a/linphone/media_api/mediaflow.c b/linphone/media_api/mediaflow.c new file mode 100644 index 000000000..8ccdadb71 --- /dev/null +++ b/linphone/media_api/mediaflow.c @@ -0,0 +1,179 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "common.h" +#include "mediaflow.h" +#include "callmember.h" + + +MediaFlow *media_flow_new(char *id_string, int type){ + MediaFlow *flow = (MediaFlow *) g_malloc(sizeof(MediaFlow)); //malloc required? + api_trace("media_flow_new: creating %s",id_string); + flow->id = id_string; + flow->type = type; + flow->flowDirections = NULL; + flow->members = NULL; + return flow; +} + +int media_flow_destroy(MediaFlow *flow){ + g_free(flow); + return 1; +} + +int media_flow_setup_fd(MediaFlow *flow, CallMember* csource, CallMember *cdestination, int direction){ + GList *source, *destination; + char *dir; + FlowDirections *fd = (FlowDirections *) g_malloc(sizeof(FlowDirections)); + if(direction == MEDIA_FLOW_DUPLEX) dir = "DUPLEX"; + else if(direction == MEDIA_FLOW_HALF_DUPLEX) dir = "HALF_DUPLEX"; + api_trace("media_flow_setup_fd: setting up %s flow for %s , %s",dir, csource->name, cdestination->name); + source = g_list_find_custom(flow->members, csource, &find); + destination =g_list_find_custom(flow->members, cdestination, &find); + if(source == NULL){ + api_error("media_flow_setup_fd: Invalid source %s specified", csource->name); + } + if(destination == NULL){ + api_error("media_flow_setup_fd: Invalid destination %s specified", cdestination->name); + //ERROR handling to be done here + } + fd->source = (Members*)source->data; + fd->destination = (Members*)destination->data; + fd->type = direction; + flow->flowDirections = g_list_append(flow->flowDirections, fd); + return 1; +} + +int find(gconstpointer mem, gconstpointer cmember){ + if(!strcmp(((Members*)mem)->member->name, ((CallMember*)cmember)->name)){ + return 0; + } + return 1; +} + +int media_flow_start_fd(FlowDirections *fd, MSSync *sync){ + Members *source, *destination; + source = fd->source; + destination = fd->destination; + if(fd->type == MEDIA_FLOW_DUPLEX){ + fd->recv = set_MSFilter(source->tx_endpoint,1,fd); + fd->dec = set_CODECFilter(source->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER); + fd->play = set_MSFilter(destination->rx_endpoint,0,fd); + + ms_filter_add_link(fd->recv,fd->dec); + ms_filter_add_link(fd->dec,fd->play); + ms_sync_attach(sync, fd->recv); + + fd->read = set_MSFilter(destination->tx_endpoint,1,fd); + fd->enc = set_CODECFilter(destination->member->profile, destination->tx_endpoint->pt,MEDIA_API_ENCODER); + fd->send = set_MSFilter(source->rx_endpoint,0,fd); + + ms_filter_add_link(fd->read, fd->enc); + ms_filter_add_link(fd->enc, fd->send); + ms_sync_attach(sync, fd->read); + + } + else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){ + + fd->recv = set_MSFilter(source->tx_endpoint,1,fd); + fd->dec = set_CODECFilter(sourcec->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER); + fd->play = set_MSFilter(destination->rx_endpoint,0,fd); + + ms_filter_add_link(fd->recv,fd->dec); + ms_filter_add_link(fd->dec,fd->play); + ms_sync_attach(sync, fd->recv); + } + return 1; +} + + +MSFilter *set_MSFilter(EndPoint *endpoint, int type, FlowDirections *fdir){ + MSFilter *filter; + RtpSession *rtps; + switch(endpoint->protocol){ + case MEDIA_RTP: + rtps = rtp_session_new(RTP_SESSION_RECVONLY); + rtp_session_set_local_addr(rtps,"0.0.0.0",8000); + rtp_session_set_scheduling_mode(rtps,0); + rtp_session_set_blocking_mode(rtps,0); + + if(type == 1){ + filter = ms_rtp_recv_new(); + ms_rtp_recv_set_session(MS_RTP_RECV(filter), rtps); + fdir->rtpSessions = g_list_append(fdir->rtpSessions, rtps); + return filter; + } + else{ + //ms_rtp_send_new + } + case MEDIA_OSS: + if(type == 1){ + filter = ms_oss_read_new(); + ms_sound_read_set_device(MS_SOUND_READ(filter),0); + return filter; + } + else{ + filter = ms_oss_write_new(); + ms_sound_write_set_device(MS_SOUND_WRITE(filter),0); + return filter; + } + case MEDIA_FILE: + if(type == 1){ + filter = ms_read_new(endpoint->file); + return filter; + } + if(type == 0){ + filter = ms_write_new(endpoint->file); + return filter; + } + + } +} + +MSFilter *set_CODECFilter(RtpProfile *profile, int pt, int mode){ + PayloadType *payload; + + switch(mode){ + case MEDIA_API_DECODER: + payload = rtp_profile_get_payload(profile, pt); + if(payload == NULL){ + api_error("media_api: undefined payload in URL\n"); + return NULL; + } + return ms_decoder_new_with_string_id(payload->mime_type); + + //Commented this to include the new RtpProfile + /*if(pt != -1) return ms_decoder_new_with_pt(pt); + *else return ms_copy_new(); + */ + case MEDIA_API_ENCODER: + + payload = rtp_profile_get_payload(profile, pt); + if(payload == NULL){ + api_error("media_api: undefined payload in URL\n"); + return NULL; + } + return ms_encoder_new_with_string_id(payload->mime_type); + /*if(pt != -1) return ms_encoder_new_with_pt(pt); + *else return ms_copy_new(); + */ + } +} + + diff --git a/linphone/media_api/mediaflow.h b/linphone/media_api/mediaflow.h new file mode 100644 index 000000000..598df4d98 --- /dev/null +++ b/linphone/media_api/mediaflow.h @@ -0,0 +1,68 @@ +/* + The objective of the media_api is to construct and run the necessary processing + on audio and video data flows for a given call (two party call) or conference. + Copyright (C) 2001 Sharath Udupa skuds@gmx.net + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a c:opy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +struct _MediaFlow{ + char *id; + int type; + GList *members; + GList *flowDirections; + GList *sync; //holds all the filters in this MediaFlow +}; + +typedef struct _MediaFlow MediaFlow; + +struct _Members{ + struct _CallMember *member; + struct _EndPoint *rx_endpoint; + struct _EndPoint *tx_endpoint; +}; + +typedef struct _Members Members; + +struct _FlowDirections{ + Members *source, *destination; + MSFilter *recv, + *dec, + *play; + MSFilter *read, //Filters used + *enc, //if type==DUPLEX + *send; + GList *rtpSessions; + int type; +}; + +typedef struct _FlowDirections FlowDirections; + + +MediaFlow *media_flow_new(char *id_string, int type); + +int media_flow_setup_fd(MediaFlow*, struct _CallMember *, struct _CallMember *, int); + +int media_flow_start_fd(FlowDirections *fd, MSSync *sync); + +int media_flow_destroy(MediaFlow *flow); + +/* Internal functions */ +int find(gconstpointer, gconstpointer); + +MSFilter *set_MSFilter(struct _EndPoint *, int, FlowDirections *); + +MSFilter *set_CODECFilter(RtpProfile* , int, int); + diff --git a/linphone/mediastreamer/.cvsignore b/linphone/mediastreamer/.cvsignore new file mode 100644 index 000000000..fd19c06ae --- /dev/null +++ b/linphone/mediastreamer/.cvsignore @@ -0,0 +1,16 @@ +*.lo +.deps +.libs +Makefile +Makefile.in +libmediastreamer.la +libmsspeex.la +mediastream +mstest +ring_test +test_alaw +test_gsm +test_lpc10 +test_mulaw +test_rtprecv +test_speex diff --git a/linphone/mediastreamer/Makefile.am b/linphone/mediastreamer/Makefile.am new file mode 100644 index 000000000..f472f0658 --- /dev/null +++ b/linphone/mediastreamer/Makefile.am @@ -0,0 +1,174 @@ +EXTRA_DIST=Makefile.ms + + +if BUILD_UGLIB +SUPPORTLIB=$(top_builddir)/support/libuglib.la +endif + + +#gdk video output +if BUILD_VIDEO +VIDEO_TESTPROGS=test_v4l test_videostream +#videoserver videoclient +endif + +if BUILD_TRUESPEECH + TRUESPEECH_SOURCES = mstruespeechencoder.c mstruespeechencoder.h \ + mstruespeechdecoder.c mstruespeechdecoder.h + TRUESPEECH_LIBADD = ../win32acm/libwin32acm.a + TRUESPEECH_TEST = test_truespeech + TRUESPEECH_INCLUDES = -I$(top_srcdir)/win32acm +endif + +if BUILD_MEDIASTREAMER + +noinst_LTLIBRARIES = libmediastreamer.la +endif + +useless_files=mstcpserv.c mstcpserv.h mstcpclient.c mstcpclient.h + +libmediastreamer_la_SOURCES=msfilter.c msfilter.h msutils.h waveheader.h\ + mscodec.c mscodec.h \ + mssoundread.c mssoundread.h \ + mssoundwrite.c mssoundwrite.h \ + msbuffer.c msbuffer.h \ + msqueue.c msqueue.h \ + msfifo.c msfifo.h \ + ms.c ms.h\ + mssync.c mssync.h \ + msnosync.c msnosync.h \ + msread.c msread.h \ + mswrite.c mswrite.h \ + mscopy.c mscopy.h \ + msosswrite.c msosswrite.h \ + msossread.c msossread.h \ + msringplayer.c msringplayer.h \ + msGSMencoder.c msGSMencoder.h \ + msGSMdecoder.c msGSMdecoder.h \ + msLPC10encoder.c msLPC10encoder.h \ + msLPC10decoder.c msLPC10decoder.h \ + msrtprecv.c msrtprecv.h \ + msrtpsend.c msrtpsend.h \ + msAlawenc.c msAlawenc.h g711common.h \ + msAlawdec.c msAlawdec.h g711common.h \ + msMUlawenc.c msMUlawenc.h g711common.h \ + msMUlawdec.c msMUlawdec.h g711common.h \ + mstimer.c mstimer.h \ + msqdispatcher.c msqdispatcher.h \ + msfdispatcher.c msfdispatcher.h \ + sndcard.c sndcard.h \ + osscard.c osscard.h\ + hpuxsndcard.c \ + alsacard.c alsacard.h \ + jackcard.c jackcard.h \ + audiostream.c mediastream.h \ + $(TRUESPEECH_SOURCES)\ + msspeexenc.c msspeexenc.h msspeexdec.c msspeexdec.h \ + $(VIDEO_SOURCES) + +if BUILD_VIDEO +libmediastreamer_la_SOURCES+=msv4l.c msv4l.h affine.c affine.h \ + msavencoder.c msavencoder.h\ + msavdecoder.c msavdecoder.h \ + videostream.c \ + msvideosource.c msvideosource.h \ + mssdlout.c mssdlout.h \ + rfc2429.h +endif + +libmediastreamer_la_LIBADD= $(GLIB_LIBS) \ + ../gsmlib/libgsm.la \ + ../lpc10-1.5/liblpc10.la \ + ../oRTP/src/libortp.la \ + $(JACK_LIBS)\ + $(SAMPLERATE_LIBS)\ + $(SUPPORTLIB) \ + $(ALSA_LIBS) \ + $(TRUESPEECH_LIBADD) \ + $(SPEEX_LIBS) \ + $(VIDEO_LIBS) + + + +if BUILD_MEDIASTREAMER +noinst_PROGRAMS=mstest ring_test test_gsm test_lpc10 test_alaw test_mulaw \ + test_speex \ + test_rtprecv \ + $(VIDEO_TESTPROGS) $(TRUESPEECH_TEST) + +libexec_PROGRAMS=mediastream +endif + + +# test program to test TrueSpeech encoder and decoder objects +test_truespeech_SOURCES=test_truespeech.c +test_truespeech_LDADD=libmediastreamer.la + +mstest_SOURCES=test.c +mstest_LDADD=libmediastreamer.la + +#test program to test MSRingPlayer object +ring_test_SOURCES=ring_test.c +ring_test_LDADD=libmediastreamer.la + +#test program to test GSM dec and enc objects +test_gsm_SOURCES=test_gsm.c +test_gsm_LDADD=libmediastreamer.la + +#test program to test speex dec and enc objects +test_speex_SOURCES=test_speex.c +test_speex_LDADD=libmediastreamer.la + +#test program to test LPC10-1.5 dec and enc objects +test_lpc10_SOURCES=test_lpc10.c +test_lpc10_LDADD=libmediastreamer.la + +#test program to test ALAW dec and enc objects +test_alaw_SOURCES=test_alaw.c +test_alaw_LDADD=libmediastreamer.la + +#test program to test MULAW dec and enc objects +test_mulaw_SOURCES=test_mulaw.c +test_mulaw_LDADD=libmediastreamer.la + + +#test program to test rtprecv object +test_rtprecv_SOURCES=test_rtprecv.c +test_rtprecv_LDADD=libmediastreamer.la + +#test program to test full video stream +test_videostream_SOURCES=test_videostream.c +test_videostream_LDADD=libmediastreamer.la + +#test program to test video4linux input plugin +test_v4l_SOURCES=test_v4l.c +test_v4l_LDADD=libmediastreamer.la + +#videoserver_SOURCES=videoserver.c +#videoserver_LDADD=libmediastreamer.la + +#videoclient_SOURCES=videoclient.c +#videoclient_LDADD=libmediastreamer.la + + +#the mediastream program that runs a processing that will be used in linphone +mediastream_SOURCES=mediastream.c +mediastream_LDADD=libmediastreamer.la + + +ORTP_CFLAGS=`cat $(top_builddir)/oRTP/ortp.defs` + +AM_CFLAGS=$(GLIB_CFLAGS) -DG_LOG_DOMAIN=\"MediaStreamer\" $(TRUESPEECH_CFLAGS) $(IPV6_CFLAGS) $(ORTP_CFLAGS) \ + $(VIDEO_CFLAGS) + +INCLUDES= -I$(top_srcdir) \ + -I$(top_srcdir)/mediastreamer \ + -I$(top_srcdir)/oRTP/include \ + -I$(top_srcdir)/gsmlib \ + -I$(top_srcdir)/lpc10-1.5 \ + $(SPEEX_CFLAGS) \ + $(TRUESPEECH_INCLUDES) + +linphone_includedir=$(includedir)/linphone + +linphone_include_HEADERS=sndcard.h diff --git a/linphone/mediastreamer/Makefile.ms b/linphone/mediastreamer/Makefile.ms new file mode 100644 index 000000000..8b7427c3c --- /dev/null +++ b/linphone/mediastreamer/Makefile.ms @@ -0,0 +1,34 @@ + +OBJEXT=o +AR = ar +RANLIB = ranlib +DEFS= -DG_LOG_DOMAIN=\"MediaStreamer\" +INCLUDES=-I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include/ \ + -I../gsmlib/ -I../lpc10-1.5 -I../oRTP +COMPILE= gcc $(DEFS) $(INCLUDES) +LIBTOOL=libtool +LDFLAGS=-L/usr/local/lib/ -lglib-1.3 -lgthread-1.3 -lpthread +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ + +libmediastreamer_a_OBJECTS = msfilter.$(OBJEXT) msbuffer.$(OBJEXT) \ +msqueue.$(OBJEXT) msfifo.$(OBJEXT) ms.$(OBJEXT) mssync.$(OBJEXT) \ +msnosync.$(OBJEXT) msread.$(OBJEXT) mswrite.$(OBJEXT) mscopy.$(OBJEXT) \ +msv4lsource.$(OBJEXT) msoss.$(OBJEXT) msosswrite.$(OBJEXT) \ +msossread.$(OBJEXT) msringplayer.$(OBJEXT) msGSMencoder.$(OBJEXT) \ +msGSMdecoder.$(OBJEXT) msLPC10encoder.$(OBJEXT) \ +msLPC10decoder.$(OBJEXT) + +all: libmediastreamer.a mstest + + +.c.o: + $(COMPILE) -c $< + +libmediastreamer.a: $(libmediastreamer_a_OBJECTS) + -rm -f libmediastreamer.a + $(AR) cru libmediastreamer.a $(libmediastreamer_a_OBJECTS) + $(RANLIB) libmediastreamer.a + + +mstest: test.o libmediastreamer.a + gcc -o mstest test.o libmediastreamer.a $(LDFLAGS) -Wl,-rpath /usr/local/lib diff --git a/linphone/mediastreamer/README b/linphone/mediastreamer/README new file mode 100644 index 000000000..1309f534b --- /dev/null +++ b/linphone/mediastreamer/README @@ -0,0 +1,3 @@ +Mediastreamer is the library that handle all media operations: rtp streaming +from file, from soundcard, with codec transcoding, and vice-versa;-). +And also video streaming in the future. diff --git a/linphone/mediastreamer/affine.c b/linphone/mediastreamer/affine.c new file mode 100644 index 000000000..99f33d782 --- /dev/null +++ b/linphone/mediastreamer/affine.c @@ -0,0 +1,144 @@ +/* + * affine.c -- Affine Transforms for 2d objects + * Copyright (C) 2002 Charles Yates + * Portions Copyright (C) 2003 Dan Dennedy + * ported from C++ to C + * wrote affine_scale() + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "affine.h" + +static inline void Multiply( affine_transform_t *this, affine_transform_t *that ) +{ + double output[2][2]; + register int i, j; + + for ( i = 0; i < 2; i ++ ) + for ( j = 0; j < 2; j ++ ) + output[ i ][ j ] = this->matrix[ i ][ 0 ] * that->matrix[ j ][ 0 ] + + this->matrix[ i ][ 1 ] * that->matrix[ j ][ 1 ]; + + this->matrix[ 0 ][ 0 ] = output[ 0 ][ 0 ]; + this->matrix[ 0 ][ 1 ] = output[ 0 ][ 1 ]; + this->matrix[ 1 ][ 0 ] = output[ 1 ][ 0 ]; + this->matrix[ 1 ][ 1 ] = output[ 1 ][ 1 ]; +} + +void affine_transform_init( affine_transform_t *this ) +{ + this->matrix[ 0 ][ 0 ] = 1; + this->matrix[ 0 ][ 1 ] = 0; + this->matrix[ 1 ][ 0 ] = 0; + this->matrix[ 1 ][ 1 ] = 1; +} + +// Rotate by a given angle +void affine_transform_rotate( affine_transform_t *this, double angle ) +{ + affine_transform_t affine; + affine.matrix[ 0 ][ 0 ] = cos( angle * M_PI / 180 ); + affine.matrix[ 0 ][ 1 ] = 0 - sin( angle * M_PI / 180 ); + affine.matrix[ 1 ][ 0 ] = sin( angle * M_PI / 180 ); + affine.matrix[ 1 ][ 1 ] = cos( angle * M_PI / 180 ); + Multiply( this, &affine ); +} + +// Shear by a given value +void affine_transform_shear( affine_transform_t *this, double shear ) +{ + affine_transform_t affine; + affine.matrix[ 0 ][ 0 ] = 1; + affine.matrix[ 0 ][ 1 ] = shear; + affine.matrix[ 1 ][ 0 ] = 0; + affine.matrix[ 1 ][ 1 ] = 1; + Multiply( this, &affine ); +} + +void affine_transform_scale( affine_transform_t *this, double sx, double sy ) +{ + affine_transform_t affine; + affine.matrix[ 0 ][ 0 ] = sx; + affine.matrix[ 0 ][ 1 ] = 0; + affine.matrix[ 1 ][ 0 ] = 0; + affine.matrix[ 1 ][ 1 ] = sy; + Multiply( this, &affine ); +} + +// Obtain the mapped x coordinate of the input +double affine_transform_mapx( affine_transform_t *this, int x, int y ) +{ + return this->matrix[0][0] * x + this->matrix[0][1] * y; +} + +// Obtain the mapped y coordinate of the input +double affine_transform_mapy( affine_transform_t *this, int x, int y ) +{ + return this->matrix[1][0] * x + this->matrix[1][1] * y; +} + +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +void affine_scale( const unsigned char *src, unsigned char *dest, int src_width, int src_height, int dest_width, int dest_height, int bpp ) +{ + affine_transform_t affine; + double scale_x = (double) dest_width / (double) src_width; + double scale_y = (double) dest_height / (double) src_height; + register unsigned char *d = dest; + register const unsigned char *s = src; + register int i, j, k, x, y; + + affine_transform_init( &affine ); + + if ( scale_x <= 1.0 && scale_y <= 1.0 ) + { + affine_transform_scale( &affine, scale_x, scale_y ); + + for( j = 0; j < src_height; j++ ) + for( i = 0; i < src_width; i++ ) + { + x = (int) ( affine_transform_mapx( &affine, i - src_width/2, j - src_height/2 ) ); + y = (int) ( affine_transform_mapy( &affine, i - src_width/2, j - src_height/2 ) ); + x += dest_width/2; + x = CLAMP( x, 0, dest_width); + y += dest_height/2; + y = CLAMP( y, 0, dest_height); + s = src + (j*src_width*bpp) + i*bpp; // + (bpp-1); + d = dest + y*dest_width*bpp + x*bpp; + for ( k = 0; k < bpp; k++ ) + *d++ = *s++; + } + } + else if ( scale_x > 1.0 && scale_y > 1.0 ) + { + affine_transform_scale( &affine, 1.0/scale_x, 1.0/scale_y ); + + for( y = 0; y < dest_height; y++ ) + for( x = 0; x < dest_width; x++ ) + { + i = (int) ( affine_transform_mapx( &affine, x - dest_width/2, y - dest_height/2 ) ); + j = (int) ( affine_transform_mapy( &affine, x - dest_width/2, y - dest_height/2 ) ); + i += src_width/2; + i = CLAMP( i, 0, dest_width); + j += src_height/2; + j = CLAMP( j, 0, dest_height); + s = src + (j*src_width*bpp) + i*bpp; // + (bpp-1); + d = dest + y*dest_width*bpp + x*bpp; + for ( k = 0; k < bpp; k++ ) + *d++ = *s++; + } + } +} diff --git a/linphone/mediastreamer/affine.h b/linphone/mediastreamer/affine.h new file mode 100644 index 000000000..620fdc9d3 --- /dev/null +++ b/linphone/mediastreamer/affine.h @@ -0,0 +1,43 @@ +/* + * affine.h -- Affine Transforms for 2d objects + * Copyright (C) 2002 Charles Yates + * Portions Copyright (C) 2003 Dan Dennedy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _AFFINE_H +#define _AFFINE_H + +#include + +/** Affine transforms for 2d image manipulation. Current provides shearing and + rotating support. +*/ + +typedef struct { + double matrix[2][2]; +} affine_transform_t; + +void affine_transform_init( affine_transform_t *this ); +void affine_transform_rotate( affine_transform_t *this, double angle ); +void affine_transform_shear( affine_transform_t *this, double shear ); +void affine_transform_scale( affine_transform_t *this, double sx, double sy ); +double affine_transform_mapx( affine_transform_t *this, int x, int y ); +double affine_transform_mapy( affine_transform_t *this, int x, int y ); +void affine_scale( const unsigned char *src, unsigned char *dest, int src_width, int src_height, int dest_width, int dest_height, int bpp ); + +#endif + diff --git a/linphone/mediastreamer/alsacard.c b/linphone/mediastreamer/alsacard.c new file mode 100644 index 000000000..03b88df75 --- /dev/null +++ b/linphone/mediastreamer/alsacard.c @@ -0,0 +1,653 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "alsacard.h" + +#ifdef HAVE_ALSA_ASOUNDLIB_H + +static gchar *over_pcmdev=NULL; + +#include "msossread.h" +#include "msosswrite.h" + +#include + +int __alsa_card_write(AlsaCard *obj,char *buf,int size); + +int alsa_set_params(AlsaCard *obj, int rw, int bits, int stereo, int rate) +{ + snd_pcm_hw_params_t *hwparams=NULL; + snd_pcm_sw_params_t *swparams=NULL; + snd_pcm_t *pcm_handle; + gint dir; + guint exact_uvalue; + gulong exact_ulvalue; + gint channels; +// gint fsize=0; + gint periods=8; + gint periodsize=256; + gint err; + int format; + + if (rw) { + pcm_handle=obj->write_handle; + } + else pcm_handle=obj->read_handle; + + /* Allocate the snd_pcm_hw_params_t structure on the stack. */ + snd_pcm_hw_params_alloca(&hwparams); + + /* Init hwparams with full configuration space */ + if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) { + g_warning("alsa_set_params: Cannot configure this PCM device.\n"); + return(-1); + } + + if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + g_warning("alsa_set_params: Error setting access.\n"); + return(-1); + } + /* Set sample format */ +#ifdef WORDS_BIGENDIAN + format=SND_PCM_FORMAT_S16_BE; +#else + format=SND_PCM_FORMAT_S16_LE; +#endif + if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) < 0) { + g_warning("alsa_set_params: Error setting format.\n"); + return(-1); + } + /* Set number of channels */ + if (stereo) channels=2; + else channels=1; + if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels) < 0) { + g_warning("alsa_set_params: Error setting channels.\n"); + return(-1); + } + /* Set sample rate. If the exact rate is not supported */ + /* by the hardware, use nearest possible rate. */ + exact_uvalue=rate; + dir=0; + if ((err=snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_uvalue, &dir))<0){ + g_warning("alsa_set_params: Error setting rate to %i:%s",rate,snd_strerror(err)); + return -1; + } + if (dir != 0) { + g_warning("alsa_set_params: The rate %d Hz is not supported by your hardware.\n " + "==> Using %d Hz instead.\n", rate, exact_uvalue); + } + /* choose greater period size when rate is high */ + periodsize=periodsize*(rate/8000); + + /* Set buffer size (in frames). The resulting latency is given by */ + /* latency = periodsize * periods / (rate * bytes_per_frame) */ + /* + fsize=periodsize * periods; + exact_value=fsize; + if ((err=snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams,&exact_value)) < 0) { + g_warning("alsa_set_params: Error setting buffer size:%s",snd_strerror(err)); + return(-1); + } + if (fsize!= exact_value) { + g_warning("alsa_set_params: The buffer size %d is not supported by your hardware.\n " + "==> Using %d instead.\n", fsize, exact_value); + } + */ + /* set period size */ + exact_ulvalue=periodsize; + dir=0; + if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &exact_ulvalue, &dir) < 0) { + g_warning("alsa_set_params: Error setting period size.\n"); + return(-1); + } + if (dir != 0) { + g_warning("alsa_set_params: The period size %d is not supported by your hardware.\n " + "==> Using %d instead.\n", periodsize, (int)exact_ulvalue); + } + periodsize=exact_ulvalue; + /* Set number of periods. Periods used to be called fragments. */ + exact_uvalue=periods; + dir=0; + if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &exact_uvalue, &dir) < 0) { + g_warning("alsa_set_params: Error setting periods.\n"); + return(-1); + } + if (dir != 0) { + g_warning("alsa_set_params: The number of periods %d is not supported by your hardware.\n " + "==> Using %d instead.\n", periods, exact_uvalue); + } + /* Apply HW parameter settings to */ + /* PCM device and prepare device */ + if ((err=snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { + g_warning("alsa_set_params: Error setting HW params:%s",snd_strerror(err)); + return(-1); + } + /*prepare sw params */ + if (rw){ + snd_pcm_sw_params_alloca(&swparams); + snd_pcm_sw_params_current(pcm_handle, swparams); + if ((err=snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,periodsize*2 ))<0){ + g_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err)); + return -1; + } + if ((err=snd_pcm_sw_params(pcm_handle, swparams))<0){ + g_warning("alsa_set_params: Error setting SW params:%s",snd_strerror(err)); + return(-1); + } + } + obj->frame_size=channels*(bits/8); + SND_CARD(obj)->bsize=periodsize*obj->frame_size; + //SND_CARD(obj)->bsize=4096; + obj->frames=periodsize; + g_message("alsa_set_params: blocksize=%i.",SND_CARD(obj)->bsize); + return SND_CARD(obj)->bsize; +} + +int alsa_card_open_r(AlsaCard *obj,int bits,int stereo,int rate) +{ + int bsize; + int err; + snd_pcm_t *pcm_handle; + gchar *pcmdev; + if (over_pcmdev!=NULL) pcmdev=over_pcmdev; + else pcmdev=obj->pcmdev; + + if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_CAPTURE,SND_PCM_NONBLOCK) < 0) { + g_warning("alsa_card_open_r: Error opening PCM device %s\n",obj->pcmdev ); + return -1; + } + g_return_val_if_fail(pcm_handle!=NULL,-1); + obj->read_handle=pcm_handle; + if ((bsize=alsa_set_params(obj,0,bits,stereo,rate))<0){ + snd_pcm_close(pcm_handle); + obj->read_handle=NULL; + return -1; + } + obj->readbuf=g_malloc0(bsize); + + err=snd_pcm_start(obj->read_handle); + if (err<0){ + g_warning("Cannot start read pcm: %s", snd_strerror(err)); + } + obj->readpos=0; + SND_CARD(obj)->bsize=bsize; + SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED; + return 0; +} + +int alsa_card_open_w(AlsaCard *obj,int bits,int stereo,int rate) +{ +// int err; + int bsize; + snd_pcm_t *pcm_handle; + gchar *pcmdev; + if (over_pcmdev!=NULL) pcmdev=over_pcmdev; + else pcmdev=obj->pcmdev; + + if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_PLAYBACK,SND_PCM_NONBLOCK) < 0) { + g_warning("alsa_card_open_w: Error opening PCM device %s\n", obj->pcmdev); + return -1; + } + obj->write_handle=pcm_handle; + if ((bsize=alsa_set_params(obj,1,bits,stereo,rate))<0){ + snd_pcm_close(pcm_handle); + obj->write_handle=NULL; + return -1; + } + obj->writebuf=g_malloc0(bsize); + + obj->writepos=0; + SND_CARD(obj)->bsize=bsize; + SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED; + return 0; +} + + +void alsa_card_set_blocking_mode(AlsaCard *obj, gboolean yesno){ + if (obj->read_handle!=NULL) snd_pcm_nonblock(obj->read_handle,!yesno); + if (obj->write_handle!=NULL) snd_pcm_nonblock(obj->write_handle,!yesno); +} + +void alsa_card_close_r(AlsaCard *obj) +{ + if (obj->read_handle!=NULL){ + snd_pcm_close(obj->read_handle); + obj->read_handle=NULL; + g_free(obj->readbuf); + obj->readbuf=NULL; + } +} + +void alsa_card_close_w(AlsaCard *obj) +{ + if (obj->write_handle!=NULL){ + snd_pcm_close(obj->write_handle); + obj->write_handle=NULL; + g_free(obj->writebuf); + obj->writebuf=NULL; + } +} + +int alsa_card_probe(AlsaCard *obj,int bits,int stereo,int rate) +{ + int ret; + ret=alsa_card_open_w(obj,bits,stereo,rate); + if (ret<0) return -1; + ret=SND_CARD(obj)->bsize; + alsa_card_close_w(obj); + return ret; +} + + +void alsa_card_destroy(AlsaCard *obj) +{ + snd_card_uninit(SND_CARD(obj)); + g_free(obj->pcmdev); + if (obj->readbuf!=0) g_free(obj->readbuf); + if (obj->writebuf!=0) g_free(obj->writebuf); +} + +gboolean alsa_card_can_read(AlsaCard *obj) +{ + int frames; + g_return_val_if_fail(obj->read_handle!=NULL,0); + if (obj->readpos!=0) return TRUE; + if ((frames=snd_pcm_avail_update(obj->read_handle)>=obj->frames)) return 1; + //g_message("frames=%i",frames); + return 0; +} + + + +int __alsa_card_read(AlsaCard *obj,char *buf,int bsize) +{ + int err; + sigset_t set; + sigemptyset(&set); + sigaddset(&set,SIGALRM); + sigprocmask(SIG_BLOCK,&set,NULL); + err=snd_pcm_readi(obj->read_handle,buf,bsize/obj->frame_size); + if (err<0) { + if (err!=-EPIPE){ + g_warning("alsa_card_read: snd_pcm_readi() failed:%s.",snd_strerror(err)); + } + snd_pcm_prepare(obj->read_handle); + err=snd_pcm_readi(obj->read_handle,buf,bsize/obj->frame_size); + if (err<0) g_warning("alsa_card_read: snd_pcm_readi() failed:%s.",snd_strerror(err)); + } + sigprocmask(SIG_UNBLOCK,&set,NULL); + return err*obj->frame_size; +} + +int alsa_card_read(AlsaCard *obj,char *buf,int size) +{ + int err; + gint bsize=SND_CARD(obj)->bsize; + g_return_val_if_fail(obj->read_handle!=NULL,-1); + if (sizereadpos,size); + + if (obj->readpos==0){ + err=__alsa_card_read(obj,obj->readbuf,bsize); + } + + memcpy(buf,&obj->readbuf[obj->readpos],canread); + obj->readpos+=canread; + if (obj->readpos>=bsize) obj->readpos=0; + return canread; + }else{ + err=__alsa_card_read(obj,buf,size); + return err; + } + +} + +int __alsa_card_write(AlsaCard *obj,char *buf,int size) +{ + int err; + sigset_t set; + sigemptyset(&set); + sigaddset(&set,SIGALRM); + sigprocmask(SIG_BLOCK,&set,NULL); + if ((err=snd_pcm_writei(obj->write_handle,buf,size/obj->frame_size))<0){ + if (err!=-EPIPE){ + g_warning("alsa_card_write: snd_pcm_writei() failed:%s.",snd_strerror(err)); + } + snd_pcm_prepare(obj->write_handle); + err=snd_pcm_writei(obj->write_handle,buf,size/obj->frame_size); + if (err<0) g_warning("alsa_card_write: Error writing sound buffer (size=%i):%s",size,snd_strerror(err)); + + } + sigprocmask(SIG_UNBLOCK,&set,NULL); + return err; +} + +int alsa_card_write(AlsaCard *obj,char *buf,int size){ + int err; + gint bsize=SND_CARD(obj)->bsize; + g_return_val_if_fail(obj->write_handle!=NULL,-1); + if (size!=bsize || obj->writepos!=0) + { + gint canwrite; + gint totalwrite=0; + + while(1){ + canwrite=MIN(bsize-obj->writepos,size); + if (canwrite==0) + break; + memcpy(&obj->writebuf[obj->writepos],buf,canwrite); + obj->writepos+=canwrite; + if (obj->writepos>=bsize){ + err=__alsa_card_write(obj,obj->writebuf,bsize); + obj->writepos=0; + } + size-=canwrite; + buf+=canwrite; + totalwrite+=canwrite; + } + return totalwrite; + + }else{ + return __alsa_card_write(obj,buf,bsize); + } +} + +snd_mixer_t *alsa_mixer_open(AlsaCard *obj){ + snd_mixer_t *mixer=NULL; + int err; + err=snd_mixer_open(&mixer,0); + if (err<0){ + g_warning("Could not open alsa mixer: %s",snd_strerror(err)); + return NULL; + } + if ((err = snd_mixer_attach (mixer, obj->mixdev)) < 0){ + g_warning("Could not attach mixer to card: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + if ((err = snd_mixer_selem_register (mixer, NULL, NULL)) < 0){ + g_warning("snd_mixer_selem_register: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + if ((err = snd_mixer_load (mixer)) < 0){ + g_warning("snd_mixer_load: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + obj->mixer=mixer; + return mixer; +} + +void alsa_mixer_close(AlsaCard *obj){ + snd_mixer_close(obj->mixer); + obj->mixer=NULL; +} + +typedef enum {CAPTURE, PLAYBACK, CAPTURE_SWITCH, PLAYBACK_SWITCH} MixerAction; + +static gint get_mixer_element(snd_mixer_t *mixer,const char *name, MixerAction action){ + long value=0; + const char *elemname; + snd_mixer_elem_t *elem; + int err; + long sndMixerPMin; + long sndMixerPMax; + long newvol; + elem=snd_mixer_first_elem(mixer); + while (elem!=NULL){ + elemname=snd_mixer_selem_get_name(elem); + //g_message("Found alsa mixer element %s.",elemname); + if (strcmp(elemname,name)==0){ + switch (action){ + case CAPTURE: + if (snd_mixer_selem_has_capture_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + err=snd_mixer_selem_get_capture_volume(elem,SND_MIXER_SCHN_UNKNOWN,&newvol); + newvol-=sndMixerPMin; + value=(100*newvol)/(sndMixerPMax-sndMixerPMin); + if (err<0) g_warning("Could not get capture volume for %s:%s",name,snd_strerror(err)); + //else g_message("Succesfully get capture level for %s.",elemname); + break; + } + break; + case PLAYBACK: + if (snd_mixer_selem_has_playback_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + err=snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_FRONT_LEFT,&newvol); + newvol-=sndMixerPMin; + value=(100*newvol)/(sndMixerPMax-sndMixerPMin); + if (err<0) g_warning("Could not get playback volume for %s:%s",name,snd_strerror(err)); + //else g_message("Succesfully get playback level for %s.",elemname); + break; + } + break; + case CAPTURE_SWITCH: + + break; + case PLAYBACK_SWITCH: + + break; + } + } + elem=snd_mixer_elem_next(elem); + } + + return value; +} + + +static void set_mixer_element(snd_mixer_t *mixer,const char *name, gint level,MixerAction action){ + const char *elemname; + snd_mixer_elem_t *elem; + long sndMixerPMin; + long sndMixerPMax; + long newvol; + + elem=snd_mixer_first_elem(mixer); + + while (elem!=NULL){ + elemname=snd_mixer_selem_get_name(elem); + //g_message("Found alsa mixer element %s.",elemname); + if (strcmp(elemname,name)==0){ + switch(action){ + case CAPTURE: + if (snd_mixer_selem_has_capture_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; + snd_mixer_selem_set_capture_volume_all(elem,newvol); + //g_message("Succesfully set capture level for %s.",elemname); + return; + } + break; + case PLAYBACK: + if (snd_mixer_selem_has_playback_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; + snd_mixer_selem_set_playback_volume_all(elem,newvol); + //g_message("Succesfully set playback level for %s.",elemname); + return; + } + break; + case CAPTURE_SWITCH: + if (snd_mixer_selem_has_capture_switch(elem)){ + snd_mixer_selem_set_capture_switch_all(elem,level); + //g_message("Succesfully set capture switch for %s.",elemname); + } + break; + case PLAYBACK_SWITCH: + if (snd_mixer_selem_has_playback_switch(elem)){ + snd_mixer_selem_set_playback_switch_all(elem,level); + //g_message("Succesfully set capture switch for %s.",elemname); + } + break; + + } + } + elem=snd_mixer_elem_next(elem); + } + + return ; +} + + +void alsa_card_set_level(AlsaCard *obj,gint way,gint a) +{ + snd_mixer_t *mixer; + mixer=alsa_mixer_open(obj); + if (mixer==NULL) return ; + switch(way){ + case SND_CARD_LEVEL_GENERAL: + set_mixer_element(mixer,"Master",a,PLAYBACK); + break; + case SND_CARD_LEVEL_INPUT: + set_mixer_element(mixer,"Capture",a,CAPTURE); + break; + case SND_CARD_LEVEL_OUTPUT: + set_mixer_element(mixer,"PCM",a,PLAYBACK); + break; + default: + g_warning("oss_card_set_level: unsupported command."); + } + alsa_mixer_close(obj); +} + +gint alsa_card_get_level(AlsaCard *obj,gint way) +{ + snd_mixer_t *mixer; + gint value = -1; + mixer=alsa_mixer_open(obj); + if (mixer==NULL) return 0; + switch(way){ + case SND_CARD_LEVEL_GENERAL: + value=get_mixer_element(mixer,"Master",PLAYBACK); + break; + case SND_CARD_LEVEL_INPUT: + value=get_mixer_element(mixer,"Capture",CAPTURE); + break; + case SND_CARD_LEVEL_OUTPUT: + value=get_mixer_element(mixer,"PCM",PLAYBACK); + break; + default: + g_warning("oss_card_set_level: unsupported command."); + } + alsa_mixer_close(obj); + return value; +} + +void alsa_card_set_source(AlsaCard *obj,int source) +{ + snd_mixer_t *mixer; + mixer=alsa_mixer_open(obj); + if (mixer==NULL) return; + switch (source){ + case 'm': + set_mixer_element(mixer,"Mic",1,CAPTURE_SWITCH); + set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); + break; + case 'l': + set_mixer_element(mixer,"Line",1,CAPTURE_SWITCH); + set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); + break; + } +} + +MSFilter *alsa_card_create_read_filter(AlsaCard *card) +{ + MSFilter *f=ms_oss_read_new(); + ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index); + return f; +} + +MSFilter *alsa_card_create_write_filter(AlsaCard *card) +{ + MSFilter *f=ms_oss_write_new(); + ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index); + return f; +} + + +SndCard * alsa_card_new(gint devid) +{ + AlsaCard * obj; + SndCard *base; + int err; + gchar *name=NULL; + + /* carefull: this is an alsalib call despite its name! */ + err=snd_card_get_name(devid,&name); + if (err<0) { + return NULL; + } + obj= g_new0(AlsaCard,1); + base= SND_CARD(obj); + snd_card_init(base); + + base->card_name=g_strdup_printf("%s (Advanced Linux Sound Architecture)",name); + base->_probe=(SndCardOpenFunc)alsa_card_probe; + base->_open_r=(SndCardOpenFunc)alsa_card_open_r; + base->_open_w=(SndCardOpenFunc)alsa_card_open_w; + base->_can_read=(SndCardPollFunc)alsa_card_can_read; + base->_set_blocking_mode=(SndCardSetBlockingModeFunc)alsa_card_set_blocking_mode; + base->_read=(SndCardIOFunc)alsa_card_read; + base->_write=(SndCardIOFunc)alsa_card_write; + base->_close_r=(SndCardCloseFunc)alsa_card_close_r; + base->_close_w=(SndCardCloseFunc)alsa_card_close_w; + base->_set_rec_source=(SndCardMixerSetRecSourceFunc)alsa_card_set_source; + base->_set_level=(SndCardMixerSetLevelFunc)alsa_card_set_level; + base->_get_level=(SndCardMixerGetLevelFunc)alsa_card_get_level; + base->_destroy=(SndCardDestroyFunc)alsa_card_destroy; + base->_create_read_filter=(SndCardCreateFilterFunc)alsa_card_create_read_filter; + base->_create_write_filter=(SndCardCreateFilterFunc)alsa_card_create_write_filter; + + + obj->pcmdev=g_strdup_printf("plughw:%i,0",devid); + obj->mixdev=g_strdup_printf("hw:%i",devid); + obj->readbuf=NULL; + obj->writebuf=NULL; + return base; +} + + +gint alsa_card_manager_init(SndCardManager *m, gint index) +{ + gint devindex; + gint found=0; + gchar *name=NULL; + for(devindex=0;indexcards[index]=alsa_card_new(devindex); + m->cards[index]->index=index; + found++; + index++; + } + } + return found; +} + +void alsa_card_manager_set_default_pcm_device(const gchar *pcmdev){ + if (over_pcmdev!=NULL){ + g_free(over_pcmdev); + } + over_pcmdev=g_strdup(pcmdev); +} + +#endif diff --git a/linphone/mediastreamer/alsacard.h b/linphone/mediastreamer/alsacard.h new file mode 100644 index 000000000..df3372fb9 --- /dev/null +++ b/linphone/mediastreamer/alsacard.h @@ -0,0 +1,50 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#ifdef HAVE_ALSA_ASOUNDLIB_H + +#include "sndcard.h" +#define ALSA_PCM_NEW_HW_PARAMS_API +#include +struct _AlsaCard +{ + SndCard parent; + gchar *pcmdev; + gchar *mixdev; + snd_pcm_t *read_handle; + snd_pcm_t *write_handle; + gint frame_size; + gint frames; + gchar *readbuf; + gint readpos; + gchar *writebuf; + gint writepos; + snd_mixer_t *mixer; +}; + +typedef struct _AlsaCard AlsaCard; + +SndCard *alsa_card_new(gint dev_id); +gint alsa_card_manager_init(SndCardManager *m, gint index); +void alsa_card_manager_set_default_pcm_device(const gchar *pcmdev); + +#endif diff --git a/linphone/mediastreamer/audiostream.c b/linphone/mediastreamer/audiostream.c new file mode 100644 index 000000000..f129b064a --- /dev/null +++ b/linphone/mediastreamer/audiostream.c @@ -0,0 +1,340 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mediastream.h" +#ifdef INET6 + #include + #include + #include +#endif + + +#define MAX_RTP_SIZE 1500 + +/* this code is not part of the library itself, it is part of the mediastream program */ +void audio_stream_free(AudioStream *stream) +{ + RtpSession *s; + RtpSession *destroyed=NULL; + if (stream->rtprecv!=NULL) { + s=ms_rtp_recv_get_session(MS_RTP_RECV(stream->rtprecv)); + if (s!=NULL){ + destroyed=s; + rtp_session_destroy(s); + } + ms_filter_destroy(stream->rtprecv); + } + if (stream->rtpsend!=NULL) { + s=ms_rtp_send_get_session(MS_RTP_SEND(stream->rtpsend)); + if (s!=NULL){ + if (s!=destroyed) + rtp_session_destroy(s); + } + ms_filter_destroy(stream->rtpsend); + } + if (stream->soundread!=NULL) ms_filter_destroy(stream->soundread); + if (stream->soundwrite!=NULL) ms_filter_destroy(stream->soundwrite); + if (stream->encoder!=NULL) ms_filter_destroy(stream->encoder); + if (stream->decoder!=NULL) ms_filter_destroy(stream->decoder); + if (stream->timer!=NULL) ms_sync_destroy(stream->timer); + g_free(stream); +} + +static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; + +static void on_dtmf_received(RtpSession *s,gint dtmf,gpointer user_data) +{ + AudioStream *stream=(AudioStream*)user_data; + if (dtmf>15){ + g_warning("Unsupported telephone-event type."); + return; + } + g_message("Receiving dtmf %c.",dtmf_tab[dtmf]); + if (stream!=NULL){ + if (strcmp(stream->soundwrite->klass->name,"OssWrite")==0) + ms_oss_write_play_dtmf(MS_OSS_WRITE(stream->soundwrite),dtmf_tab[dtmf]); + } +} + +static void on_timestamp_jump(RtpSession *s,guint32* ts, gpointer user_data) +{ + g_warning("The remote sip-phone has send data with a future timestamp: %u," + "resynchronising session.",*ts); + rtp_session_reset(s); +} + +static const char *ip4local="0.0.0.0"; +static const char *ip6local="::"; + +const char *get_local_addr_for(const char *remote) +{ + const char *ret; +#ifdef INET6 + struct addrinfo hints, *res0; + int err; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + err = getaddrinfo(remote,"8000", &hints, &res0); + if (err!=0) { + g_warning ("get_local_addr_for: %s", gai_strerror(err)); + return ip4local; + } + ret=(res0->ai_addr->sa_family==AF_INET6) ? ip6local : ip4local; + freeaddrinfo(res0); +#else + ret=ip4local; +#endif + return ret; +} + +void create_duplex_rtpsession(RtpProfile *profile, int locport,char *remip,int remport, + int payload,int jitt_comp, + RtpSession **recvsend){ + RtpSession *rtpr; + rtpr=rtp_session_new(RTP_SESSION_SENDRECV); + rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE); + rtp_session_set_profile(rtpr,profile); + rtp_session_set_local_addr(rtpr,get_local_addr_for(remip),locport); + if (remport>0) rtp_session_set_remote_addr(rtpr,remip,remport); + rtp_session_set_scheduling_mode(rtpr,0); + rtp_session_set_blocking_mode(rtpr,0); + rtp_session_set_payload_type(rtpr,payload); + rtp_session_set_jitter_compensation(rtpr,jitt_comp); + rtp_session_enable_adaptive_jitter_compensation(rtpr,TRUE); + /*rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)on_timestamp_jump,NULL);*/ + *recvsend=rtpr; +} + +void create_rtp_sessions(RtpProfile *profile, int locport,char *remip,int remport, + int payload,int jitt_comp, + RtpSession **recv, RtpSession **send){ + RtpSession *rtps,*rtpr; + /* creates two rtp filters to recv send streams (remote part)*/ + + rtps=rtp_session_new(RTP_SESSION_SENDONLY); + rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE); + rtp_session_set_profile(rtps,profile); +#ifdef INET6 + rtp_session_set_local_addr(rtps,"::",locport+2); +#else + rtp_session_set_local_addr(rtps,"0.0.0.0",locport+2); +#endif + rtp_session_set_remote_addr(rtps,remip,remport); + rtp_session_set_scheduling_mode(rtps,0); + rtp_session_set_blocking_mode(rtps,0); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + rtpr=rtp_session_new(RTP_SESSION_RECVONLY); + rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE); + rtp_session_set_profile(rtpr,profile); +#ifdef INET6 + rtp_session_set_local_addr(rtpr,"::",locport); +#else + rtp_session_set_local_addr(rtpr,"0.0.0.0",locport); +#endif + rtp_session_set_scheduling_mode(rtpr,0); + rtp_session_set_blocking_mode(rtpr,0); + rtp_session_set_send_payload_type(rtpr,payload); + rtp_session_set_recv_payload_type(rtpr,payload); + rtp_session_set_jitter_compensation(rtpr,jitt_comp); + rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)on_timestamp_jump,(unsigned long)NULL); + *recv=rtpr; + *send=rtps; + +} + + +AudioStream * audio_stream_start_full(RtpProfile *profile, int locport,char *remip,int remport, + int payload,int jitt_comp, gchar *infile, gchar *outfile, SndCard *playcard, SndCard *captcard) +{ + AudioStream *stream=g_new0(AudioStream,1); + RtpSession *rtps,*rtpr; + PayloadType *pt; + + //create_rtp_sessions(profile,locport,remip,remport,payload,jitt_comp,&rtpr,&rtps); + + create_duplex_rtpsession(profile,locport,remip,remport,payload,jitt_comp,&rtpr); + rtp_session_signal_connect(rtpr,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream); + rtps=rtpr; + + stream->rtpsend=ms_rtp_send_new(); + ms_rtp_send_set_session(MS_RTP_SEND(stream->rtpsend),rtps); + stream->rtprecv=ms_rtp_recv_new(); + ms_rtp_recv_set_session(MS_RTP_RECV(stream->rtprecv),rtpr); + + + /* creates the local part */ + if (infile==NULL) stream->soundread=snd_card_create_read_filter(captcard); + else stream->soundread=ms_read_new(infile); + if (outfile==NULL) stream->soundwrite=snd_card_create_write_filter(playcard); + else stream->soundwrite=ms_write_new(outfile); + + /* creates the couple of encoder/decoder */ + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + g_error("audiostream.c: undefined payload type."); + return NULL; + } + stream->encoder=ms_encoder_new_with_string_id(pt->mime_type); + stream->decoder=ms_decoder_new_with_string_id(pt->mime_type); + if ((stream->encoder==NULL) || (stream->decoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + audio_stream_free(stream); + g_error("mediastream.c: No decoder available for payload %i.",payload); + return NULL; + } + /* give the sound filters some properties */ + ms_filter_set_property(stream->soundread,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate); + ms_filter_set_property(stream->soundwrite,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate); + + /* give the encoder/decoder some parameters*/ + ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate); + ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_BITRATE,&pt->normal_bitrate); + ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_FREQ,&pt->clock_rate); + ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_BITRATE,&pt->normal_bitrate); + + ms_filter_set_property(stream->encoder,MS_FILTER_PROPERTY_FMTP, (void*)pt->send_fmtp); + ms_filter_set_property(stream->decoder,MS_FILTER_PROPERTY_FMTP,(void*)pt->recv_fmtp); + /* create the synchronisation source */ + stream->timer=ms_timer_new(); + + /* and then connect all */ + ms_filter_add_link(stream->soundread,stream->encoder); + ms_filter_add_link(stream->encoder,stream->rtpsend); + ms_filter_add_link(stream->rtprecv,stream->decoder); + ms_filter_add_link(stream->decoder,stream->soundwrite); + + ms_sync_attach(stream->timer,stream->soundread); + ms_sync_attach(stream->timer,stream->rtprecv); + + /* and start */ + ms_start(stream->timer); + + return stream; +} + +static int defcard=0; + +void audio_stream_set_default_card(int cardindex){ + defcard=cardindex; +} + +AudioStream * audio_stream_start_with_files(RtpProfile *prof,int locport,char *remip, + int remport,int profile,int jitt_comp,gchar *infile, gchar*outfile) +{ + return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,infile,outfile,NULL,NULL); +} + +AudioStream * audio_stream_start(RtpProfile *prof,int locport,char *remip,int remport,int profile,int jitt_comp) +{ + SndCard *sndcard; + sndcard=snd_card_manager_get_card(snd_card_manager,defcard); + return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,NULL,NULL,sndcard,sndcard); +} + +AudioStream *audio_stream_start_with_sndcards(RtpProfile *prof,int locport,char *remip,int remport,int profile,int jitt_comp,SndCard *playcard, SndCard *captcard) +{ + g_return_val_if_fail(playcard!=NULL,NULL); + g_return_val_if_fail(captcard!=NULL,NULL); + return audio_stream_start_full(prof,locport,remip,remport,profile,jitt_comp,NULL,NULL,playcard,captcard); +} + +void audio_stream_set_rtcp_information(AudioStream *st, const char *cname){ + if (st->send_session!=NULL){ + rtp_session_set_source_description(st->send_session,cname,NULL,NULL,NULL,NULL,"linphone-" LINPHONE_VERSION, + "This is free software (GPL) !"); + } +} + +void audio_stream_stop(AudioStream * stream) +{ + + ms_stop(stream->timer); + ortp_global_stats_display(); + ms_sync_detach(stream->timer,stream->soundread); + ms_sync_detach(stream->timer,stream->rtprecv); + + ms_filter_remove_links(stream->soundread,stream->encoder); + ms_filter_remove_links(stream->encoder,stream->rtpsend); + ms_filter_remove_links(stream->rtprecv,stream->decoder); + ms_filter_remove_links(stream->decoder,stream->soundwrite); + + audio_stream_free(stream); +} + +RingStream * ring_start(gchar *file,gint interval,SndCard *sndcard) +{ + return ring_start_with_cb(file,interval,sndcard,NULL,NULL); +} + +RingStream * ring_start_with_cb(gchar *file,gint interval,SndCard *sndcard, MSFilterNotifyFunc func,gpointer user_data) +{ + RingStream *stream; + int tmp; + g_return_val_if_fail(sndcard!=NULL,NULL); + stream=g_new0(RingStream,1); + stream->source=ms_ring_player_new(file,interval); + if (stream->source==NULL) { + g_warning("Could not create ring player. Probably the ring file (%s) does not exist.",file); + return NULL; + } + if (func!=NULL) ms_filter_set_notify_func(MS_FILTER(stream->source),func,user_data); + stream->sndwrite=snd_card_create_write_filter(sndcard); + ms_filter_get_property(stream->source,MS_FILTER_PROPERTY_FREQ,&tmp); + ms_filter_set_property(stream->sndwrite,MS_FILTER_PROPERTY_FREQ,&tmp); + ms_filter_get_property(stream->source,MS_FILTER_PROPERTY_CHANNELS,&tmp); + ms_filter_set_property(stream->sndwrite,MS_FILTER_PROPERTY_CHANNELS,&tmp); + stream->timer=ms_timer_new(); + ms_filter_add_link(stream->source,stream->sndwrite); + ms_sync_attach(stream->timer,stream->source); + ms_start(stream->timer); + return stream; +} + +void ring_stop(RingStream *stream) +{ + ms_stop(stream->timer); + ms_sync_detach(stream->timer,stream->source); + ms_sync_destroy(stream->timer); + ms_filter_remove_links(stream->source,stream->sndwrite); + ms_filter_destroy(stream->source); + ms_filter_destroy(stream->sndwrite); + g_free(stream); +} + +/* returns the latency in samples if the audio device with id dev_id is openable in full duplex mode, else 0 */ +gint test_audio_dev(int dev_id) +{ + gint err; + SndCard *sndcard=snd_card_manager_get_card(snd_card_manager,dev_id); + if (sndcard==NULL) return -1; + err=snd_card_probe(sndcard,16,0,8000); + return err; /* return latency in number of sample */ +} + +gint audio_stream_send_dtmf(AudioStream *stream, gchar dtmf) +{ + ms_rtp_send_dtmf(MS_RTP_SEND(stream->rtpsend), dtmf); + ms_oss_write_play_dtmf(MS_OSS_WRITE(stream->soundwrite),dtmf); + return 0; +} diff --git a/linphone/mediastreamer/g711common.h b/linphone/mediastreamer/g711common.h new file mode 100644 index 000000000..3f5ad16fd --- /dev/null +++ b/linphone/mediastreamer/g711common.h @@ -0,0 +1,171 @@ +/* + * PCM - A-Law conversion + * Copyright (c) 2000 by Abramo Bagnara + * + * Wrapper for linphone Codec class by Simon Morlat + */ + +static inline int val_seg(int val) +{ + int r = 0; + val >>= 7; + if (val & 0xf0) { + val >>= 4; + r += 4; + } + if (val & 0x0c) { + val >>= 2; + r += 2; + } + if (val & 0x02) + r += 1; + return r; +} + +/* + * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law + * + * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data. + * + * Linear Input Code Compressed Code + * ------------------------ --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +static inline unsigned char s16_to_alaw(int pcm_val) +{ + int mask; + int seg; + unsigned char aval; + + if (pcm_val >= 0) { + mask = 0xD5; + } else { + mask = 0x55; + pcm_val = -pcm_val; + if (pcm_val > 0x7fff) + pcm_val = 0x7fff; + } + + if (pcm_val < 256) + aval = pcm_val >> 4; + else { + /* Convert the scaled magnitude to segment number. */ + seg = val_seg(pcm_val); + aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f); + } + return aval ^ mask; +} + +/* + * alaw_to_s16() - Convert an A-law value to 16-bit linear PCM + * + */ +static inline int alaw_to_s16(unsigned char a_val) +{ + int t; + int seg; + + a_val ^= 0x55; + t = a_val & 0x7f; + if (t < 16) + t = (t << 4) + 8; + else { + seg = (t >> 4) & 0x07; + t = ((t & 0x0f) << 4) + 0x108; + t <<= seg -1; + } + return ((a_val & 0x80) ? t : -t); +} +/* + * s16_to_ulaw() - Convert a linear PCM value to u-law + * + * In order to simplify the encoding process, the original linear magnitude + * is biased by adding 33 which shifts the encoding range from (0 - 8158) to + * (33 - 8191). The result can be seen in the following encoding table: + * + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz + * + * Each biased linear code has a leading 1 which identifies the segment + * number. The value of the segment number is equal to 7 minus the number + * of leading 0's. The quantization interval is directly available as the + * four bits wxyz. * The trailing bits (a - h) are ignored. + * + * Ordinarily the complement of the resulting code word is used for + * transmission, and so the code word is complemented before it is returned. + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */ +{ + int mask; + int seg; + unsigned char uval; + + if (pcm_val < 0) { + pcm_val = 0x84 - pcm_val; + mask = 0x7f; + } else { + pcm_val += 0x84; + mask = 0xff; + } + if (pcm_val > 0x7fff) + pcm_val = 0x7fff; + + /* Convert the scaled magnitude to segment number. */ + seg = val_seg(pcm_val); + + /* + * Combine the sign, segment, quantization bits; + * and complement the code word. + */ + uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f); + return uval ^ mask; +} + +/* + * ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM + * + * First, a biased linear code is derived from the code word. An unbiased + * output can then be obtained by subtracting 33 from the biased code. + * + * Note that this function expects to be passed the complement of the + * original code word. This is in keeping with ISDN conventions. + */ +static inline int ulaw_to_s16(unsigned char u_val) +{ + int t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = ((u_val & 0x0f) << 3) + 0x84; + t <<= (u_val & 0x70) >> 4; + + return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84)); +} diff --git a/linphone/mediastreamer/hpuxsndcard.c b/linphone/mediastreamer/hpuxsndcard.c new file mode 100644 index 000000000..8210e29d7 --- /dev/null +++ b/linphone/mediastreamer/hpuxsndcard.c @@ -0,0 +1,301 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "sndcard.h" +#include "osscard.h" + +#ifdef HAVE_SYS_AUDIO_H +#include + + +#include "msossread.h" +#include "msosswrite.h" + +#include +#include + + +int hpuxsnd_open(HpuxSndCard *obj, int bits,int stereo, int rate) +{ + int fd; + int p=0,cond=0; + int i=0; + int min_size=0,blocksize=512; + /* do a quick non blocking open to be sure that we are not going to be blocked here + for the eternity */ + fd=open(obj->dev_name,O_RDWR|O_NONBLOCK); + if (fd<0) return -EWOULDBLOCK; + close(fd); + /* open the device */ + fd=open(obj->dev_name,O_RDWR); + + g_return_val_if_fail(fd>0,-errno); + + ioctl(fd,AUDIO_RESET,0); + ioctl(fd,AUDIO_SET_SAMPLE_RATE,rate); + ioctl(fd,AUDIO_SET_CHANNELS,stereo); + p=AUDIO_FORMAT_LINEAR16BIT; + ioctl(fd,AUDIO_SET_DATA_FORMAT,p); + /* ioctl(fd,AUDIO_GET_RXBUFSIZE,&min_size); does not work ? */ + min_size=2048; + + g_message("dsp blocksize is %i.",min_size); + obj->fd=fd; + obj->readpos=0; + obj->writepos=0; + SND_CARD(obj)->bits=bits; + SND_CARD(obj)->stereo=stereo; + SND_CARD(obj)->rate=rate; + SND_CARD(obj)->bsize=min_size; + return fd; +} + +int hpux_snd_card_probe(HpuxSndCard *obj,int bits,int stereo,int rate) +{ + return 2048; +} + + +int hpux_snd_card_open(HpuxSndCard *obj,int bits,int stereo,int rate) +{ + int fd; + obj->ref++; + if (obj->fd==0){ + fd=hpuxsnd_open(obj,bits,stereo,rate); + if (fd<0) { + obj->fd=0; + obj->ref--; + return -1; + } + } + SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED; + return 0; +} + +void hpux_snd_card_close(HpuxSndCard *obj) +{ + int i; + obj->ref--; + if (obj->ref==0) { + close(obj->fd); + obj->fd=0; + SND_CARD(obj)->flags&=~SND_CARD_FLAGS_OPENED; + + } +} + +void hpux_snd_card_destroy(HpuxSndCard *obj) +{ + snd_card_uninit(SND_CARD(obj)); + g_free(obj->dev_name); + g_free(obj->mixdev_name); +} + +gboolean hpux_snd_card_can_read(HpuxSndCard *obj) +{ + struct timeval tout={0,0}; + int err; + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(obj->fd,&fdset); + err=select(obj->fd+1,&fdset,NULL,NULL,&tout); + if (err>0) return TRUE; + else return FALSE; +} + +int hpux_snd_card_read(HpuxSndCard *obj,char *buf,int size) +{ + int err; + gint bsize=SND_CARD(obj)->bsize; + if (sizereadpos,size); + if (obj->readbuf==NULL) obj->readbuf=g_malloc0(bsize); + if (obj->readpos==0){ + err=read(obj->fd,obj->readbuf,bsize); + if (err<0) { + g_warning("hpux_snd_card_read: read() failed:%s.",strerror(errno)); + return -1; + } + } + + memcpy(buf,&obj->readbuf[obj->readpos],canread); + obj->readpos+=canread; + if (obj->readpos>=bsize) obj->readpos=0; + return canread; + }else{ + err=read(obj->fd,buf,size); + if (err<0) { + g_warning("hpux_snd_card_read: read-2() failed:%s.",strerror(errno)); + } + return err; + } + +} + +int hpux_snd_card_write(HpuxSndCard *obj,char *buf,int size) +{ + int err; + gint bsize=SND_CARD(obj)->bsize; + if (sizewritepos,size); + if (obj->writebuf==NULL) obj->writebuf=g_malloc0(bsize); + + memcpy(&obj->writebuf[obj->writepos],buf,canwrite); + obj->writepos+=canwrite; + if (obj->writepos>=bsize){ + err=write(obj->fd,obj->writebuf,bsize); + } + return canwrite; + }else{ + return write(obj->fd,buf,bsize); + } +} + +#define SND_CARD_LEVEL_TO_HPUX_LEVEL(a) (((a)*2) - 100) +#define HPUX_LEVEL_TO_SND_CARD_LEVEL(a) (((a)+200)/2) +void hpux_snd_card_set_level(HpuxSndCard *obj,gint way,gint a) +{ + struct audio_gain gain; + int error,mix_fd; + + g_return_if_fail(obj->mixdev_name!=NULL); + memset(&gain,0,sizeof(struct audio_gain)); + switch(way){ + case SND_CARD_LEVEL_GENERAL: + gain.cgain[0].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + gain.cgain[1].monitor_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + break; + case SND_CARD_LEVEL_INPUT: + gain.cgain[0].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + gain.cgain[1].receive_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + break; + case SND_CARD_LEVEL_OUTPUT: + gain.cgain[0].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + gain.cgain[1].transmit_gain=SND_CARD_LEVEL_TO_HPUX_LEVEL(a); + break; + default: + g_warning("hpux_snd_card_set_level: unsupported command."); + return; + } + gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT; + mix_fd = open(obj->mixdev_name, O_WRONLY); + g_return_if_fail(mix_fd>0); + error=ioctl(mix_fd,AUDIO_SET_GAINS,&gain); + if (error<0){ + g_warning("hpux_snd_card_set_level: Could not set gains: %s",strerror(errno)); + } + close(mix_fd); +} + +gint hpux_snd_card_get_level(HpuxSndCard *obj,gint way) +{ + struct audio_gain gain; + int p=0,mix_fd,error; + g_return_if_fail(obj->mixdev_name!=NULL); + + gain.channel_mask=AUDIO_CHANNEL_RIGHT|AUDIO_CHANNEL_LEFT; + mix_fd = open(obj->mixdev_name, O_RDONLY); + g_return_if_fail(mix_fd>0); + error=ioctl(mix_fd,AUDIO_GET_GAINS,&gain); + if (error<0){ + g_warning("hpux_snd_card_set_level: Could not get gains: %s",strerror(errno)); + } + close(mix_fd); + + switch(way){ + case SND_CARD_LEVEL_GENERAL: + p=gain.cgain[0].monitor_gain; + break; + case SND_CARD_LEVEL_INPUT: + p=gain.cgain[0].receive_gain; + break; + case SND_CARD_LEVEL_OUTPUT: + p=gain.cgain[0].transmit_gain; + break; + default: + g_warning("hpux_snd_card_get_level: unsupported command."); + return -1; + } + return HPUX_LEVEL_TO_SND_CARD_LEVEL(p); +} + +void hpux_snd_card_set_source(HpuxSndCard *obj,int source) +{ + gint p=0; + gint mix_fd; + gint error=0; + g_return_if_fail(obj->mixdev_name!=NULL); + + mix_fd=open("/dev/audio",O_WRONLY); + g_return_if_fail(mix_fd>0); + switch(source){ + case 'm': + error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_MIKE); + break; + case 'l': + error=ioctl(mix_fd,AUDIO_SET_INPUT,AUDIO_IN_LINE); + break; + default: + g_warning("hpux_snd_card_set_source: unsupported source."); + } + close(mix_fd); +} + +MSFilter *hpux_snd_card_create_read_filter(HpuxSndCard *card) +{ + MSFilter *f=ms_oss_read_new(); + ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index); + return f; +} + +MSFilter *hpux_snd_card_create_write_filter(HpuxSndCard *card) +{ + MSFilter *f=ms_oss_write_new(); + ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index); + return f; +} + + +SndCard * hpux_snd_card_new(char *devname, char *mixdev_name) +{ + HpuxSndCard * obj= g_new0(HpuxSndCard,1); + SndCard *base= SND_CARD(obj); + snd_card_init(base); + obj->dev_name=g_strdup(devname); + obj->mixdev_name=g_strdup( mixdev_name); + base->card_name=g_strdup(devname); + base->_probe=(SndCardOpenFunc)hpux_snd_card_probe; + base->_open_r=(SndCardOpenFunc)hpux_snd_card_open; + base->_open_w=(SndCardOpenFunc)hpux_snd_card_open; + base->_can_read=(SndCardPollFunc)hpux_snd_card_can_read; + base->_read=(SndCardIOFunc)hpux_snd_card_read; + base->_write=(SndCardIOFunc)hpux_snd_card_write; + base->_close_r=(SndCardCloseFunc)hpux_snd_card_close; + base->_close_w=(SndCardCloseFunc)hpux_snd_card_close; + base->_set_rec_source=(SndCardMixerSetRecSourceFunc)hpux_snd_card_set_source; + base->_set_level=(SndCardMixerSetLevelFunc)hpux_snd_card_set_level; + base->_get_level=(SndCardMixerGetLevelFunc)hpux_snd_card_get_level; + base->_destroy=(SndCardDestroyFunc)hpux_snd_card_destroy; + base->_create_read_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_read_filter; + base->_create_write_filter=(SndCardCreateFilterFunc)hpux_snd_card_create_write_filter; + return base; +} + +#endif diff --git a/linphone/mediastreamer/jackcard.c b/linphone/mediastreamer/jackcard.c new file mode 100644 index 000000000..b929cce9e --- /dev/null +++ b/linphone/mediastreamer/jackcard.c @@ -0,0 +1,574 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + JACK support + Copyright (C) 2004 Tobias Gehrig tobias@gehrig.tk +*/ + +#include "jackcard.h" + +#ifdef __JACK_ENABLED__ + +#include "msossread.h" +#include "msosswrite.h" + +#include + +#define READBUFFERSIZE 524288 +#define WRITEBUFFERSIZE 524288 +#define BSIZE 512 + +/** + * jack_shutdown: + * @arg: + * + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + * + */ +void +jack_shutdown (void *arg) +{ + JackCard* obj = (JackCard*) arg; + + obj->jack_running = FALSE; + obj->jack_active = FALSE; + obj->read.port = NULL; + if (obj->read.open) + obj->read.init = TRUE; + obj->write.port = NULL; + if (obj->write.open) + obj->write.init = TRUE; +} + +int samplerate(jack_nframes_t rate, void *arg) +{ + JackCard* obj = (JackCard*) arg; + int error; + + obj->rate = rate; + if (obj->read.open) { + obj->read.data.src_ratio = (double)obj->read.rate / (double)obj->rate; + obj->read.data.input_frames = (long)((double)obj->read.frames/obj->read.data.src_ratio); + g_free(obj->read.data.data_in); + obj->read.data.data_in = malloc(obj->read.data.input_frames*sizeof(float)); + if (obj->read.src_state) + if ((error = src_set_ratio(obj->read.src_state, obj->read.data.src_ratio)) != 0) + g_warning("Error while resetting the write samplerate: %s", src_strerror(error)); + } + if (obj->write.open) { + obj->write.data.src_ratio = (double)obj->rate / (double)obj->write.rate; + obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio); + g_free(obj->write.data.data_out); + obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float)); + if (obj->write.src_state) + if ((error = src_set_ratio(obj->write.src_state, obj->write.data.src_ratio)) != 0) + g_warning("Error while resetting the write samplerate: %s", src_strerror(error)); + } + return 0; +} + +/* + * The process callback for this JACK application. + * It is called by JACK at the appropriate times. + * @nframes : + * @arg : + */ +int +process (jack_nframes_t nframes, void *arg) +{ + JackCard* obj = (JackCard*) arg; + sample_t *out; + sample_t *in; + + if (obj->clear && !obj->write.can_process) { + out = (sample_t *) jack_port_get_buffer (obj->write.port, nframes); + memset (out, 0, nframes * sizeof(sample_t)); + obj->clear = FALSE; + } + + if (!obj->can_process) + return 0; + + if(obj->read.can_process) { + in = (sample_t *) jack_port_get_buffer (obj->read.port, nframes); + jack_ringbuffer_write (obj->read.buffer, (void *) in, sizeof(sample_t) * nframes); + } + + if (obj->write.can_process) { + out = (sample_t *) jack_port_get_buffer (obj->write.port, nframes); + memset (out, 0, nframes * sizeof(sample_t)); + if (obj->clear && jack_ringbuffer_read_space(obj->write.buffer) == 0) { + obj->write.can_process = FALSE; + if (!obj->read.open) + obj->can_process = FALSE; + obj->clear = FALSE; + return 0; + } + jack_ringbuffer_read (obj->write.buffer, (void *) out, sizeof(sample_t) * nframes); + } + return 0; +} + +int jack_init(JackCard* obj) +{ + char* client_name; + int error; + + if (!obj->jack_running) { + obj->client = NULL; + client_name = g_strdup_printf("linphone-%u", g_random_int()); + if ((obj->client = jack_client_new (client_name)) == NULL) { + g_warning("cannot create jack client"); + g_free(client_name); + return -1; + } + g_message("Found Jack Daemon"); + g_free(client_name); + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + jack_set_process_callback (obj->client, process, obj); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + jack_on_shutdown (obj->client, jack_shutdown, obj); + jack_set_sample_rate_callback (obj->client, samplerate, obj); + obj->rate = jack_get_sample_rate (obj->client); + if (obj->rate == 0) { + g_warning ("rate is 0???"); + if (jack_client_close(obj->client) != 0) + g_warning("could not close client"); + return -1; + } + obj->buffer_size = jack_get_buffer_size(obj->client); + obj->jack_running = TRUE; + } + + if (!obj->jack_active) { + if (jack_activate (obj->client)) { + g_warning("cannot activate jack client"); + return -1; + } else obj->jack_active = TRUE; + } + + if (obj->read.init) { + if (!obj->read.port && (obj->read.port = jack_port_register (obj->client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))==NULL) { + g_warning("error while trying to register input port"); + return -1; + } + if (!obj->read.phys_ports && (obj->read.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) { + g_warning("Cannot find any physical capture ports\n"); + jack_port_unregister(obj->client, obj->read.port); + obj->read.port = NULL; + return -1; + } + if (!jack_port_connected(obj->read.port)) + if ((error = jack_connect (obj->client, obj->read.phys_ports[0], jack_port_name (obj->read.port))) != 0) { + g_warning("cannot connect input ports: %s -> %s\n", jack_port_name (obj->read.port), obj->read.phys_ports[0]); + if (error == EEXIST) g_warning("connection already made"); + else { + jack_port_unregister(obj->client, obj->read.port); + obj->read.port = NULL; + return -1; + } + } + obj->read.init = FALSE; + } + + if (obj->write.init) { + if (!obj->write.port && (obj->write.port = jack_port_register (obj->client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0))==NULL) { + g_warning("error while trying to register output port"); + return -1; + } + if (!obj->write.phys_ports && (obj->write.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { + g_warning("Cannot find any physical playback ports\n"); + jack_port_unregister(obj->client, obj->write.port); + obj->write.port = NULL; + return -1; + } + if (!jack_port_connected(obj->write.port)) { + if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[0])) != 0) { + g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[0]); + if (error == EEXIST) g_warning("connection already made"); + else { + jack_port_unregister(obj->client, obj->write.port); + obj->write.port = NULL; + return -1; + } + } + if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[1])) != 0) { + g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[1]); + if (error == EEXIST) g_warning("connection already made"); + else { + jack_port_unregister(obj->client, obj->write.port); + obj->write.port = NULL; + return -1; + } + } + } + obj->write.init = FALSE; + } + return 0; +} + +int jack_card_open_r(JackCard *obj,int bits,int stereo,int rate) +{ + int channels = stereo + 1, bsize, error; + obj->read.init = TRUE; + if (jack_init(obj) != 0) return -1; + + obj->read.rate = rate; + obj->sample_size = bits / 8; + obj->frame_size = channels * obj->sample_size; + bsize = BSIZE; + obj->read.frames = bsize / 2; + SND_CARD(obj)->bsize = bsize; + SND_CARD(obj)->flags |= SND_CARD_FLAGS_OPENED; + obj->read.channels = channels; + if ((obj->read.src_state = src_new (SRC_SINC_FASTEST, channels, &error)) == NULL) + g_warning("Error while initializing the samplerate converter: %s", src_strerror(error)); + obj->read.data.src_ratio = (double)rate / (double)obj->rate; + obj->read.data.input_frames = (long)((double)obj->read.frames/obj->read.data.src_ratio); + obj->read.data.data_in = malloc(obj->read.data.input_frames*sizeof(float)); + obj->read.data.data_out = malloc(obj->read.frames*sizeof(float)); + obj->read.data.end_of_input = 0; + if (!obj->read.buffer) + obj->read.buffer = jack_ringbuffer_create(READBUFFERSIZE); + obj->read.can_process = TRUE; + obj->can_process = TRUE; + obj->read.open = TRUE; + obj->read.init = FALSE; + return 0; +} + +int jack_card_open_w(JackCard *obj,int bits,int stereo,int rate) +{ + int channels = stereo + 1, bsize, err; + obj->write.init = TRUE; + if (jack_init(obj) != 0) return -1; + + obj->write.rate = rate; + obj->sample_size = bits / 8; + obj->frame_size = channels * obj->sample_size; + bsize = BSIZE; + obj->write.frames = bsize / 2; + SND_CARD(obj)->bsize = bsize; + SND_CARD(obj)->flags |= SND_CARD_FLAGS_OPENED; + obj->write.channels = channels; + if ((obj->write.src_state = src_new (SRC_SINC_FASTEST, channels, &err)) == NULL) + g_warning("Error while initializing the samplerate converter: %s", src_strerror(err)); + obj->write.data.src_ratio = (double)obj->rate / (double)rate; + obj->write.data.data_in = malloc(obj->write.frames*sizeof(float)); + obj->write.data.end_of_input = 0; + obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio); + obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float)); + if (!obj->write.buffer) + obj->write.buffer = jack_ringbuffer_create(WRITEBUFFERSIZE); + obj->write.can_process = TRUE; + obj->can_process = TRUE; + obj->write.open = TRUE; + obj->write.init = FALSE; + return 0; +} + +void jack_card_set_blocking_mode(JackCard *obj, gboolean yesno) +{ +} + +void jack_card_close_r(JackCard *obj) +{ + obj->read.open = FALSE; + obj->read.init = FALSE; + obj->read.can_process = FALSE; + if (!obj->write.open) + obj->can_process = FALSE; + if (obj->read.src_state) + obj->read.src_state = src_delete (obj->read.src_state); + g_free(obj->read.data.data_in); + g_free(obj->read.data.data_out); +} + +void jack_card_close_w(JackCard *obj) +{ + obj->write.open = FALSE; + obj->write.init = FALSE; + obj->clear = TRUE; + if (!obj->jack_running) { + obj->write.can_process = FALSE; + obj->can_process = FALSE; + } + if (obj->write.src_state) + obj->write.src_state = src_delete (obj->write.src_state); + g_free(obj->write.data.data_in); + g_free(obj->write.data.data_out); +} + +int jack_card_probe(JackCard *obj,int bits,int stereo,int rate) +{ + if (obj->jack_running) return BSIZE; + else if (jack_init(obj) == 0) return BSIZE; + else return -1; +} + +void jack_card_destroy(JackCard *obj) +{ + if (obj->jack_running) jack_client_close (obj->client); + snd_card_uninit(SND_CARD(obj)); + if (obj->read.buffer) { + jack_ringbuffer_free(obj->read.buffer); + obj->read.buffer = NULL; + } + if (obj->write.buffer) { + jack_ringbuffer_free(obj->write.buffer); + obj->write.buffer = NULL; + } + if (obj->read.phys_ports) { + g_free(obj->read.phys_ports); + obj->read.phys_ports = NULL; + } + if (obj->write.phys_ports) { + g_free(obj->write.phys_ports); + obj->write.phys_ports = NULL; + } +} + +gboolean jack_card_can_read(JackCard *obj) +{ + g_return_val_if_fail(obj->read.buffer!=NULL,0); + if (jack_ringbuffer_read_space(obj->read.buffer)>=(long)((double)obj->read.frames/obj->read.data.src_ratio)*sizeof(sample_t)) return TRUE; + else return FALSE; +} + +int jack_card_read(JackCard *obj,char *buf,int size) +{ + size_t bytes, can_read, i; + int error; + float norm, value; + + g_return_val_if_fail((obj->read.buffer!=NULL)&&(obj->read.src_state!=NULL),-1); + if (jack_init(obj) != 0) return -1; + size /= 2; + can_read = MIN(size, obj->read.frames); + // can_read = MIN(((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t), jack_ringbuffer_read_space(obj->read.buffer)); + can_read = ((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t); + obj->read.can_process = FALSE; + bytes = jack_ringbuffer_read (obj->read.buffer, (void *)obj->read.data.data_in, can_read); + obj->read.can_process = TRUE; + obj->read.data.input_frames = bytes / sizeof(sample_t); + can_read = MIN(size, obj->read.frames); + obj->read.data.output_frames = can_read; + if ((error = src_process(obj->read.src_state, &(obj->read.data))) != 0) + g_warning("error while samplerate conversion. error: %s", src_strerror(error)); + norm = obj->read.level*obj->level*(float)0x8000; + for (i=0; i < obj->read.data.output_frames_gen; i++) { + value = obj->read.data.data_out[i]*norm; + if (value >= 32767.0) + ((short*)buf)[i] = 32767; + else if (value <= -32768.0) + ((short*)buf)[i] = -32768; + else + ((short*)buf)[i] = (short)value; + } + bytes = obj->read.data.output_frames_gen * 2; + return bytes; +} + +int jack_card_write(JackCard *obj,char *buf,int size) +{ + size_t bytes, can_write, i; + int error; + float norm; + + g_return_val_if_fail((obj->write.buffer!=NULL)&&(obj->write.src_state!=NULL),-1); + if (jack_init(obj) != 0) return -1; + size /= 2; + can_write = MIN(size, obj->write.frames); + norm = obj->write.level*obj->level/(float)0x8000; + for (i=0; iwrite.data.data_in[i] = (float)((short*)buf)[i]*norm; + } + obj->write.data.input_frames = can_write; + if ((error = src_process(obj->write.src_state, &(obj->write.data))) != 0) + g_warning("error while samplerate conversion. error: %s", src_strerror(error)); + obj->write.can_process = FALSE; + bytes = jack_ringbuffer_write (obj->write.buffer, (void *) obj->write.data.data_out, sizeof(sample_t)*obj->write.data.output_frames_gen); + obj->write.can_process = TRUE; + return bytes; +} + +void jack_card_set_level(JackCard *obj,gint way,gint a) +{ + switch(way){ + case SND_CARD_LEVEL_GENERAL: + obj->level = (float)a / 100.0; + break; + case SND_CARD_LEVEL_INPUT: + obj->read.level = (float)a / 100.0; + break; + case SND_CARD_LEVEL_OUTPUT: + obj->write.level = (float)a / 100.0; + break; + default: + g_warning("jack_card_set_level: unsupported command."); + } +} + +gint jack_card_get_level(JackCard *obj,gint way) +{ + gint value = 0; + + switch(way){ + case SND_CARD_LEVEL_GENERAL: + value = (gint)(obj->level*100.0); + break; + case SND_CARD_LEVEL_INPUT: + value = (gint)(obj->read.level*100.0); + break; + case SND_CARD_LEVEL_OUTPUT: + value = (gint)(obj->write.level*100.0); + break; + default: + g_warning("jack_card_get_level: unsupported command."); + } + return value; +} + +void jack_card_set_source(JackCard *obj,int source) +{ +} + +MSFilter *jack_card_create_read_filter(JackCard *card) +{ + MSFilter *f=ms_oss_read_new(); + ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index); + return f; +} + +MSFilter *jack_card_create_write_filter(JackCard *card) +{ + MSFilter *f=ms_oss_write_new(); + ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index); + return f; +} +SndCard * jack_card_new(jack_client_t *client) +{ + JackCard * obj; + SndCard *base; + + obj= g_new0(JackCard,1); + + if (!client) return NULL; + obj->client = client; + obj->jack_running = TRUE; + obj->jack_active = FALSE; + obj->can_process = FALSE; + obj->clear = TRUE; + obj->write.can_process = FALSE; + obj->write.open = FALSE; + obj->write.init = TRUE; + obj->write.port = NULL; + obj->write.phys_ports = NULL; + obj->write.buffer = NULL; + obj->read.can_process = FALSE; + obj->read.open = FALSE; + obj->read.init = TRUE; + obj->read.port = NULL; + obj->read.phys_ports = NULL; + obj->read.buffer = NULL; + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + jack_set_process_callback (client, process, obj); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + jack_on_shutdown (client, jack_shutdown, obj); + + jack_set_sample_rate_callback (client, samplerate, obj); + + obj->rate = jack_get_sample_rate (client); + obj->buffer_size = jack_get_buffer_size(obj->client); + + jack_init(obj); + + base= SND_CARD(obj); + snd_card_init(base); + +#ifdef HAVE_GLIB + base->card_name=g_strdup_printf("JACK client"); +#else + base->card_name=malloc(100); + snprintf(base->card_name, 100, "JACK client"); +#endif + + base->_probe=(SndCardOpenFunc)jack_card_probe; + base->_open_r=(SndCardOpenFunc)jack_card_open_r; + base->_open_w=(SndCardOpenFunc)jack_card_open_w; + base->_can_read=(SndCardPollFunc)jack_card_can_read; + base->_set_blocking_mode=(SndCardSetBlockingModeFunc)jack_card_set_blocking_mode; + base->_read=(SndCardIOFunc)jack_card_read; + base->_write=(SndCardIOFunc)jack_card_write; + base->_close_r=(SndCardCloseFunc)jack_card_close_r; + base->_close_w=(SndCardCloseFunc)jack_card_close_w; + base->_set_rec_source=(SndCardMixerSetRecSourceFunc)jack_card_set_source; + base->_set_level=(SndCardMixerSetLevelFunc)jack_card_set_level; + base->_get_level=(SndCardMixerGetLevelFunc)jack_card_get_level; + base->_destroy=(SndCardDestroyFunc)jack_card_destroy; + base->_create_read_filter=(SndCardCreateFilterFunc)jack_card_create_read_filter; + base->_create_write_filter=(SndCardCreateFilterFunc)jack_card_create_write_filter; + + obj->read.buffer=NULL; + obj->write.buffer=NULL; + obj->buffer_size = 0; + obj->level = 1.0; + obj->write.level = 1.0; + obj->read.level = 1.0; + + return base; +} + + +gint jack_card_manager_init(SndCardManager *m, gint index) +{ + jack_client_t *client = NULL; + char* client_name; + + client_name=g_strdup_printf("linphone-%u", g_random_int()); + if ((client = jack_client_new (client_name))!= NULL) + { + g_message("Found Jack Daemon"); + g_free(client_name); + m->cards[index]=jack_card_new(client); + m->cards[index]->index=index; + return 1; + } else { + g_free(client_name); + return 0; + } +} + +#endif diff --git a/linphone/mediastreamer/jackcard.h b/linphone/mediastreamer/jackcard.h new file mode 100644 index 000000000..33ec46dc0 --- /dev/null +++ b/linphone/mediastreamer/jackcard.h @@ -0,0 +1,81 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + JACK support + Copyright (C) 2004 Tobias Gehrig tobias@gehrig.tk +*/ + +#ifndef JACK_CARD_H +#define JACK_CARD_H + +#include + +#ifdef __JACK_ENABLED__ + +#include "sndcard.h" + +#include +#include + +#include + +typedef jack_default_audio_sample_t sample_t; + +typedef struct { + jack_port_t *port; + const char **phys_ports; + float level; + jack_ringbuffer_t *buffer; + gint channels; + gint rate; + SRC_STATE* src_state; + SRC_DATA data; + size_t frames; + gboolean can_process; + gboolean open; + gboolean init; +} jackcard_mode_t; + +struct _JackCard +{ + SndCard parent; + + jack_client_t *client; + gboolean jack_running; + gboolean jack_active; + float level; + jack_nframes_t buffer_size; + gint sample_size; + gint frame_size; + gint rate; + gboolean can_process; + gboolean clear; + + jackcard_mode_t read, write; +}; + +typedef struct _JackCard JackCard; + +SndCard * jack_card_new(jack_client_t *client); + +gint jack_card_manager_init(SndCardManager *m, gint index); + +#endif + +#endif diff --git a/linphone/mediastreamer/mediastream.c b/linphone/mediastreamer/mediastream.c new file mode 100644 index 000000000..e88cf1902 --- /dev/null +++ b/linphone/mediastreamer/mediastream.c @@ -0,0 +1,144 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mediastream.h" + +#include +#include +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond--; + if (cond<0) exit(-1); +} + +void parse_addr(gchar *addr, char **ip, int *port) +{ + char *semicolon; + gint iplen; + + *ip=NULL; + *port=0; + semicolon=strchr(addr,':'); + if (semicolon==NULL) return; + iplen=semicolon-addr; + *ip=g_malloc(iplen+1); + strncpy(*ip,addr,iplen); + (*ip)[iplen]='\0'; + *port=atoi(semicolon+1); +} + +char *usage="mediastream --local --remote --payload \n"; +void run_media_streams(gint localport, gchar *remote_ip, gint remoteport, gint payload); + +int main(int argc, char * argv[]) +{ + gint i; + gint localport=0,remoteport=0,payload=0; + gchar *ip; + gchar *tmp; + + /*create the rtp session */ + ortp_init(); + rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015); + rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb); + rtp_profile_set_payload(&av_profile,98,&payload_type_h263_1998); + if (argc<4) { + printf(usage); + return -1; + } + for (i=1;itype!=PAYLOAD_VIDEO){ + printf("Starting audio stream.\n"); + audio=audio_stream_start(&av_profile,localport,remote_ip,remoteport,payload,50); + }else{ +#ifdef VIDEO_ENABLED + printf("Starting video stream.\n"); + video=video_stream_start(&av_profile, + localport, + remote_ip, + remoteport, + payload, + 50, + TRUE, + "Video4Linux", + "/dev/video0"); +#else + printf("Error: video support not compiled.\n"); +#endif + } + while(cond) + { + /* sleep until we receive SIGINT */ + sleep(1); + ortp_global_stats_display(); + } + + printf("stoping all...\n"); + + if (audio) audio_stream_stop(audio); +#ifdef VIDEO_ENABLED + if (video) video_stream_stop(video); +#endif +} diff --git a/linphone/mediastreamer/mediastream.h b/linphone/mediastreamer/mediastream.h new file mode 100644 index 000000000..0298b64f4 --- /dev/null +++ b/linphone/mediastreamer/mediastream.h @@ -0,0 +1,133 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MEDIASTREAM_H +#define MEDIASTREAM_H + +#include "msrtprecv.h" +#include "msrtpsend.h" +#include "ms.h" +#include "msosswrite.h" +#include "msossread.h" +#include "msread.h" +#include "mswrite.h" +#include "mstimer.h" +#include "mscodec.h" +#include "msspeexdec.h" +#include "msringplayer.h" + + +struct _AudioStream +{ + MSSync *timer; + RtpSession *send_session; + RtpSession *recv_session; + MSFilter *soundread; + MSFilter *soundwrite; + MSFilter *encoder; + MSFilter *decoder; + MSFilter *rtprecv; + MSFilter *rtpsend; +}; + + +typedef struct _AudioStream AudioStream; + +struct _RingStream +{ + MSSync *timer; + MSFilter *source; + MSFilter *sndwrite; +}; + +typedef struct _RingStream RingStream; + +/* start a thread that does sampling->encoding->rtp_sending|rtp_receiving->decoding->playing */ +AudioStream *audio_stream_start (RtpProfile * prof, int locport, char *remip, + int remport, int profile, int jitt_comp); + +AudioStream *audio_stream_start_with_sndcards(RtpProfile * prof, int locport, char *remip4, + int remport, int profile, int jitt_comp, SndCard *playcard, SndCard *captcard); + +AudioStream *audio_stream_start_with_files (RtpProfile * prof, int locport, + char *remip4, int remport, + int profile, int jitt_comp, + gchar * infile, gchar * outfile); +void audio_stream_set_rtcp_information(AudioStream *st, const char *cname); + + +/* stop the above process*/ +void audio_stream_stop (AudioStream * stream); + +RingStream *ring_start (gchar * file, gint interval, SndCard *sndcard); +RingStream *ring_start_with_cb(gchar * file, gint interval, SndCard *sndcard, MSFilterNotifyFunc func,gpointer user_data); +void ring_stop (RingStream * stream); + +/* returns the latency in samples if the audio device with id dev_id is openable in full duplex mode, else 0 */ +gint test_audio_dev (int dev_id); + +/* send a dtmf */ +gint audio_stream_send_dtmf (AudioStream * stream, gchar dtmf); + +void audio_stream_set_default_card(int cardindex); + + +#ifdef VIDEO_ENABLED + +/***************** + Video Support + *****************/ + + + +struct _VideoStream +{ + MSSync *timer; + RtpSession *send_session; + RtpSession *recv_session; + MSFilter *source; + MSFilter *output; + MSFilter *encoder; + MSFilter *decoder; + MSFilter *rtprecv; + MSFilter *rtpsend; + gboolean show_local; +}; + + +typedef struct _VideoStream VideoStream; + +VideoStream *video_stream_start(RtpProfile *profile, int locport, char *remip4, int remport, + int payload, int jitt_comp, gboolean show_local, const gchar *source, const gchar *device); +void video_stream_set_rtcp_information(VideoStream *st, const char *cname); +void video_stream_stop (VideoStream * stream); + +VideoStream * video_preview_start(const gchar *source, const gchar *device); +void video_preview_stop(VideoStream *stream); + +VideoStream * video_stream_send_only_start(RtpProfile *profile, int locport, char *remip, int remport, + int payload, const gchar *source, const gchar *device); + +void video_stream_send_only_stop(VideoStream *stream); + +#endif + +#endif diff --git a/linphone/mediastreamer/ms.c b/linphone/mediastreamer/ms.c new file mode 100644 index 000000000..c9b9a86a0 --- /dev/null +++ b/linphone/mediastreamer/ms.c @@ -0,0 +1,394 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ms.h" +#include "sndcard.h" +#include "mscodec.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_DLOPEN +#include +#endif + +#ifdef HAVE_GLIB +#include "gmodule.h" /* g_module_open() */ +#endif + +#define MS_PLUGINS_DIR PACKAGE_PLUGINS_DIR "/mediastreamer" + + +#ifdef VIDEO_ENABLED +extern void ms_video_source_register_all(); +#endif + +/** + * ms_init: + * + * + * Initialize the mediastreamer. This must be the first function called in a program + * using the mediastreamer library. + * + * + */ +void ms_init() +{ + if (!g_thread_supported()) g_thread_init (NULL); + + /* initialize the oss subsystem */ + snd_card_manager_init(snd_card_manager); + /* register the statically linked codecs */ + ms_codec_register_all(); +#ifdef VIDEO_ENABLED + ms_video_source_register_all(); +#endif + ms_load_plugins(MS_PLUGINS_DIR); +} + + +static gint compare(gconstpointer a, gconstpointer b) +{ + MSFilter *f1=(MSFilter*)a,*f2=(MSFilter*)b; + if (f1->klassklass) return -1; + if (f1->klass==f2->klass) return 0; + /* if f1->klass>f2->klass ....*/ + return 1; +} + +static GList *g_list_append_if_new(GList *l,gpointer data) +{ + GList *res=l; + if (g_list_find(res,data)==NULL) + res=g_list_append(res,data); + return(res); +} + +static GList *get_nexts(MSFilter *f,GList *l) +{ + int i; + MSFifo *fifo; + MSQueue *q; + GList *res=l; + + /* check fifos*/ + for (i=0;i klass->max_foutputs;i++) + { + fifo=f->outfifos[i]; + if (fifo!=NULL) res=g_list_append_if_new(res,(gpointer)fifo->next_data); + } + /* check queues*/ + for (i=0;i klass->max_qoutputs;i++) + { + q=f->outqueues[i]; + if (q!=NULL) res=g_list_append_if_new(res,(gpointer)q->next_data); + } + return(res); +} + +/* compile graphs attached to a sync source*/ +int ms_compile(MSSync *sync) +{ + int i; + GList *list1=NULL,*list2=NULL,*elem; + GList *proc_chain=NULL; + MSFilter *f; + + /* first free the old list if we are just updating*/ + if (sync->execution_list!=NULL) g_list_free(sync->execution_list); + /* get the list of filters attached to this sync*/ + for (i=0;ifilters;i++) + { + //printf("found filter !\n"); + list1=g_list_append(list1,sync->attached_filters[i]); + } + /* find the processing chain */ + while (list1!=NULL) + { + list2=NULL; + /* sort the list by types of filter*/ + list1=g_list_sort(list1,compare); + /* save into the processing chain list*/ + //printf("list1 :%i elements\n",g_list_length(list1)); + proc_chain=g_list_concat(proc_chain,list1); + /* get all following filters. They are appended to list2*/ + elem=list1; + while (elem!=NULL) + { + f=(MSFilter*)(elem->data); + /* check if filter 's status */ + if (f->klass->attributes & FILTER_CAN_SYNC) + { + sync->samples_per_tick=0; + } + list2=get_nexts(f,list2); + elem=g_list_next(elem); + } + list1=list2; + } + sync->execution_list=proc_chain; + sync->flags&=~MS_SYNC_NEED_UPDATE; + ms_trace("%i filters successfully compiled in a processing chain.",g_list_length(sync->execution_list)); + return 0; +} + +/*execute the processing chain attached to a sync source. It is called as a thread by ms_main()*/ +void *ms_thread_run(void *sync_ptr) +{ + MSSync *sync=(MSSync*) sync_ptr; + GList *filter; + MSFilter *f; + + + ms_sync_lock(sync); + while(sync->run) + { + //g_message("sync->run=%i",sync->run); + if (sync->samples_per_tick==0) ms_sync_suspend(sync); + if (sync->flags & MS_SYNC_NEED_UPDATE){ + ms_compile(sync); + ms_sync_setup(sync); + } + filter=sync->execution_list; + ms_sync_unlock(sync); + //ms_trace("Calling synchronisation"); + ms_sync_synchronize(sync); + while(filter!=NULL) + { + f=(MSFilter*)filter->data; + if (MS_FILTER_GET_CLASS(f)->attributes & FILTER_IS_SOURCE) + { + /* execute it once */ + ms_trace("Running source filter %s.",f->klass->name); + ms_filter_process(f); + } + else + { + /* make the filter process its input data until it has no more */ + while ( ms_filter_fifos_have_data(f) || ms_filter_queues_have_data(f) ) + { + ms_trace("Running filter %s.",f->klass->name); + ms_filter_process(f); + } + } + filter=g_list_next(filter); + } + ms_sync_lock(sync); + } + g_cond_signal(sync->stop_cond); /* signal that the sync thread has finished */ + ms_sync_unlock(sync); + g_message("Mediastreamer processing thread is exiting."); + return NULL; +} + +/* stop the processing chain attached to a sync source.*/ +void ms_thread_stop(MSSync *sync) +{ + if (sync->thread!=NULL) + { + if (sync->samples_per_tick==0) + { + /* to wakeup the thread */ + //g_cond_signal(sync->thread_cond); + } + g_mutex_lock(sync->lock); + sync->run=0; + sync->thread=NULL; + g_cond_wait(sync->stop_cond,sync->lock); + g_mutex_unlock(sync->lock); + } + //g_message("ms_thread_stop() finished."); +} + +/** + * ms_start: + * @sync: A synchronisation source to be started. + * + * Starts a thread that will shedule all processing chains attached to the synchronisation source @sync. + * + * + */ +void ms_start(MSSync *sync) +{ + if (sync->run==1) return; /*already running*/ + ms_compile(sync); + ms_sync_setup(sync); + /* this is to avoid race conditions, for example: + ms_start(sync); + ms_oss_write_start(ossw); + here tge ossw filter need to be compiled to run ms_oss_write_start() + */ + ms_trace("ms_start: creating new thread."); + sync->run=1; + sync->thread=g_thread_create((GThreadFunc)ms_thread_run,(gpointer)sync,TRUE,NULL); + if (sync->thread==NULL){ + g_warning("Could not create thread !"); + } +} + +/** + * ms_stop: + * @sync: A synchronisation source to be stopped. + * + * Stop the thread that was sheduling the processing chains attached to the synchronisation source @sync. + * The processing chains are kept unchanged, no object is freed. The synchronisation source can be restarted using ms_start(). + * + * + */ +void ms_stop(MSSync *sync) +{ + ms_thread_stop(sync); + ms_sync_unsetup(sync); +} + + +gint ms_load_plugin(gchar *path) +{ +#ifdef HAVE_GLIB + g_module_open(path,0); +#endif + return 0; +} + +gchar * ms_proc_get_param(gchar *parameter) +{ + gchar *file; + int fd; + int err,len; + gchar *p,*begin,*end; + gchar *ret; + fd=open("/proc/cpuinfo",O_RDONLY); + if (fd<0){ + g_warning("Could not open /proc/cpuinfo."); + return NULL; + } + file=g_malloc(1024); + err=read(fd,file,1024); + file[err-1]='\0'; + /* find the parameter */ + p=strstr(file,parameter); + if (p==NULL){ + /* parameter not found */ + g_free(file); + return NULL; + } + /* find the following ':' */ + p=strchr(p,':'); + if (p==NULL){ + g_free(file); + return NULL; + } + /* find the value*/ + begin=p+2; + end=strchr(begin,'\n'); + if (end==NULL) end=strchr(begin,'\0'); + len=end-begin+1; + ret=g_malloc(len+1); + snprintf(ret,len,"%s",begin); + //printf("%s=%s\n",parameter,ret); + g_free(file); + return ret; +} + +gint ms_proc_get_type() +{ + static int proc_type=0; + gchar *value; + if (proc_type==0){ + value=ms_proc_get_param("cpu family"); + if (value!=NULL) { + proc_type=atoi(value); + g_free(value); + }else return -1; + } + return proc_type; +} + +gint ms_proc_get_speed() +{ + char *value; + static int proc_speed=0; + if (proc_speed==0){ + value=ms_proc_get_param("cpu MHz"); + if (value!=NULL){ + proc_speed=atoi(value); + g_free(value); + }else return -1; + } + //printf("proc_speed=%i\n",proc_speed); + return proc_speed; +} + +#define PLUGINS_EXT ".so" + +typedef void (*init_func_t)(void); + +void ms_load_plugins(const char *dir){ +#ifdef HAVE_DLOPEN + DIR *ds; + struct dirent *de; + char *fullpath; + ds=opendir(dir); + if (ds==NULL){ + g_warning("Cannot open directory %s: %s",dir,strerror(errno)); + return; + } + while( (de=readdir(ds))!=NULL){ + if (de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL){ + void *handle; + fullpath=g_strdup_printf("%s/%s",dir,de->d_name); + g_message("Loading plugin %s...",fullpath); + + if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ + g_warning("Fail to load plugin %s : %s",fullpath,dlerror()); + }else { + char *initroutine_name=g_malloc0(strlen(de->d_name)+10); + char *p; + void *initroutine; + strcpy(initroutine_name,de->d_name); + p=strstr(initroutine_name,PLUGINS_EXT); + strcpy(p,"_init"); + initroutine=dlsym(handle,initroutine_name); + if (initroutine!=NULL){ + init_func_t func=(init_func_t)initroutine; + func(); + g_message("Plugin loaded."); + }else{ + g_warning("Could not locate init routine of plugin %s",de->d_name); + } + g_free(initroutine_name); + } + g_free(fullpath); + } + } + closedir(ds); +#else + g_warning("no loadable plugin support: plugins cannot be loaded."); +#endif +} diff --git a/linphone/mediastreamer/ms.h b/linphone/mediastreamer/ms.h new file mode 100644 index 000000000..b214c776a --- /dev/null +++ b/linphone/mediastreamer/ms.h @@ -0,0 +1,81 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + + +#ifndef MS_H +#define MS_H +#include "msfilter.h" +#include "mssync.h" + + +void ms_init(); + +/* compile graphs attached to a sync source*/ +int ms_compile(MSSync *source); + + +/* stop the processing chain attached to a sync source.*/ +void ms_thread_stop(MSSync *sync); + + +/** + * function_name:ms_thread_run + * @sync: The synchronization source for all the set of graphs to run. + * + * Execute the processing chain attached to a sync source. This function loops indefinitely. + * The media streamer programmer can choose to execute this function directly, or to call ms_start(), + * that will start a thread for the synchronisation source. + * + * Returns: no return value. + */ +void *ms_thread_run(void *sync); + + +/** + * function_name:ms_start + * @sync: A synchronisation source to be started. + * + * Starts a thread that will shedule all processing chains attached to the synchronisation source @sync. + * + * Returns: no return value. + */ +void ms_start(MSSync *sync); + + +/** + * function_name:ms_stop + * @sync: A synchronisation source to be stopped. + * + * Stop the thread that was sheduling the processing chains attached to the synchronisation source @sync. + * The processing chains are kept unchanged, no object is freed. The synchronisation source can be restarted using ms_start(). + * + * Returns: no return value. + */ +void ms_stop(MSSync *sync); + + +gchar * ms_proc_get_param(gchar *parameter); +gint ms_proc_get_type(); +gint ms_proc_get_speed(); + +void ms_load_plugins(const char *dir); + +#endif diff --git a/linphone/mediastreamer/msAlawdec.c b/linphone/mediastreamer/msAlawdec.c new file mode 100644 index 000000000..0ce2f4ed0 --- /dev/null +++ b/linphone/mediastreamer/msAlawdec.c @@ -0,0 +1,132 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msAlawdec.h" +#include "g711common.h" + +extern MSFilter * ms_ALAWencoder_new(void); + +MSCodecInfo ALAWinfo={ + { + "ALAW codec", + 0, + MS_FILTER_AUDIO_CODEC, + ms_ALAWencoder_new, + "This is the classic A-law codec. Good quality, but only usable with high speed network connections." + }, + ms_ALAWencoder_new, + ms_ALAWdecoder_new, + 320, + 160, + 64000, + 8000, + 8, + "PCMA", + 1, + 1, +}; + +static MSALAWDecoderClass *ms_ALAWdecoder_class=NULL; + +MSFilter * ms_ALAWdecoder_new(void) +{ + MSALAWDecoder *r; + + r=g_new(MSALAWDecoder,1); + ms_ALAWdecoder_init(r); + if (ms_ALAWdecoder_class==NULL) + { + ms_ALAWdecoder_class=g_new(MSALAWDecoderClass,1); + ms_ALAWdecoder_class_init(ms_ALAWdecoder_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ALAWdecoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_ALAWdecoder_init(MSALAWDecoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=ALAW_DECODER_RMAXGRAN; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSALAWDECODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSALAWDECODER_MAX_INPUTS); + +} + +void ms_ALAWdecoder_class_init(MSALAWDecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ALAWDecoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ALAWinfo; + MS_FILTER_CLASS(klass)->max_finputs=MSALAWDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSALAWDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=ALAW_DECODER_RMAXGRAN; + MS_FILTER_CLASS(klass)->w_maxgran=ALAW_DECODER_WMAXGRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ALAWdecoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ALAWdecoder_process; +} + +void ms_ALAWdecoder_process(MSALAWDecoder *r) +{ + MSFifo *fi,*fo; + int inlen,outlen; + gchar *s,*d; + int i; + /* process output fifos, but there is only one for this class of filter*/ + + /* this is the simplest process function design: + the filter declares a r_mingran of ALAW_DECODER_RMAXGRAN, so the mediastreamer's + scheduler will call the process function each time there is ALAW_DECODER_RMAXGRAN + bytes to read in the input fifo. If there is more, then it will call it several + time in order to the fifo to be completetly processed. + This is very simple, but not very efficient because of the multiple call function + of MSFilterProcessFunc that may happen. + The MSAlawEncoder implements another design; see it. + */ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + g_return_if_fail(fi!=NULL); + g_return_if_fail(fo!=NULL); + + inlen=ms_fifo_get_read_ptr(fi,ALAW_DECODER_RMAXGRAN,(void**)&s); + if (s==NULL) return; + outlen=ms_fifo_get_write_ptr(fo,ALAW_DECODER_WMAXGRAN,(void**)&d); + if (d!=NULL) + { + for(i=0;iklass=MS_FILTER_CLASS(ms_ALAWencoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_ALAWencoder_init(MSALAWEncoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=ALAW_ENCODER_RMAXGRAN; /* the filter can be called as soon as there is + something to process */ + memset(r->f_inputs,0,sizeof(MSFifo*)*MSALAWENCODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSALAWENCODER_MAX_INPUTS); + +} + +void ms_ALAWencoder_class_init(MSALAWEncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ALAWEncoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&ALAWinfo; + MS_FILTER_CLASS(klass)->max_finputs=MSALAWENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSALAWENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=ALAW_ENCODER_RMAXGRAN; + MS_FILTER_CLASS(klass)->w_maxgran=ALAW_ENCODER_WMAXGRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ALAWencoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ALAWencoder_process; +} + +void ms_ALAWencoder_process(MSALAWEncoder *r) +{ + MSFifo *fi,*fo; + int inlen,outlen; + gchar *s,*d; + int i; + /* process output fifos, but there is only one for this class of filter*/ + + /* this is the sophisticated design of the process function: + Here the filter declares that it can be called as soon as there is something + to read on the input fifo by setting r_mingran=0. + Then it ask for the fifo to get as many data as possible by calling: + inlen=ms_fifo_get_read_ptr(fi,0,(void**)&s); + This avoid multiple call to the process function to process all data available + on the input fifo... but the writing of the process function is a bit + more difficult, because althoug ms_fifo_get_read_ptr() returns N bytes, + we cannot ask ms_fifo_get_write_ptr to return N bytes if + N>MS_FILTER_CLASS(klass)->w_maxgran. This is forbidden by the MSFifo + mechanism. + This is an open issue. + For the moment what is done here is that ms_fifo_get_write_ptr() is called + several time with its maximum granularity in order to try to write the output. + ... + One solution: + -create a new function ms_fifo_get_rw_ptr(fifo1,p1, fifo2,p2) to + return the number of bytes able to being processed according to the input + and output fifo, and their respective data pointers + */ + + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + + inlen=ms_fifo_get_read_ptr(fi,ALAW_ENCODER_RMAXGRAN,(void**)&s); + if (s==NULL) return; + outlen=ms_fifo_get_write_ptr(fo,ALAW_ENCODER_WMAXGRAN,(void**)&d); + if (d!=NULL) + { + for(i=0;iklass=MS_FILTER_CLASS(ms_GSMdecoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_GSMdecoder_init(MSGSMDecoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->inqueues=r->q_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=33; + memset(r->q_inputs,0,sizeof(MSFifo*)*MSGSMDECODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSGSMDECODER_MAX_INPUTS); + r->gsm_handle=gsm_create(); +} + +void ms_GSMdecoder_class_init(MSGSMDecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"GSMDecoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&GSMinfo; + MS_FILTER_CLASS(klass)->max_qinputs=MSGSMDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSGSMDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->w_maxgran=2*160; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_GSMdecoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_GSMdecoder_process; +} + +void ms_GSMdecoder_process(MSGSMDecoder *r) +{ + MSFifo *fo; + MSQueue *qi; + void *d; + MSMessage *inm; + + /* process output fifos, but there is only one for this class of filter*/ + + qi=r->q_inputs[0]; + fo=r->f_outputs[0]; + inm=ms_queue_get(qi); + ms_fifo_get_write_ptr(fo,160*2,&d); + if (d!=NULL) + gsm_decode(r->gsm_handle,(guchar*)inm->data,(gsm_signal*)d); + ms_message_destroy(inm); +} + +void ms_GSMdecoder_uninit(MSGSMDecoder *obj) +{ + gsm_destroy(obj->gsm_handle); +} + +void ms_GSMdecoder_destroy( MSGSMDecoder *obj) +{ + ms_GSMdecoder_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msGSMdecoder.h b/linphone/mediastreamer/msGSMdecoder.h new file mode 100644 index 000000000..2930d8197 --- /dev/null +++ b/linphone/mediastreamer/msGSMdecoder.h @@ -0,0 +1,64 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSGSMDECODER_H +#define MSGSMDECODER_H + +#include "msfilter.h" +#include "mscodec.h" +#include + +/*this is the class that implements a GSMdecoder filter*/ + +#define MSGSMDECODER_MAX_INPUTS 1 /* max output per filter*/ + + +typedef struct _MSGSMDecoder +{ + /* the MSGSMDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSGSMDecoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSQueue *q_inputs[MSGSMDECODER_MAX_INPUTS]; + MSFifo *f_outputs[MSGSMDECODER_MAX_INPUTS]; + gsm gsm_handle; +} MSGSMDecoder; + +typedef struct _MSGSMDecoderClass +{ + /* the MSGSMDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSGSMDecoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSGSMDecoderClass; + +/* PUBLIC */ +#define MS_GSMDECODER(filter) ((MSGSMDecoder*)(filter)) +#define MS_GSMDECODER_CLASS(klass) ((MSGSMDecoderClass*)(klass)) +MSFilter * ms_GSMdecoder_new(void); + +/* FOR INTERNAL USE*/ +void ms_GSMdecoder_init(MSGSMDecoder *r); +void ms_GSMdecoder_class_init(MSGSMDecoderClass *klass); +void ms_GSMdecoder_destroy( MSGSMDecoder *obj); +void ms_GSMdecoder_process(MSGSMDecoder *r); + +extern MSCodecInfo GSMinfo; + +#endif diff --git a/linphone/mediastreamer/msGSMencoder.c b/linphone/mediastreamer/msGSMencoder.c new file mode 100644 index 000000000..8c085048c --- /dev/null +++ b/linphone/mediastreamer/msGSMencoder.c @@ -0,0 +1,98 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msGSMencoder.h" +#include "mscodec.h" + +extern MSCodecInfo GSMinfo; + +static MSGSMEncoderClass *ms_GSMencoder_class=NULL; + +MSFilter * ms_GSMencoder_new(void) +{ + MSGSMEncoder *r; + + r=g_new(MSGSMEncoder,1); + ms_GSMencoder_init(r); + if (ms_GSMencoder_class==NULL) + { + ms_GSMencoder_class=g_new(MSGSMEncoderClass,1); + ms_GSMencoder_class_init(ms_GSMencoder_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_GSMencoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_GSMencoder_init(MSGSMEncoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outqueues=r->q_outputs; + MS_FILTER(r)->r_mingran=2*160; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSGSMENCODER_MAX_INPUTS); + memset(r->q_outputs,0,sizeof(MSFifo*)*MSGSMENCODER_MAX_INPUTS); + r->gsm_handle=gsm_create(); +} + +void ms_GSMencoder_class_init(MSGSMEncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"GSMEncoder"); + MS_FILTER_CLASS(klass)->max_finputs=MSGSMENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_qoutputs=MSGSMENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=2*160; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_GSMencoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_GSMencoder_process; + MS_FILTER_CLASS(klass)->info=MS_FILTER_INFO(&GSMinfo); +} + +void ms_GSMencoder_process(MSGSMEncoder *r) +{ + MSFifo *fi; + MSQueue *qo; + int err1; + void *s; + + /* process output fifos, but there is only one for this class of filter*/ + + fi=r->f_inputs[0]; + qo=r->q_outputs[0]; + err1=ms_fifo_get_read_ptr(fi,160*2,&s); + if (err1>0){ + MSMessage *m=ms_message_new(33); + gsm_encode(r->gsm_handle,(gsm_signal*)s,(gsm_byte*)m->data); + ms_queue_put(qo,m); + } + +} + +void ms_GSMencoder_uninit(MSGSMEncoder *obj) +{ + gsm_destroy(obj->gsm_handle); +} + +void ms_GSMencoder_destroy( MSGSMEncoder *obj) +{ + ms_GSMencoder_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msGSMencoder.h b/linphone/mediastreamer/msGSMencoder.h new file mode 100644 index 000000000..aa466a64d --- /dev/null +++ b/linphone/mediastreamer/msGSMencoder.h @@ -0,0 +1,61 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSGSMENCODER_H +#define MSGSMENCODER_H + +#include "msfilter.h" +#include + +/*this is the class that implements a GSMencoder filter*/ + +#define MSGSMENCODER_MAX_INPUTS 1 /* max output per filter*/ + + +typedef struct _MSGSMEncoder +{ + /* the MSGSMEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSGSMEncoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSGSMENCODER_MAX_INPUTS]; + MSQueue *q_outputs[MSGSMENCODER_MAX_INPUTS]; + gsm gsm_handle; +} MSGSMEncoder; + +typedef struct _MSGSMEncoderClass +{ + /* the MSGSMEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSGSMEncoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSGSMEncoderClass; + +/* PUBLIC */ +#define MS_GSMENCODER(filter) ((MSGSMEncoder*)(filter)) +#define MS_GSMENCODER_CLASS(klass) ((MSGSMEncoderClass*)(klass)) +MSFilter * ms_GSMencoder_new(void); + +/* FOR INTERNAL USE*/ +void ms_GSMencoder_init(MSGSMEncoder *r); +void ms_GSMencoder_class_init(MSGSMEncoderClass *klass); +void ms_GSMencoder_destroy( MSGSMEncoder *obj); +void ms_GSMencoder_process(MSGSMEncoder *r); + +#endif diff --git a/linphone/mediastreamer/msLPC10decoder.c b/linphone/mediastreamer/msLPC10decoder.c new file mode 100644 index 000000000..1d398bea9 --- /dev/null +++ b/linphone/mediastreamer/msLPC10decoder.c @@ -0,0 +1,129 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msLPC10decoder.h" +#include "msLPC10encoder.h" +#include +#include + +extern MSFilter * ms_LPC10encoder_new(void); + +MSCodecInfo LPC10info={ + { + "LPC10-15 codec", + 0, + MS_FILTER_AUDIO_CODEC, + ms_LPC10encoder_new, + "A low quality but very low bit rate codec from the U.S. Department of Defense." + }, + ms_LPC10encoder_new, + ms_LPC10decoder_new, + 360, + 7, + 2400, + 8000, + 115, + "1015", + 1, + 1, +}; + +static MSLPC10DecoderClass *ms_LPC10decoder_class=NULL; + +MSFilter * ms_LPC10decoder_new(void) +{ + MSLPC10Decoder *r; + + r=g_new(MSLPC10Decoder,1); + ms_LPC10decoder_init(r); + if (ms_LPC10decoder_class==NULL) + { + ms_LPC10decoder_class=g_new(MSLPC10DecoderClass,1); + ms_LPC10decoder_class_init(ms_LPC10decoder_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_LPC10decoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_LPC10decoder_init(MSLPC10Decoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=7; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSLPC10DECODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSLPC10DECODER_MAX_INPUTS); + r->lpc10_dec=create_lpc10_decoder_state(); +} + +void ms_LPC10decoder_class_init(MSLPC10DecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"LPC10Dec"); + MS_FILTER_CLASS(klass)->max_finputs=MSLPC10DECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSLPC10DECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=7; + MS_FILTER_CLASS(klass)->w_maxgran=LPC10_SAMPLES_PER_FRAME*2; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_LPC10decoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_LPC10decoder_process; + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&LPC10info; +} + +void ms_LPC10decoder_process(MSLPC10Decoder *r) +{ + MSFifo *fi,*fo; + int err1; + void *s,*d; + float speech[LPC10_SAMPLES_PER_FRAME]; + INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + + /* process output fifos, but there is only one for this class of filter*/ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + if (fi!=NULL) + { + err1=ms_fifo_get_read_ptr(fi,7,&s); + if (err1>0) + { + err1=ms_fifo_get_write_ptr(fo,LPC10_SAMPLES_PER_FRAME*2,&d); + if (d!=NULL) + { + read_bits(s, bits, LPC10_BITS_IN_COMPRESSED_FRAME); + lpc10_decode(bits,speech, r->lpc10_dec); + write_16bit_samples((INT16*)d, speech, LPC10_SAMPLES_PER_FRAME); + } + } + } +} + +void ms_LPC10decoder_uninit(MSLPC10Decoder *obj) +{ + free(obj->lpc10_dec); +} + +void ms_LPC10decoder_destroy( MSLPC10Decoder *obj) +{ + ms_LPC10decoder_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msLPC10decoder.h b/linphone/mediastreamer/msLPC10decoder.h new file mode 100644 index 000000000..59d9deca4 --- /dev/null +++ b/linphone/mediastreamer/msLPC10decoder.h @@ -0,0 +1,64 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSLPC10DECODER_H +#define MSLPC10DECODER_H + +#include +#include +#include + +/*this is the class that implements a LPC10decoder filter*/ + +#define MSLPC10DECODER_MAX_INPUTS 1 /* max output per filter*/ + + +typedef struct _MSLPC10Decoder +{ + /* the MSLPC10Decoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSLPC10Decoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSLPC10DECODER_MAX_INPUTS]; + MSFifo *f_outputs[MSLPC10DECODER_MAX_INPUTS]; + struct lpc10_decoder_state *lpc10_dec; +} MSLPC10Decoder; + +typedef struct _MSLPC10DecoderClass +{ + /* the MSLPC10Decoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSLPC10Decoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSLPC10DecoderClass; + +/* PUBLIC */ +#define MS_LPC10DECODER(filter) ((MSLPC10Decoder*)(filter)) +#define MS_LPC10DECODER_CLASS(klass) ((MSLPC10DecoderClass*)(klass)) +MSFilter * ms_LPC10decoder_new(void); + +/* FOR INTERNAL USE*/ +void ms_LPC10decoder_init(MSLPC10Decoder *r); +void ms_LPC10decoder_class_init(MSLPC10DecoderClass *klass); +void ms_LPC10decoder_destroy( MSLPC10Decoder *obj); +void ms_LPC10decoder_process(MSLPC10Decoder *r); + +extern MSCodecInfo LPC10info; + +#endif diff --git a/linphone/mediastreamer/msLPC10encoder.c b/linphone/mediastreamer/msLPC10encoder.c new file mode 100644 index 000000000..2c083f364 --- /dev/null +++ b/linphone/mediastreamer/msLPC10encoder.c @@ -0,0 +1,251 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "msLPC10encoder.h" +#include + + +extern MSCodecInfo LPC10info; + +/* The return value of each of these calls is the same as that + returned by fread/fwrite, which should be the number of samples + successfully read/written, not the number of bytes. */ + +int +read_16bit_samples(INT16 int16samples[], float speech[], int n) +{ + int i; + + /* Convert 16 bit integer samples to floating point values in the + range [-1,+1]. */ + + for (i = 0; i < n; i++) { + speech[i] = ((float) int16samples[i]) / 32768.0; + } + + return (n); +} + + + +int +write_16bit_samples(INT16 int16samples[], float speech[], int n) +{ + int i; + float real_sample; + + /* Convert floating point samples in range [-1,+1] to 16 bit + integers. */ + for (i = 0; i < n; i++) { + real_sample = 32768.0 * speech[i]; + if (real_sample < -32768.0) { + int16samples[i] = -32768; + } else if (real_sample > 32767.0) { + int16samples[i] = 32767; + } else { + int16samples[i] = real_sample; + } + } + return (n); +} + +/* + +Write the bits in bits[0] through bits[len-1] to file f, in "packed" +format. + +bits is expected to be an array of len integer values, where each +integer is 0 to represent a 0 bit, and any other value represents a 1 +bit. This bit string is written to the file f in the form of several +8 bit characters. If len is not a multiple of 8, then the last +character is padded with 0 bits -- the padding is in the least +significant bits of the last byte. The 8 bit characters are "filled" +in order from most significant bit to least significant. + +*/ + +void +write_bits(unsigned char *data, INT32 *bits, int len) +{ + int i; /* generic loop variable */ + unsigned char mask; /* The next bit position within the + variable "data" to place the next + bit. */ + + + /* Fill in the array bits. + * The first compressed output bit will be the most significant + * bit of the byte, so initialize mask to 0x80. The next byte of + * compressed data is initially 0, and the desired bits will be + * turned on below. + */ + mask = 0x80; + *data = 0; + + for (i = 0; i < len; i++) { + /* Turn on the next bit of output data, if necessary. */ + if (bits[i]) { + (*data) |= mask; + } + /* + * If the byte data is full, determined by mask becoming 0, + * then write the byte to the output file, and reinitialize + * data and mask for the next output byte. Also add the byte + * if (i == len-1), because if len is not a multiple of 8, + * then mask won't yet be 0. */ + mask >>= 1; + if ((mask == 0) || (i == len-1)) { + data++; + *data = 0; + mask = 0x80; + } + } +} + + + +/* + +Read bits from file f into bits[0] through bits[len-1], in "packed" +format. + +Read ceiling(len/8) characters from file f, if that many are available +to read, otherwise read to the end of the file. The first character's +8 bits, in order from MSB to LSB, are used to fill bits[0] through +bits[7]. The second character's bits are used to fill bits[8] through +bits[15], and so on. If ceiling(len/8) characters are available to +read, and len is not a multiple of 8, then some of the least +significant bits of the last character read are completely ignored. +Every entry of bits[] that is modified is changed to either a 0 or a +1. + +The number of bits successfully read is returned, and is always in the +range 0 to len, inclusive. If it is less than len, it will always be +a multiple of 8. + +*/ + +int +read_bits(unsigned char *data, INT32 *bits, int len) +{ + int i,ind=0; /* generic loop variable */ + int c=0; + + /* Unpack the array bits into coded_frame. */ + for (i = 0; i < len; i++) { + if ((i % 8) == 0) { + c = (int)(data[ind]); + ind++; + } + if (c & (0x80 >> (i & 7))) { + bits[i] = 1; + } else { + bits[i] = 0; + } + } + return (len); +} + + + + +static MSLPC10EncoderClass *ms_LPC10encoder_class=NULL; + +MSFilter * ms_LPC10encoder_new(void) +{ + MSLPC10Encoder *r; + + r=g_new(MSLPC10Encoder,1); + ms_LPC10encoder_init(r); + if (ms_LPC10encoder_class==NULL) + { + ms_LPC10encoder_class=g_new(MSLPC10EncoderClass,1); + ms_LPC10encoder_class_init(ms_LPC10encoder_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_LPC10encoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_LPC10encoder_init(MSLPC10Encoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=LPC10_SAMPLES_PER_FRAME*2; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSLPC10ENCODER_MAX_INPUTS); + r->lpc10_enc=create_lpc10_encoder_state(); +} + +void ms_LPC10encoder_class_init(MSLPC10EncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"LPC10Enc"); + MS_FILTER_CLASS(klass)->max_finputs=MSLPC10ENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSLPC10ENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=LPC10_SAMPLES_PER_FRAME*2; + MS_FILTER_CLASS(klass)->w_maxgran=7; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_LPC10encoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_LPC10encoder_process; + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&LPC10info; +} + +void ms_LPC10encoder_process(MSLPC10Encoder *r) +{ + MSFifo *fi,*fo; + int err1; + void *s,*d; + float speech[LPC10_SAMPLES_PER_FRAME]; + INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + + /* process output fifos, but there is only one for this class of filter*/ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + if (fi!=NULL) + { + err1=ms_fifo_get_read_ptr(fi,LPC10_SAMPLES_PER_FRAME*2,&s); + if (err1>0) + { + err1=ms_fifo_get_write_ptr(fo,7,&d); + if (d!=NULL) + { + read_16bit_samples((INT16*)s, speech, LPC10_SAMPLES_PER_FRAME); + lpc10_encode(speech, bits, r->lpc10_enc); + write_bits(d, bits, LPC10_BITS_IN_COMPRESSED_FRAME); + } + } + + } +} + +void ms_LPC10encoder_uninit(MSLPC10Encoder *obj) +{ + free(obj->lpc10_enc); +} + +void ms_LPC10encoder_destroy( MSLPC10Encoder *obj) +{ + ms_LPC10encoder_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msLPC10encoder.h b/linphone/mediastreamer/msLPC10encoder.h new file mode 100644 index 000000000..4db164366 --- /dev/null +++ b/linphone/mediastreamer/msLPC10encoder.h @@ -0,0 +1,74 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSLPC10ENCODER_H +#define MSLPC10ENCODER_H + +#include "mscodec.h" + + +int +read_16bit_samples(gint16 int16samples[], float speech[], int n); + +int +write_16bit_samples(gint16 int16samples[], float speech[], int n); + +void +write_bits(unsigned char *data, gint32 *bits, int len); + +int +read_bits(unsigned char *data, gint32 *bits, int len); + + +/*this is the class that implements a LPC10encoder filter*/ + +#define MSLPC10ENCODER_MAX_INPUTS 1 /* max output per filter*/ + + +typedef struct _MSLPC10Encoder +{ + /* the MSLPC10Encoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSLPC10Encoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSLPC10ENCODER_MAX_INPUTS]; + MSFifo *f_outputs[MSLPC10ENCODER_MAX_INPUTS]; + struct lpc10_encoder_state *lpc10_enc; +} MSLPC10Encoder; + +typedef struct _MSLPC10EncoderClass +{ + /* the MSLPC10Encoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSLPC10Encoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSLPC10EncoderClass; + +/* PUBLIC */ +#define MS_LPC10ENCODER(filter) ((MSLPC10Encoder*)(filter)) +#define MS_LPC10ENCODER_CLASS(klass) ((MSLPC10EncoderClass*)(klass)) +MSFilter * ms_LPC10encoder_new(void); + +/* FOR INTERNAL USE*/ +void ms_LPC10encoder_init(MSLPC10Encoder *r); +void ms_LPC10encoder_class_init(MSLPC10EncoderClass *klass); +void ms_LPC10encoder_destroy( MSLPC10Encoder *obj); +void ms_LPC10encoder_process(MSLPC10Encoder *r); + +#endif diff --git a/linphone/mediastreamer/msMUlawdec.c b/linphone/mediastreamer/msMUlawdec.c new file mode 100644 index 000000000..e15260c8a --- /dev/null +++ b/linphone/mediastreamer/msMUlawdec.c @@ -0,0 +1,130 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msMUlawdec.h" +#include "g711common.h" + +extern MSFilter * ms_MULAWencoder_new(void); + +MSCodecInfo MULAWinfo={ + { + "MULAW codec", + 0, + MS_FILTER_AUDIO_CODEC, + ms_MULAWencoder_new, + "This is the classic Mu-law codec. Good quality, but only usable with high speed network connections." + }, + ms_MULAWencoder_new, + ms_MULAWdecoder_new, + 320, + 160, + 64000, + 8000, + 0, + "PCMU", + 1, + 1 +}; + +static MSMULAWDecoderClass *ms_MULAWdecoder_class=NULL; + +MSFilter * ms_MULAWdecoder_new(void) +{ + MSMULAWDecoder *r; + + r=g_new(MSMULAWDecoder,1); + ms_MULAWdecoder_init(r); + if (ms_MULAWdecoder_class==NULL) + { + ms_MULAWdecoder_class=g_new(MSMULAWDecoderClass,1); + ms_MULAWdecoder_class_init(ms_MULAWdecoder_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_MULAWdecoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_MULAWdecoder_init(MSMULAWDecoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=MULAW_DECODER_RMAXGRAN; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSMULAWDECODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSMULAWDECODER_MAX_INPUTS); + +} + +void ms_MULAWdecoder_class_init(MSMULAWDecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MULAWDecoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&MULAWinfo; + MS_FILTER_CLASS(klass)->max_finputs=MSMULAWDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSMULAWDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=MULAW_DECODER_RMAXGRAN; + MS_FILTER_CLASS(klass)->w_maxgran=MULAW_DECODER_WMAXGRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_MULAWdecoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_MULAWdecoder_process; +} + +void ms_MULAWdecoder_process(MSMULAWDecoder *r) +{ + MSFifo *fi,*fo; + int inlen,outlen; + gchar *s,*d; + int i; + /* process output fifos, but there is only one for this class of filter*/ + + /* this is the simplest process function design: + the filter declares a r_mingran of MULAW_DECODER_RMAXGRAN, so the mediastreamer's + scheduler will call the process function each time there is MULAW_DECODER_RMAXGRAN + bytes to read in the input fifo. If there is more, then it will call it several + time in order to the fifo to be completetly processed. + This is very simple, but not very efficient because of the multiple call function + of MSFilterProcessFunc that may happen. + The MSAlawEncoder implements another design; see it. + */ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + + inlen=ms_fifo_get_read_ptr(fi,MULAW_DECODER_RMAXGRAN,(void**)&s); + if (s==NULL) g_error("ms_MULAWdecoder_process: internal error."); + outlen=ms_fifo_get_write_ptr(fo,MULAW_DECODER_WMAXGRAN,(void**)&d); + if (d!=NULL) + { + for(i=0;iklass=MS_FILTER_CLASS(ms_MULAWencoder_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_MULAWencoder_init(MSMULAWEncoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=MULAW_ENCODER_RMAXGRAN; /* the filter can be called as soon as there is + something to process */ + memset(r->f_inputs,0,sizeof(MSFifo*)*MSMULAWENCODER_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSMULAWENCODER_MAX_INPUTS); + +} + +void ms_MULAWencoder_class_init(MSMULAWEncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MULAWEncoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&MULAWinfo; + MS_FILTER_CLASS(klass)->max_finputs=MSMULAWENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSMULAWENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=MULAW_ENCODER_RMAXGRAN; + MS_FILTER_CLASS(klass)->w_maxgran=MULAW_ENCODER_WMAXGRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_MULAWencoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_MULAWencoder_process; +} + +void ms_MULAWencoder_process(MSMULAWEncoder *r) +{ + MSFifo *fi,*fo; + int inlen,outlen; + gchar *s,*d; + int i; + /* process output fifos, but there is only one for this class of filter*/ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + inlen=ms_fifo_get_read_ptr(fi,MULAW_ENCODER_RMAXGRAN,(void**)&s); + outlen=ms_fifo_get_write_ptr(fo,MULAW_ENCODER_WMAXGRAN,(void**)&d); + if (d!=NULL) + { + for(i=0;i + +#include "msavdecoder.h" +#include "mscodec.h" +#include "rfc2429.h" + +extern MSFilter *ms_mpeg_encoder_new(); +extern MSFilter *ms_mpeg4_encoder_new(); +extern MSFilter *ms_h263p_encoder_new(); + + +MSCodecInfo MPEGinfo={ + { + "MPEG1 codec", + 0, + MS_FILTER_VIDEO_CODEC, + ms_mpeg_encoder_new, + "This is a MPEG1 codec taken from the ffmpeg project." + }, + ms_mpeg_encoder_new, + ms_mpeg_decoder_new, + 0, + 0, + 0, /*bitrate */ + 0, /*sample freq */ + 0, + "MPV", + 1, + 1 +}; + +MSCodecInfo h263pinfo={ + { + "H263 codec", + 0, + MS_FILTER_VIDEO_CODEC, + ms_h263p_encoder_new, + "This is a H263 codec taken from the ffmpeg project." + }, + ms_h263p_encoder_new, + ms_h263p_decoder_new, + 0, + 0, + 0, /*bitrate */ + 0, /*sample freq */ + 0, + "H263-1998", + 1, + 1 +}; + +MSCodecInfo MPEG4info={ + { + "MPEG4 codec", + 0, + MS_FILTER_VIDEO_CODEC, + ms_mpeg4_encoder_new, + "This is a MPEG4 codec taken from the ffmpeg project." + }, + ms_mpeg4_encoder_new, + ms_mpeg4_decoder_new, + 0, + 0, + 0, /*bitrate */ + 0, /*sample freq */ + 0, + "MP4V-ES", + 1, + 1 +}; + + +void ms_AVCodec_init() +{ + avcodec_init(); + avcodec_register_all(); + ms_filter_register((MSFilterInfo*)&h263pinfo); + //ms_filter_register((MSFilterInfo*)&MPEG4info); +} + + +static MSAVDecoderClass *ms_avdecoder_class=NULL; + +MSFilter *ms_mpeg_decoder_new() +{ + return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG1VIDEO); +} + +MSFilter *ms_mpeg4_decoder_new() +{ + return ms_AVdecoder_new_with_codec(CODEC_ID_MPEG4); +} + +MSFilter *ms_h263p_decoder_new(){ + /* H263P decoder doesn't exist in libavcodec...*/ + return ms_AVdecoder_new_with_codec(CODEC_ID_H263); +} + +MSFilter * ms_AVdecoder_new_with_codec(enum CodecID codec_id) +{ + MSAVDecoder *enc; + + enc=g_malloc0(sizeof(MSAVDecoder)); + if (ms_avdecoder_class==NULL) + { + ms_avdecoder_class=g_malloc0(sizeof(MSAVDecoderClass)); + ms_AVdecoder_class_init(ms_avdecoder_class); + } + MS_FILTER(enc)->klass=(MSFilterClass*)ms_avdecoder_class; + ms_AVdecoder_init(enc,avcodec_find_decoder(codec_id)); + return MS_FILTER(enc); +} + + +void ms_AVdecoder_init(MSAVDecoder *dec, AVCodec *codec) +{ + gint error; + + ms_filter_init(MS_FILTER(dec)); + MS_FILTER(dec)->inqueues=dec->q_inputs; + MS_FILTER(dec)->outqueues=dec->q_outputs; + avcodec_get_context_defaults(&dec->av_context); + ms_AVdecoder_set_width(dec,VIDEO_SIZE_CIF_W); + ms_AVdecoder_set_height(dec,VIDEO_SIZE_CIF_H); + dec->av_codec=codec; + dec->av_opened=0; + dec->skip_gob=1; + dec->obufwrap=NULL; + dec->buf_size=0; +} + +void ms_AVdecoder_class_init(MSAVDecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name( MS_FILTER_CLASS(klass),"AVdecoder"); + MS_FILTER_CLASS(klass)->max_qinputs=MSAVDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_qoutputs=MSAVDECODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=0; + MS_FILTER_CLASS(klass)->w_maxgran=0; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_AVdecoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_AVdecoder_process; +} + +void ms_AVdecoder_uninit(MSAVDecoder *dec) +{ + if (dec->obufwrap!=NULL) ms_buffer_destroy(dec->obufwrap); + if (dec->av_opened) avcodec_close(&dec->av_context); +} +void ms_AVdecoder_destroy( MSAVDecoder *obj) +{ + ms_AVdecoder_uninit(obj); + g_free(obj); +} + +gint ms_AVdecoder_set_format(MSAVDecoder *dec, gchar *fmt) +{ + gint format; + if (strcmp(fmt,"YUV420P")==0) format=PIX_FMT_YUV420P; + else if (strcmp(fmt,"YUV422")==0) format=PIX_FMT_YUV422; + else if (strcmp(fmt,"RGB24")==0) format=PIX_FMT_RGB24; + else if (strcmp(fmt,"BGR24")==0) format=PIX_FMT_BGR24; + else if (strcmp(fmt,"YUV422P")==0) format=PIX_FMT_YUV422P; + else if (strcmp(fmt,"YUV444P")==0) format=PIX_FMT_YUV444P; + else { + g_warning("ms_AVdecoder_set_format: unsupported format %s.",fmt); + return -1; + } + dec->output_pix_fmt=format; + return 0; +} + +void ms_AVdecoder_process(MSAVDecoder *r) +{ + AVFrame orig; + AVFrame transformed; + MSQueue *inq,*outq; + MSMessage *inm,*outm; + gint error; + gint got_picture; + gint len; + unsigned char *data; + AVCodecContext *ctx=&r->av_context; + gint gob_num; + + inq=r->q_inputs[0]; + outq=r->q_outputs[0]; + + /* get a picture from the input queue */ + inm=ms_queue_get(inq); + g_return_if_fail(inm!=NULL); + if (inm->size >= 2) + { + guint32 *p = (guint32*)inm->data; + char *ph=inm->data; + int PLEN; + gboolean P; + if (!r->av_opened){ + error=avcodec_open(&r->av_context, r->av_codec); + if (error!=0) g_warning("avcodec_open() failed: %i",error); + else r->av_opened=1; + } + P=rfc2429_get_P(ph); + PLEN=rfc2429_get_PLEN(ph); + /*printf("receiving new packet; P=%i; V=%i; PLEN=%i; PEBIT=%i\n",P,rfc2429_get_V(ph),PLEN,rfc2429_get_PEBIT(ph)); + */ + gob_num = (ntohl(*p) >> 10) & 0x1f; + ms_trace("gob %i, size %i", gob_num, inm->size); + ms_trace("ms_AVdecoder_process: received %08x %08x", ntohl(p[0]), ntohl(p[1])); + + /* remove H.263 Payload Header */ + if (PLEN>0){ + /* we ignore the redundant picture header and + directly go to the bitstream */ + inm->data+=PLEN; + inm->size-=PLEN; + } + if (P){ + inm->data[0]=inm->data[1]=0; + }else{ + /* no PSC omitted */ + inm->data+=2; + inm->size-=2; + } + + /* accumulate the video packet until we have the rtp markbit*/ + memcpy(r->buf_compressed + r->buf_size, inm->data, inm->size); + r->buf_size += inm->size; + + if (inm->markbit) + { + unsigned char *data = r->buf_compressed; + ms_trace("ms_AVdecoder_process: decoding %08x %08x %08x", ntohl(((unsigned int *)data)[0]), ntohl(((unsigned int *)data)[1]), ntohl(((unsigned int *)data)[2])); + while (r->buf_size > 0) { + len=avcodec_decode_video(&r->av_context,&orig,&got_picture,data,r->buf_size ); + if (len<0) { + ms_warning("ms_AVdecoder_process: error %i.",len); + break; + } + if (got_picture) { + /*g_message("ms_AVdecoder_process: got_picture: width=%i height=%i fmt=%i", + ctx->width,ctx->height,ctx->pix_fmt);*/ + /* set the image in the wanted format */ + outm=ms_message_alloc(); + if (r->obufwrap==NULL){ + r->obufwrap=ms_buffer_new(avpicture_get_size(r->output_pix_fmt,r->width,r->height)); + r->obufwrap->ref_count++; + } + ms_message_set_buf(outm,r->obufwrap); + avpicture_fill(&transformed,(unsigned char *)outm->data,r->output_pix_fmt,r->width,r->height); + img_convert(&transformed, r->output_pix_fmt, + &orig,ctx->pix_fmt,ctx->width,ctx->height); + ms_queue_put(outq,outm); + } + r->buf_size -= len; + data += len; + } + r->buf_size=0; + } + } + ms_message_destroy(inm); +} + + +void ms_AVdecoder_set_width(MSAVDecoder *av,gint w) +{ + /*av->av_context.width=av->width=w;*/ + av->width=w; +} + +void ms_AVdecoder_set_height(MSAVDecoder *av,gint h) +{ + /*av->av_context.height=av->height=h;*/ + av->height=h; +} diff --git a/linphone/mediastreamer/msavdecoder.h b/linphone/mediastreamer/msavdecoder.h new file mode 100644 index 000000000..ca449793a --- /dev/null +++ b/linphone/mediastreamer/msavdecoder.h @@ -0,0 +1,87 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSAVDECODER_H +#define MSAVDECODER_H + +#include "msfilter.h" + + +#include + +/*this is the class that implements a AVdecoder filter*/ + +#define MSAVDECODER_MAX_INPUTS 1 /* max output per filter*/ + + +struct _MSAVDecoder +{ + /* the MSAVDecoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSAVDecoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSQueue *q_inputs[MSAVDECODER_MAX_INPUTS]; + MSQueue *q_outputs[MSAVDECODER_MAX_INPUTS]; + AVCodec *av_codec; /*the AVCodec from which this MSFilter is related */ + AVCodecContext av_context; /* the context of the AVCodec */ + gint av_opened; + int output_pix_fmt; + int width; + int height; + int skip_gob; + unsigned char buf_compressed[100000]; + int buf_size; + MSBuffer *obufwrap; /* alternate buffer, when format change is needed*/ +}; + +typedef struct _MSAVDecoder MSAVDecoder; + +struct _MSAVDecoderClass +{ + /* the MSAVDecoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSAVDecoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +}; + +typedef struct _MSAVDecoderClass MSAVDecoderClass; + +/* PUBLIC */ +#define MS_AVDECODER(filter) ((MSAVDecoder*)(filter)) +#define MS_AVDECODER_CLASS(klass) ((MSAVDecoderClass*)(klass)) + +MSFilter *ms_h263p_decoder_new(); +MSFilter *ms_mpeg_decoder_new(); +MSFilter *ms_mpeg4_decoder_new(); +MSFilter * ms_AVdecoder_new_with_codec(enum CodecID codec_id); + +gint ms_AVdecoder_set_format(MSAVDecoder *dec, gchar *fmt); +void ms_AVdecoder_set_width(MSAVDecoder *av,gint w); +void ms_AVdecoder_set_height(MSAVDecoder *av,gint h); + +/* FOR INTERNAL USE*/ +void ms_AVdecoder_init(MSAVDecoder *r, AVCodec *codec); +void ms_AVdecoder_uninit(MSAVDecoder *enc); +void ms_AVdecoder_class_init(MSAVDecoderClass *klass); +void ms_AVdecoder_destroy( MSAVDecoder *obj); +void ms_AVdecoder_process(MSAVDecoder *r); + +void ms_AVCodec_init(); + +#endif diff --git a/linphone/mediastreamer/msavencoder.c b/linphone/mediastreamer/msavencoder.c new file mode 100644 index 000000000..85a45cfa6 --- /dev/null +++ b/linphone/mediastreamer/msavencoder.c @@ -0,0 +1,258 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msavencoder.h" +#include "msutils.h" + +#ifdef _WIN32 +#include +#else +#include /* ntohl(3) */ +#endif + +extern MSCodecInfo MPEG4info; +extern MSCodecInfo MPEGinfo; +extern MSCodecInfo h263pinfo; + +static MSAVEncoderClass *ms_avencoder_class=NULL; +static void ms_AVencoder_rtp_callback (AVCodecContext *ctx,void *data, int size, int packet_number); + +MSFilter *ms_h263p_encoder_new() +{ + /* temporily prefer CODEC_ID_H263 to CODEC_ID_H263P since + ffmpeg does not comply to H233P at profile=0. + */ + return ms_AVencoder_new_with_codec(CODEC_ID_H263P,&h263pinfo); +} + +MSFilter *ms_mpeg_encoder_new() +{ + return ms_AVencoder_new_with_codec(CODEC_ID_MPEG1VIDEO, &MPEGinfo); +} + +MSFilter *ms_mpeg4_encoder_new() +{ + return ms_AVencoder_new_with_codec(CODEC_ID_MPEG4,&MPEG4info); +} + +MSFilter * ms_AVencoder_new_with_codec(enum CodecID codec_id, MSCodecInfo *info) +{ + MSAVEncoder *enc; + AVCodec *avc; + enc=g_malloc0(sizeof(MSAVEncoder)); + if (ms_avencoder_class==NULL) + { + ms_avencoder_class=g_malloc0(sizeof(MSAVEncoderClass)); + ms_AVencoder_class_init(ms_avencoder_class); + } + MS_FILTER(enc)->klass=(MSFilterClass*)ms_avencoder_class; + avc=avcodec_find_encoder(codec_id); + if (avc==NULL) g_error("unknown av codec."); + ms_AVencoder_init(enc,avc); + return MS_FILTER(enc); +} + + +void ms_AVencoder_init(MSAVEncoder *enc, AVCodec *codec) +{ + AVCodecContext *c=&enc->av_context; + + ms_filter_init(MS_FILTER(enc)); + MS_FILTER(enc)->inqueues=enc->q_inputs; + MS_FILTER(enc)->outqueues=enc->q_outputs; + /* put default values */ + memset(c, 0, sizeof(AVCodecContext)); + avcodec_get_context_defaults(c); + + /* put sample parameters */ + c->bit_rate = 50000; + /* resolution must be a multiple of two */ + c->width = VIDEO_SIZE_CIF_W; + c->height = VIDEO_SIZE_CIF_H; + ms_AVencoder_set_frame_rate(enc,15,1); + c->gop_size = 10; /* emit one intra frame every x frames */ + c->rtp_mode = 1; + c->rtp_payload_size = 1000; + c->opaque = (void *) enc; + c->rtp_callback = ms_AVencoder_rtp_callback; + c->pix_fmt=PIX_FMT_YUV420P; + + enc->av_opened=0; + enc->av_codec=codec; + enc->yuv_buf=NULL; + enc->comp_buf=NULL; + /*set default input format */ + ms_AVencoder_set_format(enc,"RGB24"); + enc->outm=NULL; +} + +void ms_AVencoder_class_init(MSAVEncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->info=0; + MS_FILTER_CLASS(klass)->max_qinputs=MSAVENCODER_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_qoutputs=MSAVENCODER_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=0; + MS_FILTER_CLASS(klass)->w_maxgran=0; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_AVencoder_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_AVencoder_process; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"AVEncoder"); + +} + +void ms_AVencoder_uninit(MSAVEncoder *enc) +{ + if (enc->av_opened) + avcodec_close(&enc->av_context); + if (enc->comp_buf!=NULL) { + ms_buffer_destroy(enc->comp_buf); + enc->comp_buf=NULL; + } + if (enc->yuv_buf!=NULL) { + ms_buffer_destroy(enc->yuv_buf); + enc->yuv_buf=NULL; + } + if (enc->outm!=NULL) ms_message_destroy(enc->outm); + +} +void ms_AVencoder_destroy( MSAVEncoder *obj) +{ + ms_AVencoder_uninit(obj); + g_free(obj); +} + + +void ms_AVencoder_set_frame_rate(MSAVEncoder *obj, gint frame_rate, gint frame_rate_base) +{ + obj->av_context.time_base.num = frame_rate; + obj->av_context.time_base.den = frame_rate_base; +} + +static void ms_AVencoder_rtp_callback (AVCodecContext *ctx, void *data, int size, int packet_number) +{ + MSAVEncoder *r = MS_AVENCODER(ctx->opaque); + MSQueue *outq = r->q_outputs[0]; + MSMessage *outm; + MSMessage *prev_outm=r->outm; + guint32 *p = (guint32 *) data; + gint gob_num = (ntohl(*p) >> 10) & 0x1f; + + /*g_message("ms_AVencoder_rtp_callback: packet %i, size %i, GOB number %i", packet_number, size, gob_num);*/ + ms_trace("ms_AVencoder_rtp_callback: received %08x %08x", ntohl(p[0]), ntohl(p[1])); + /* set the H.263 Payload Header (RFC 2429) ie H263-1998 */ + p[0] = ntohl( (0x04000000) | (ntohl(p[0]) & 0x0000ffff) ); /* P=1, V=0, PLEN=0 */ + ms_trace("ms_AVencoder_rtp_callback: sending %08x %08x", ntohl(p[0]), ntohl(p[1])); + outm = ms_message_new(size); + memcpy(outm->data,data,size); + r->outm=outm; + + /*g_message("output video packet of size %i",size);*/ + if (prev_outm) { + if (gob_num==0) prev_outm->markbit=TRUE; + ms_queue_put(outq, prev_outm); + } +} + +void ms_AVencoder_process(MSAVEncoder *r) +{ + AVFrame orig; + AVFrame pict; + AVCodecContext *c=&r->av_context; + MSQueue *inq,*outq; + MSMessage *inm,*outm; + gint error; + + inq=r->q_inputs[0]; + outq=r->q_outputs[0]; + + /* get a picture from the input queue */ + inm=ms_queue_get(inq); + g_return_if_fail(inm!=NULL); + + /* allocate a new image */ + if (r->yuv_buf==NULL){ + gint bsize = avpicture_get_size(c->pix_fmt,c->width,c->height); + r->yuv_buf=ms_buffer_new(bsize); + r->yuv_buf->ref_count++; + + r->comp_buf=ms_buffer_new(bsize/2); + r->comp_buf->ref_count++; + } + if (!r->av_opened || r->av_context.codec == NULL){ + error=avcodec_open(c, r->av_codec); + ms_trace("image format is %i.",c->pix_fmt); + if (error!=0) { + g_warning("avcodec_open() failed: %i",error); + return; + }else r->av_opened=1; + } + outm=ms_message_alloc(); + /* convert image if necessary */ + if (r->input_pix_fmt!=c->pix_fmt){ + ms_trace("Changing picture format."); + avpicture_fill((AVPicture*)&orig,inm->data,r->input_pix_fmt,c->width,c->height); + avpicture_fill((AVPicture*)&pict,r->yuv_buf->buffer,c->pix_fmt,c->width,c->height); + if (img_convert((AVPicture*)&pict,c->pix_fmt,(AVPicture*)&orig,r->input_pix_fmt,c->width,c->height) < 0) { + g_warning("img_convert failed"); + return; + } + //if (pict.data[0]==NULL) g_error("img_convert failed."); + ms_message_set_buf(outm,r->yuv_buf); + } + else + { + avpicture_fill((AVPicture*)&pict,inm->data,c->pix_fmt,c->width,c->height); + ms_message_set_buf(outm,inm->buffer); + } + /* timestamp used by ffmpeg, unset here */ + pict.pts=AV_NOPTS_VALUE; + error=avcodec_encode_video(c, r->comp_buf->buffer, r->comp_buf->size, &pict); + if (error<=0) ms_warning("ms_AVencoder_process: error %i.",error); + else { + ms_trace("ms_AVencoder_process: video encoding done"); + /* set the mark bit on the last packet, which contains the end of the frame */ + /* + MSMessage *last=ms_queue_peek_last(r->q_outputs[0]); + if (last!=NULL) last->markbit=TRUE; + else g_warning("No last packet ?"); + */ + } + if (r->q_outputs[1]!=NULL) ms_queue_put(r->q_outputs[1],outm); + else ms_message_destroy(outm); + ms_message_destroy(inm); +} + +gint ms_AVencoder_set_format(MSAVEncoder *enc, gchar *fmt) +{ + gint format; + if (strcmp(fmt,"YUV420P")==0) format=PIX_FMT_YUV420P; + else if (strcmp(fmt,"YUV422")==0) format=PIX_FMT_YUV422; + else if (strcmp(fmt,"RGB24")==0) format=PIX_FMT_RGB24; + else if (strcmp(fmt,"BGR24")==0) format=PIX_FMT_BGR24; + else if (strcmp(fmt,"YUV422P")==0) format=PIX_FMT_YUV422P; + else if (strcmp(fmt,"YUV444P")==0) format=PIX_FMT_YUV444P; + else { + g_warning("ms_AVdecoder_set_format: unsupported format %s.",fmt); + return -1; + } + enc->input_pix_fmt=format; + + return 0; +} diff --git a/linphone/mediastreamer/msavencoder.h b/linphone/mediastreamer/msavencoder.h new file mode 100644 index 000000000..429a4bd07 --- /dev/null +++ b/linphone/mediastreamer/msavencoder.h @@ -0,0 +1,92 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSAVENCODER_H +#define MSAVENCODER_H + +#include "msfilter.h" +#include "mscodec.h" +#include + +/*this is the class that implements a AVencoder filter*/ + +#define MSAVENCODER_MAX_INPUTS 1 /* max output per filter*/ +#define MSAVENCODER_MAX_OUTPUTS 2 + +struct _MSAVEncoder +{ + /* the MSAVEncoder derivates from MSFilter, so the MSFilter object MUST be the first of the MSAVEncoder object + in order to the object mechanism to work*/ + MSFilter filter; + MSQueue *q_inputs[MSAVENCODER_MAX_INPUTS]; + MSQueue *q_outputs[MSAVENCODER_MAX_OUTPUTS]; + AVCodec *av_codec; /*the AVCodec from which this MSFilter is related */ + AVCodecContext av_context; /* the context of the AVCodec */ + gint input_pix_fmt; + gint av_opened; + MSBuffer *comp_buf; + MSBuffer *yuv_buf; + MSMessage *outm; +}; + +typedef struct _MSAVEncoder MSAVEncoder; +/* MSAVEncoder always outputs planar YUV and accept any incoming format you should setup using + ms_AVencoder_set_format() +q_outputs[0] is the compressed video stream output +q_outputs[1] is a YUV planar buffer of the image it receives in input. +*/ + + +struct _MSAVEncoderClass +{ + /* the MSAVEncoder derivates from MSFilter, so the MSFilter class MUST be the first of the MSAVEncoder class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +}; + +typedef struct _MSAVEncoderClass MSAVEncoderClass; + +/* PUBLIC */ +#define MS_AVENCODER(filter) ((MSAVEncoder*)(filter)) +#define MS_AVENCODER_CLASS(klass) ((MSAVEncoderClass*)(klass)) + +MSFilter *ms_h263p_encoder_new(); +MSFilter *ms_mpeg_encoder_new(); +MSFilter *ms_mpeg4_encoder_new(); +MSFilter * ms_AVencoder_new_with_codec(enum CodecID codec_id, MSCodecInfo *info); + +gint ms_AVencoder_set_format(MSAVEncoder *enc, gchar *fmt); + +#define ms_AVencoder_set_width(av,w) (av)->av_context.width=(w) +#define ms_AVencoder_set_height(av,h) (av)->av_context.height=(h) +#define ms_AVencoder_set_bit_rate(av,r) (av)->av_context.bit_rate=(r) + +void ms_AVencoder_set_frame_rate(MSAVEncoder *enc, gint frame_rate, gint frame_rate_base); + +/* FOR INTERNAL USE*/ +void ms_AVencoder_init(MSAVEncoder *r, AVCodec *codec); +void ms_AVencoder_uninit(MSAVEncoder *enc); +void ms_AVencoder_class_init(MSAVEncoderClass *klass); +void ms_AVencoder_destroy( MSAVEncoder *obj); +void ms_AVencoder_process(MSAVEncoder *r); + + +#endif diff --git a/linphone/mediastreamer/msbuffer.c b/linphone/mediastreamer/msbuffer.c new file mode 100644 index 000000000..dedef45f4 --- /dev/null +++ b/linphone/mediastreamer/msbuffer.c @@ -0,0 +1,91 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msbuffer.h" +#include "msutils.h" +#include + + + +MSBuffer * ms_buffer_new(guint32 size) +{ + MSBuffer *buf; + buf=(MSBuffer*)g_malloc(sizeof(MSBuffer)+size); + buf->ref_count=0; + buf->size=size; + ms_trace("ms_buffer_new: Allocating buffer of %i bytes.",size); + /* allocate the data buffer: there is a lot of optmisation that can be done by using a pool of cached buffers*/ + buf->buffer=((char*)(buf))+sizeof(MSBuffer); /* to avoid to do two allocations, + buffer info and buffer are contigous.*/ + buf->freefn=NULL; + buf->freearg=NULL; + return(buf); +} + +MSBuffer *ms_buffer_new_with_buf(char *extbuf, int size,void (*freefn)(void *), void *freearg) +{ + MSBuffer *buf; + buf=(MSBuffer*)g_malloc(sizeof(MSBuffer)); + buf->ref_count=0; + buf->size=size; + buf->buffer=extbuf; + buf->freefn=freefn; + buf->freearg=freearg; + return(buf); +} + + +void ms_buffer_destroy(MSBuffer *buf) +{ + if (buf->freefn!=NULL) buf->freefn(buf->freearg); + g_free(buf); +} + +MSMessage *ms_message_alloc() +{ + MSMessage *m=g_malloc(sizeof(MSMessage)); + memset(m,0,sizeof(MSMessage)); + return m; +} + +MSMessage *ms_message_new(gint size) +{ + MSMessage *m=ms_message_alloc(); + MSBuffer *buf=ms_buffer_new(size); + ms_message_set_buf(m,buf); + return m; +} + +void ms_message_destroy(MSMessage *m) +{ + /* the buffer is freed if its ref_count goes to zero */ + if (m->buffer!=NULL){ + m->buffer->ref_count--; + if (m->buffer->ref_count==0) ms_buffer_destroy(m->buffer); + } + g_free(m); +} + +MSMessage * ms_message_dup(MSMessage *m) +{ + MSMessage *msg=ms_message_alloc(); + ms_message_set_buf(msg,m->buffer); + return msg; +} diff --git a/linphone/mediastreamer/msbuffer.h b/linphone/mediastreamer/msbuffer.h new file mode 100644 index 000000000..d182f1b80 --- /dev/null +++ b/linphone/mediastreamer/msbuffer.h @@ -0,0 +1,78 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSBUFFER_H +#define MSBUFFER_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_GLIB +#include +#else +#include +#endif + + +#define MS_BUFFER_LARGE 4092 + + +typedef struct _MSBuffer +{ + gchar *buffer; + guint32 size; + gint ref_count; + void (*freefn)(void *); + void *freearg; +}MSBuffer; + +MSBuffer * ms_buffer_new(guint32 size); +MSBuffer *ms_buffer_new_with_buf(char *extbuf, int size,void (*freefn)(void *), void *freearg); +void ms_buffer_destroy(MSBuffer *buf); + +struct _MSMessage +{ + MSBuffer *buffer; /* points to a MSBuffer */ + char *data; /*points to buffer->buffer */ + guint32 size; /* the size of the buffer to read in data. It may not be the + physical size (I mean buffer->buffer->size */ + struct _MSMessage *next; + struct _MSMessage *prev; /* MSMessage are queued into MSQueues */ + gboolean markbit; +}; + +typedef struct _MSMessage MSMessage; + +MSMessage *ms_message_new(gint size); + +#define ms_message_set_buf(m,b) do { (b)->ref_count++; (m)->buffer=(b); (m)->data=(b)->buffer; (m)->size=(b)->size; }while(0) +#define ms_message_unset_buf(m) do { (m)->buffer->ref_count--; (m)->buffer=NULL; (m)->size=0; (m)->data=NULL; } while(0) + +#define ms_message_size(m) (m)->size +void ms_message_destroy(MSMessage *m); + +MSMessage * ms_message_dup(MSMessage *m); + +/* allocate a single message without buffer */ +MSMessage *ms_message_alloc(); + +#endif diff --git a/linphone/mediastreamer/mscodec.c b/linphone/mediastreamer/mscodec.c new file mode 100644 index 000000000..092db1328 --- /dev/null +++ b/linphone/mediastreamer/mscodec.c @@ -0,0 +1,259 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mscodec.h" + +#ifndef _WIN32 +# include "msGSMdecoder.h" +# include "msLPC10decoder.h" +#endif +#include "msMUlawdec.h" +#include "msAlawdec.h" + +#ifdef TRUESPEECH +extern MSCodecInfo TrueSpeechinfo; +#endif + +#ifdef VIDEO_ENABLED +extern void ms_AVCodec_init(); +#endif + +#define UDP_HDR_SZ 8 +#define RTP_HDR_SZ 12 +#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/ + + + + +/* register all statically linked codecs */ +void ms_codec_register_all() +{ +#ifndef _WIN32 + ms_filter_register(MS_FILTER_INFO(&GSMinfo)); + ms_filter_register(MS_FILTER_INFO(&LPC10info)); +#endif + ms_filter_register(MS_FILTER_INFO(&MULAWinfo)); + ms_filter_register(MS_FILTER_INFO(&ALAWinfo)); +#ifdef TRUESPEECH + ms_filter_register(MS_FILTER_INFO(&TrueSpeechinfo)); +#endif +#ifdef VIDEO_ENABLED + ms_AVCodec_init(); +#endif + +} + +/* returns a list of MSCodecInfo */ +GList * ms_codec_get_all_audio() +{ + GList *audio_codecs=NULL; + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if (info->type==MS_FILTER_AUDIO_CODEC){ + audio_codecs=g_list_append(audio_codecs,info); + } + elem=g_list_next(elem); + } + return audio_codecs; +} + + +MSCodecInfo * ms_audio_codec_info_get(gchar *name) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ( (info->type==MS_FILTER_AUDIO_CODEC) ){ + MSCodecInfo *codinfo=(MSCodecInfo *)info; + if (strcmp(codinfo->description,name)==0){ + return MS_CODEC_INFO(info); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSCodecInfo * ms_video_codec_info_get(gchar *name) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ( (info->type==MS_FILTER_VIDEO_CODEC) ){ + MSCodecInfo *codinfo=(MSCodecInfo *)info; + if (strcmp(codinfo->description,name)==0){ + return MS_CODEC_INFO(info); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +/* returns a list of MSCodecInfo */ +GList * ms_codec_get_all_video() +{ + GList *video_codecs=NULL; + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if (info->type==MS_FILTER_VIDEO_CODEC){ + video_codecs=g_list_append(video_codecs,info); + } + elem=g_list_next(elem); + } + return video_codecs; +} + +MSFilter * ms_encoder_new(gchar *name) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (strcmp(info->name,name)==0){ + return codinfo->encoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSFilter * ms_decoder_new(gchar *name) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (strcmp(info->name,name)==0){ + return codinfo->decoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSFilter * ms_encoder_new_with_pt(gint pt) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (codinfo->pt==pt){ + return codinfo->encoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSFilter * ms_decoder_new_with_pt(gint pt) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (codinfo->pt==pt){ + return codinfo->decoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSFilter * ms_decoder_new_with_string_id(gchar *id) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (strcasecmp(codinfo->description,id)==0){ + return codinfo->decoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} + +MSFilter * ms_encoder_new_with_string_id(gchar *id) +{ + GList *elem=filter_list; + MSFilterInfo *info; + while (elem!=NULL) + { + info=(MSFilterInfo *)elem->data; + if ((info->type==MS_FILTER_AUDIO_CODEC) || (info->type==MS_FILTER_VIDEO_CODEC)){ + MSCodecInfo *codinfo=(MSCodecInfo *)elem->data; + if (strcasecmp(codinfo->description,id)==0){ + return codinfo->encoder(); + } + } + elem=g_list_next(elem); + } + return NULL; +} +/* return 0 if codec can be used with bandwidth, -1 else*/ +int ms_codec_is_usable(MSCodecInfo *codec,double bandwidth) +{ + double codec_band; + double npacket; + double packet_size; + + if (((MSFilterInfo*)codec)->type==MS_FILTER_AUDIO_CODEC) + { + /* calculate the total bandwdith needed by codec (including headers for rtp, udp, ip)*/ + /* number of packet per second*/ + npacket=2.0*(double)(codec->rate)/(double)(codec->fr_size); + packet_size=(double)(codec->dt_size)+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; + codec_band=packet_size*8.0*npacket; + } + else return -1; + return(codec_band +#include +#include +#include +#include +#include + +static MSCopyClass *ms_copy_class=NULL; + +MSFilter * ms_copy_new(void) +{ + MSCopy *r; + + r=g_new(MSCopy,1); + ms_copy_init(r); + if (ms_copy_class==NULL) + { + ms_copy_class=g_new(MSCopyClass,1); + ms_copy_class_init(ms_copy_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_copy_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_copy_init(MSCopy *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->r_mingran=MSCOPY_DEF_GRAN; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSCOPY_MAX_INPUTS); + memset(r->f_outputs,0,sizeof(MSFifo*)*MSCOPY_MAX_INPUTS); +} + +void ms_copy_class_init(MSCopyClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"fifocopier"); + MS_FILTER_CLASS(klass)->max_finputs=MSCOPY_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSCOPY_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=MSCOPY_DEF_GRAN; + MS_FILTER_CLASS(klass)->w_maxgran=MSCOPY_DEF_GRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_copy_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_copy_process; +} + +void ms_copy_process(MSCopy *r) +{ + MSFifo *fi,*fo; + int err1; + gint gran=MS_FILTER(r)->klass->r_maxgran; + void *s,*d; + + /* process output fifos, but there is only one for this class of filter*/ + + fi=r->f_inputs[0]; + fo=r->f_outputs[0]; + if (fi!=NULL) + { + err1=ms_fifo_get_read_ptr(fi,gran,&s); + if (err1>0) err1=ms_fifo_get_write_ptr(fo,gran,&d); + if (err1>0) + { + memcpy(d,s,gran); + } + } +} + +void ms_copy_destroy( MSCopy *obj) +{ + g_free(obj); +} diff --git a/linphone/mediastreamer/mscopy.h b/linphone/mediastreamer/mscopy.h new file mode 100644 index 000000000..2b5749b99 --- /dev/null +++ b/linphone/mediastreamer/mscopy.h @@ -0,0 +1,61 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSCOPY_H +#define MSCOPY_H + +#include "msfilter.h" + + +/*this is the class that implements a copy filter*/ + +#define MSCOPY_MAX_INPUTS 1 /* max output per filter*/ + +#define MSCOPY_DEF_GRAN 64 /* the default granularity*/ + +typedef struct _MSCopy +{ + /* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSCOPY_MAX_INPUTS]; + MSFifo *f_outputs[MSCOPY_MAX_INPUTS]; +} MSCopy; + +typedef struct _MSCopyClass +{ + /* the MSCopy derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSCopyClass; + +/* PUBLIC */ +#define MS_COPY(filter) ((MSCopy*)(filter)) +#define MS_COPY_CLASS(klass) ((MSCopyClass*)(klass)) +MSFilter * ms_copy_new(void); + +/* FOR INTERNAL USE*/ +void ms_copy_init(MSCopy *r); +void ms_copy_class_init(MSCopyClass *klass); +void ms_copy_destroy( MSCopy *obj); +void ms_copy_process(MSCopy *r); + +#endif diff --git a/linphone/mediastreamer/msfdispatcher.c b/linphone/mediastreamer/msfdispatcher.c new file mode 100644 index 000000000..692bbb7b0 --- /dev/null +++ b/linphone/mediastreamer/msfdispatcher.c @@ -0,0 +1,94 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a dispatcher of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msfdispatcher.h" + +static MSFdispatcherClass *ms_fdispatcher_class=NULL; + +MSFilter * ms_fdispatcher_new(void) +{ + MSFdispatcher *obj; + obj=g_malloc(sizeof(MSFdispatcher)); + if (ms_fdispatcher_class==NULL){ + ms_fdispatcher_class=g_malloc(sizeof(MSFdispatcherClass)); + ms_fdispatcher_class_init(ms_fdispatcher_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_fdispatcher_class); + ms_fdispatcher_init(obj); + return MS_FILTER(obj); +} + + +void ms_fdispatcher_init(MSFdispatcher *obj) +{ + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->infifos=obj->f_inputs; + MS_FILTER(obj)->outfifos=obj->f_outputs; + MS_FILTER(obj)->r_mingran=MS_FDISPATCHER_DEF_GRAN; + memset(obj->f_inputs,0,sizeof(MSFifo*)*MS_FDISPATCHER_MAX_INPUTS); + memset(obj->f_outputs,0,sizeof(MSFifo*)*MS_FDISPATCHER_MAX_OUTPUTS); +} + + + +void ms_fdispatcher_class_init(MSFdispatcherClass *klass) +{ + MSFilterClass *parent_class=MS_FILTER_CLASS(klass); + ms_filter_class_init(parent_class); + ms_filter_class_set_name(parent_class,"fdispatcher"); + parent_class->max_finputs=MS_FDISPATCHER_MAX_INPUTS; + parent_class->max_foutputs=MS_FDISPATCHER_MAX_OUTPUTS; + parent_class->r_maxgran=MS_FDISPATCHER_DEF_GRAN; + parent_class->w_maxgran=MS_FDISPATCHER_DEF_GRAN; + parent_class->destroy=(MSFilterDestroyFunc)ms_fdispatcher_destroy; + parent_class->process=(MSFilterProcessFunc)ms_fdispatcher_process; +} + + +void ms_fdispatcher_destroy( MSFdispatcher *obj) +{ + g_free(obj); +} + +void ms_fdispatcher_process(MSFdispatcher *obj) +{ + gint i; + MSFifo *inf=obj->f_inputs[0]; + + + if (inf!=NULL){ + void *s,*d; + /* dispatch fifos */ + while ( ms_fifo_get_read_ptr(inf,MS_FDISPATCHER_DEF_GRAN,&s) >0 ){ + for (i=0;if_outputs[i]; + + if (outf!=NULL) + { + ms_fifo_get_write_ptr(outf,MS_FDISPATCHER_DEF_GRAN,&d); + if (d!=NULL) memcpy(d,s,MS_FDISPATCHER_DEF_GRAN); + } + } + } + } +} + + diff --git a/linphone/mediastreamer/msfdispatcher.h b/linphone/mediastreamer/msfdispatcher.h new file mode 100644 index 000000000..b1b457df5 --- /dev/null +++ b/linphone/mediastreamer/msfdispatcher.h @@ -0,0 +1,61 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a dispatcher of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSFDISPATCHER_H +#define MSFDISPATCHER_H + +#include "msfilter.h" + + +/*this is the class that implements a fdispatcher filter*/ + +#define MS_FDISPATCHER_MAX_INPUTS 1 +#define MS_FDISPATCHER_MAX_OUTPUTS 5 +#define MS_FDISPATCHER_DEF_GRAN 64 /* the default granularity*/ + +typedef struct _MSFdispatcher +{ + /* the MSFdispatcher derivates from MSFilter, so the MSFilter object MUST be the first of the MSFdispatcher object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MS_FDISPATCHER_MAX_INPUTS]; + MSFifo *f_outputs[MS_FDISPATCHER_MAX_OUTPUTS]; +} MSFdispatcher; + +typedef struct _MSFdispatcherClass +{ + /* the MSFdispatcher derivates from MSFilter, so the MSFilter class MUST be the first of the MSFdispatcher class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSFdispatcherClass; + +/* PUBLIC */ +#define MS_FDISPATCHER(filter) ((MSFdispatcher*)(filter)) +#define MS_FDISPATCHER_CLASS(klass) ((MSFdispatcherClass*)(klass)) +MSFilter * ms_fdispatcher_new(void); + +/* FOR INTERNAL USE*/ +void ms_fdispatcher_init(MSFdispatcher *r); +void ms_fdispatcher_class_init(MSFdispatcherClass *klass); +void ms_fdispatcher_destroy( MSFdispatcher *obj); +void ms_fdispatcher_process(MSFdispatcher *r); + +#endif diff --git a/linphone/mediastreamer/msfifo.c b/linphone/mediastreamer/msfifo.c new file mode 100644 index 000000000..871cf0a87 --- /dev/null +++ b/linphone/mediastreamer/msfifo.c @@ -0,0 +1,167 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "msutils.h" +#include "msfifo.h" + +MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset) +{ + MSFifo *fifo; + gint saved_offset=MAX(r_gran+r_offset,w_offset); + + g_return_val_if_fail(saved_offset<=(buf->size),NULL); + fifo=g_malloc(sizeof(MSFifo)); + fifo->buffer=buf; + fifo->r_gran=r_gran; + fifo->w_gran=w_gran; + fifo->begin=fifo->wr_ptr=fifo->rd_ptr=buf->buffer+saved_offset; + fifo->readsize=0; + fifo->size=fifo->writesize=buf->size-saved_offset; + fifo->saved_offset= saved_offset; + fifo->r_end=fifo->w_end=buf->buffer+buf->size; + fifo->pre_end=fifo->w_end-saved_offset; + buf->ref_count++; + fifo->prev_data=NULL; + fifo->next_data=NULL; + ms_trace("fifo base=%x, begin=%x, end=%x, saved_offset=%i, size=%i" + ,fifo->buffer->buffer,fifo->begin,fifo->w_end,fifo->saved_offset,fifo->size); + return(fifo); +} + +MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset, + gint min_fifo_size) +{ + MSFifo *fifo; + MSBuffer *buf; + gint saved_offset=MAX(r_gran+r_offset,w_offset); + gint fifo_size; + if (min_fifo_size==0) min_fifo_size=w_gran; + + /* we must allocate a fifo with a size multiple of min_fifo_size, + with a saved_offset */ + if (min_fifo_size>MS_BUFFER_LARGE) + fifo_size=(min_fifo_size) + saved_offset; + else fifo_size=(6*min_fifo_size) + saved_offset; + buf=ms_buffer_new(fifo_size); + fifo=ms_fifo_new(buf,r_gran,w_gran,r_offset,w_offset); + ms_trace("fifo_size=%i",fifo_size); + return(fifo); +} + +void ms_fifo_destroy( MSFifo *fifo) +{ + g_free(fifo); +} + +void ms_fifo_destroy_with_buffer(MSFifo *fifo) +{ + ms_buffer_destroy(fifo->buffer); + ms_fifo_destroy(fifo); +} + +gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr) +{ + gchar *rnext; + + *ret_ptr=NULL; + //ms_trace("ms_fifo_get_read_ptr: entering."); + g_return_val_if_fail(bsize<=fifo->r_gran,-EINVAL); + + if (bsize>fifo->readsize) + { + ms_trace("Not enough data: bsize=%i, readsize=%i",bsize,fifo->readsize); + return -1; + } + + rnext=fifo->rd_ptr+bsize; + if (rnext<=fifo->r_end){ + + *ret_ptr=fifo->rd_ptr; + fifo->rd_ptr=rnext; + }else{ + int unread=fifo->r_end-fifo->rd_ptr; + *ret_ptr=fifo->begin-unread; + memcpy(fifo->buffer->buffer,fifo->r_end-fifo->saved_offset,fifo->saved_offset); + fifo->rd_ptr=(char*)(*ret_ptr) + bsize; + fifo->r_end=fifo->w_end; /* this is important ! */ + ms_trace("moving read ptr to %x",fifo->rd_ptr); + + } + /* update write size*/ + fifo->writesize+=bsize; + fifo->readsize-=bsize; + return bsize; +} + + +void ms_fifo_update_write_ptr(MSFifo *fifo, gint written){ + gint reserved=fifo->wr_ptr-fifo->prev_wr_ptr; + gint unwritten; + g_return_if_fail(reserved>=0); + unwritten=reserved-written; + g_return_if_fail(unwritten>=0); + /* fix readsize and writesize */ + fifo->readsize-=unwritten; + fifo->writesize+=unwritten; + fifo->wr_ptr=fifo->prev_wr_ptr+written; +} + +gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr) +{ + gchar *wnext; + + *ret_ptr=NULL; + //ms_trace("ms_fifo_get_write_ptr: Entering."); + g_return_val_if_fail(bsize<=fifo->w_gran,-EINVAL); + if (bsize>fifo->writesize) + { + ms_trace("Not enough space: bsize=%i, writesize=%i",bsize,fifo->writesize); + *ret_ptr=NULL; + return -1; + } + wnext=fifo->wr_ptr+bsize; + if (wnext<=fifo->w_end){ + *ret_ptr=fifo->wr_ptr; + fifo->wr_ptr=wnext; + }else{ + *ret_ptr=fifo->begin; + fifo->r_end=fifo->wr_ptr; + fifo->wr_ptr=fifo->begin+bsize; + ms_trace("moving write ptr to %x",fifo->wr_ptr); + } + fifo->prev_wr_ptr=*ret_ptr; + /* update readsize*/ + fifo->readsize+=bsize; + fifo->writesize-=bsize; + //ms_trace("ms_fifo_get_write_ptr: readsize=%i, writesize=%i",fifo->readsize,fifo->writesize); + return bsize; +} + +gint ms_fifo_get_rw_ptr(MSFifo *f1,void **p1,gint minsize1, + MSFifo *f2,void **p2,gint minsize2) +{ + gint rbsize,wbsize; + + rbsize=MIN(f1->readsize,(f1->pre_end-f1->rd_ptr)); + wbsize=MIN(f2->writesize,(f2->w_end-f2->wr_ptr)); + return 0; +} diff --git a/linphone/mediastreamer/msfifo.h b/linphone/mediastreamer/msfifo.h new file mode 100644 index 000000000..fde1bece1 --- /dev/null +++ b/linphone/mediastreamer/msfifo.h @@ -0,0 +1,73 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_GLIB +#include +#else +#include "glist.h" +#endif +#include "msbuffer.h" + +typedef struct _MSFifo +{ + gint r_gran; /*maximum granularity for reading*/ + gint w_gran; /*maximum granularity for writing*/ + gchar * rd_ptr; /* read pointer on the position where there is something to read on the MSBuffer */ + guint32 readsize; + gchar * wr_ptr; + gchar * prev_wr_ptr; + guint32 writesize; /* write pointer on the position where it is possible to write on the MSBuffer */ + gchar * begin; /* rd_ptr et wr_ptr must all be >=begin*/ + guint32 size; /* the length of the fifo, but this may not be equal to buffer->size*/ + guint32 saved_offset; + gchar * pre_end; /* the end of the buffer that is copied at the begginning when we wrap around*/ + gchar * w_end; /* when a wr ptr is expected to exceed end_offset, + it must be wrapped around to go at the beginning of the buffer. This is the end of the buffer*/ + gchar * r_end; /* this is the last position written at the end of the fifo. If a read ptr is expected to + exceed this pointer, it must be put at the begginning of the buffer */ + void *prev_data; /*user data, usually the writing MSFilter*/ + void *next_data; /* user data, usually the reading MSFilter */ + MSBuffer *buffer; +} MSFifo; + +/* constructor*/ +/* r_gran: max granularity for reading (in number of bytes)*/ +/* w_gran: max granularity for writing (in number of bytes)*/ +/* r_offset: number of bytes that are kept available behind read pointer (for recursive filters)*/ +/* w_offset: number of bytes that are kept available behind write pointer (for recursive filters)*/ +/* buf is a MSBuffer that should be compatible with the above parameter*/ +MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset); + +/*does the same that ms_fifo_new(), but also allocate a compatible buffer automatically*/ +MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset, gint min_buffer_size); + +void ms_fifo_destroy( MSFifo *fifo); + +void ms_fifo_destroy_with_buffer(MSFifo *fifo); + +/* get data to read */ +gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr); + +/* get a buffer to write*/ +gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr); + +/* in case the buffer got by ms_fifo_get_write_ptr() could not be filled completely, you must +tell it by using this function */ +void ms_fifo_update_write_ptr(MSFifo *fifo, gint written); diff --git a/linphone/mediastreamer/msfilter.c b/linphone/mediastreamer/msfilter.c new file mode 100644 index 000000000..c67e9f0e2 --- /dev/null +++ b/linphone/mediastreamer/msfilter.c @@ -0,0 +1,537 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include +#include "msfilter.h" + + + +void ms_filter_init(MSFilter *filter) +{ + filter->finputs=0; + filter->foutputs=0; + filter->qinputs=0; + filter->qoutputs=0; + filter->infifos=NULL; + filter->outfifos=NULL; + filter->inqueues=NULL; + filter->outqueues=NULL; + filter->lock=g_mutex_new(); + filter->min_fifo_size=0x7fff; + filter->notify_event=NULL; + filter->userdata=NULL; +} + +void ms_filter_uninit(MSFilter *filter) +{ + g_mutex_free(filter->lock); +} + +void ms_filter_class_init(MSFilterClass *filterclass) +{ + filterclass->name=NULL; + filterclass->max_finputs=0; + filterclass->max_foutputs=0; + filterclass->max_qinputs=0; + filterclass->max_qoutputs=0; + filterclass->r_maxgran=0; + filterclass->w_maxgran=0; + filterclass->r_offset=0; + filterclass->w_offset=0; + filterclass->set_property=NULL; + filterclass->get_property=NULL; + filterclass->setup=NULL; + filterclass->unsetup=NULL; + filterclass->process=NULL; + filterclass->destroy=NULL; + filterclass->attributes=0; + filterclass->ref_count=0; +} + +/* find output queue */ +gint find_oq(MSFilter *m1,MSQueue *oq) +{ + gint i; + + for (i=0;imax_qoutputs;i++){ + if (m1->outqueues[i]==oq) return i; + } + + return -1; +} + +/* find input queue */ +gint find_iq(MSFilter *m1,MSQueue *iq) +{ + gint i; + for (i=0;imax_qinputs;i++){ + if (m1->inqueues[i]==iq) return i; + } + return -1; +} + +/* find output fifo */ +gint find_of(MSFilter *m1,MSFifo *of) +{ + gint i; + for (i=0;imax_foutputs;i++){ + if (m1->outfifos[i]==of) return i; + } + + return -1; +} + +/* find input fifo */ +gint find_if(MSFilter *m1,MSFifo *inf) +{ + gint i; + + for (i=0;imax_finputs;i++){ + if (m1->infifos[i]==inf) return i; + } + + return -1; +} + +#define find_free_iq(_m1) find_iq(_m1,NULL) +#define find_free_oq(_m1) find_oq(_m1,NULL) +#define find_free_if(_m1) find_if(_m1,NULL) +#define find_free_of(_m1) find_of(_m1,NULL) + +int ms_filter_add_link(MSFilter *m1, MSFilter *m2) +{ + gint m1_q=-1; + gint m1_f=-1; + gint m2_q=-1; + gint m2_f=-1; + /* determine the type of link we can add */ + m1_q=find_free_oq(m1); + m1_f=find_free_of(m1); + m2_q=find_free_iq(m2); + m2_f=find_free_if(m2); + if ((m1_q!=-1) && (m2_q!=-1)){ + /* link with queues */ + ms_trace("m1_q=%i , m2_q=%i",m1_q,m2_q); + return ms_filter_link(m1,m1_q,m2,m2_q,LINK_QUEUE); + } + if ((m1_f!=-1) && (m2_f!=-1)){ + /* link with queues */ + ms_trace("m1_f=%i , m2_f=%i",m1_f,m2_f); + return ms_filter_link(m1,m1_f,m2,m2_f,LINK_FIFO); + } + g_warning("ms_filter_add_link: could not link."); + return -1; +} +/** + * ms_filter_link: + * @m1: A #MSFilter object. + * @pin1: The pin number on @m1. + * @m2: A #MSFilter object. + * @pin2: The pin number on @m2. + * @linktype: Type of connection, it may be #LINK_QUEUE, #LINK_FIFOS. + * + * This function links two MSFilter object between them. It must be used to make chains of filters. + * All data outgoing from pin1 of m1 will go to the input pin2 of m2. + * The way to communicate can be fifos or queues, depending of the nature of the filters. Filters can have + * multiple queue pins and multiple fifo pins, but most of them have only one queue input/output or only one + * fifo input/output. Fifos are usally used by filters doing audio processing, while queues are used by filters doing + * video processing. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_filter_link(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2, int linktype) +{ + MSQueue *q; + MSFifo *fifo; + + g_message("ms_filter_add_link: %s,%i -> %s,%i",m1->klass->name,pin1,m2->klass->name,pin2); + switch(linktype) + { + case LINK_QUEUE: + /* Are filter m1 and m2 able to accept more queues connections ?*/ + g_return_val_if_fail(m1->qoutputsmax_qoutputs,-EMLINK); + g_return_val_if_fail(m2->qinputsmax_qinputs,-EMLINK); + /* Are filter m1 and m2 valid with their inputs and outputs ?*/ + g_return_val_if_fail(m1->outqueues!=NULL,-EFAULT); + g_return_val_if_fail(m2->inqueues!=NULL,-EFAULT); + /* are the requested pins exists ?*/ + g_return_val_if_fail(pin1max_qoutputs,-EINVAL); + g_return_val_if_fail(pin2max_qinputs,-EINVAL); + /* are the requested pins free ?*/ + g_return_val_if_fail(m1->outqueues[pin1]==NULL,-EBUSY); + g_return_val_if_fail(m2->inqueues[pin2]==NULL,-EBUSY); + + q=ms_queue_new(); + m1->outqueues[pin1]=m2->inqueues[pin2]=q; + m1->qoutputs++; + m2->qinputs++; + q->prev_data=(void*)m1; + q->next_data=(void*)m2; + break; + case LINK_FIFO: + /* Are filter m1 and m2 able to accept more fifo connections ?*/ + g_return_val_if_fail(m1->foutputsmax_foutputs,-EMLINK); + g_return_val_if_fail(m2->finputsmax_finputs,-EMLINK); + /* Are filter m1 and m2 valid with their inputs and outputs ?*/ + g_return_val_if_fail(m1->outfifos!=NULL,-EFAULT); + g_return_val_if_fail(m2->infifos!=NULL,-EFAULT); + /* are the requested pins exists ?*/ + g_return_val_if_fail(pin1max_foutputs,-EINVAL); + g_return_val_if_fail(pin2max_finputs,-EINVAL); + /* are the requested pins free ?*/ + g_return_val_if_fail(m1->outfifos[pin1]==NULL,-EBUSY); + g_return_val_if_fail(m2->infifos[pin2]==NULL,-EBUSY); + + if (MS_FILTER_GET_CLASS(m1)->attributes & FILTER_IS_SOURCE) + { + /* configure min_fifo_size */ + fifo=ms_fifo_new_with_buffer(MS_FILTER_GET_CLASS(m2)->r_maxgran, + MS_FILTER_GET_CLASS(m1)->w_maxgran, + MS_FILTER_GET_CLASS(m2)->r_offset, + MS_FILTER_GET_CLASS(m1)->w_offset, + MS_FILTER_GET_CLASS(m1)->w_maxgran); + m2->min_fifo_size=MS_FILTER_GET_CLASS(m1)->w_maxgran; + } + else + { + gint next_size; + ms_trace("ms_filter_add_link: min_fifo_size=%i",m1->min_fifo_size); + fifo=ms_fifo_new_with_buffer(MS_FILTER_GET_CLASS(m2)->r_maxgran, + MS_FILTER_GET_CLASS(m1)->w_maxgran, + MS_FILTER_GET_CLASS(m2)->r_offset, + MS_FILTER_GET_CLASS(m1)->w_offset, + m1->min_fifo_size); + if (MS_FILTER_GET_CLASS(m2)->r_maxgran>0){ + next_size=(m1->min_fifo_size* + (MS_FILTER_GET_CLASS(m2)->w_maxgran)) / + (MS_FILTER_GET_CLASS(m2)->r_maxgran); + }else next_size=m1->min_fifo_size; + ms_trace("ms_filter_add_link: next_size=%i",next_size); + m2->min_fifo_size=next_size; + } + + + m1->outfifos[pin1]=m2->infifos[pin2]=fifo; + m1->foutputs++; + m2->finputs++; + fifo->prev_data=(void*)m1; + fifo->next_data=(void*)m2; + break; + } + return 0; +} +/** + * ms_filter_unlink: + * @m1: A #MSFilter object. + * @pin1: The pin number on @m1. + * @m2: A #MSFilter object. + * @pin2: The pin number on @m2. + * @linktype: Type of connection, it may be #LINK_QUEUE, #LINK_FIFOS. + * + * Unlink @pin1 of filter @m1 from @pin2 of filter @m2. @linktype specifies what type of connection is removed. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_filter_unlink(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2,gint linktype) +{ + switch(linktype) + { + case LINK_QUEUE: + /* Are filter m1 and m2 valid with their inputs and outputs ?*/ + g_return_val_if_fail(m1->outqueues!=NULL,-EFAULT); + g_return_val_if_fail(m2->inqueues!=NULL,-EFAULT); + /* are the requested pins exists ?*/ + g_return_val_if_fail(pin1max_qoutputs,-EINVAL); + g_return_val_if_fail(pin2max_qinputs,-EINVAL); + /* are the requested pins busy ?*/ + g_return_val_if_fail(m1->outqueues[pin1]!=NULL,-ENOENT); + g_return_val_if_fail(m2->inqueues[pin2]!=NULL,-ENOENT); + /* are the two pins connected together ?*/ + g_return_val_if_fail(m1->outqueues[pin1]==m2->inqueues[pin2],-EINVAL); + + ms_queue_destroy(m1->outqueues[pin1]); + m1->outqueues[pin1]=m2->inqueues[pin2]=NULL; + m1->qoutputs--; + m2->qinputs--; + + break; + case LINK_FIFO: + /* Are filter m1 and m2 valid with their inputs and outputs ?*/ + g_return_val_if_fail(m1->outfifos!=NULL,-EFAULT); + g_return_val_if_fail(m2->infifos!=NULL,-EFAULT); + /* are the requested pins exists ?*/ + g_return_val_if_fail(pin1max_foutputs,-EINVAL); + g_return_val_if_fail(pin2max_finputs,-EINVAL); + /* are the requested pins busy ?*/ + g_return_val_if_fail(m1->outfifos[pin1]!=NULL,-ENOENT); + g_return_val_if_fail(m2->infifos[pin2]!=NULL,-ENOENT); + /* are the two pins connected together ?*/ + g_return_val_if_fail(m1->outfifos[pin1]==m2->infifos[pin2],-EINVAL); + ms_fifo_destroy_with_buffer(m1->outfifos[pin1]); + m1->outfifos[pin1]=m2->infifos[pin2]=NULL; + m1->foutputs--; + m2->finputs--; + break; + } + return 0; +} + +/** + *ms_filter_remove_links: + *@m1: a filter + *@m2: another filter. + * + * Removes all links between m1 and m2. + * + *Returns: 0 if one more link have been removed, -1 if not. +**/ +gint ms_filter_remove_links(MSFilter *m1, MSFilter *m2) +{ + int i,j; + int removed=-1; + MSQueue *qo; + MSFifo *fo; + /* takes all outputs of m1, and removes the one that goes to m2 */ + if (m1->outqueues!=NULL){ + for (i=0;imax_qoutputs;i++) + { + qo=m1->outqueues[i]; + if (qo!=NULL){ + MSFilter *rmf; + /* test if the queue connects to m2 */ + rmf=(MSFilter*)qo->next_data; + if (rmf==m2){ + j=find_iq(rmf,qo); + if (j==-1) g_error("Could not find input queue: impossible case."); + ms_filter_unlink(m1,i,m2,j,LINK_QUEUE); + removed=0; + } + } + } + } + if (m1->outfifos!=NULL){ + for (i=0;imax_foutputs;i++) + { + fo=m1->outfifos[i]; + if (fo!=NULL){ + MSFilter *rmf; + /* test if the queue connects to m2 */ + rmf=(MSFilter*)fo->next_data; + if (rmf==m2){ + j=find_if(rmf,fo); + if (j==-1) g_error("Could not find input fifo: impossible case."); + ms_filter_unlink(m1,i,m2,j,LINK_FIFO); + removed=0; + } + } + } + } + return removed; +} + +/** + * ms_filter_fifos_have_data: + * @f: a #MSFilter object. + * + * Tells if the filter has enough data in its input fifos in order to be executed succesfully. + * + * Returns: 1 if it can be executed, 0 else. + */ +gint ms_filter_fifos_have_data(MSFilter *f) +{ + gint i,j; + gint max_inputs=f->klass->max_finputs; + gint con_inputs=f->finputs; + MSFifo *fifo; + /* test fifos */ + for(i=0,j=0; (iinfifos[i]; + if (fifo!=NULL) + { + j++; + if (fifo->readsize==0) return 0; + if (fifo->readsize>=f->r_mingran) return 1; + } + } + return 0; +} + +/** + * ms_filter_queues_have_data: + * @f: a #MSFilter object. + * + * Tells if the filter has enough data in its input queues in order to be executed succesfully. + * + * Returns: 1 if it can be executed, 0 else. + */ +gint ms_filter_queues_have_data(MSFilter *f) +{ + gint i,j; + gint max_inputs=f->klass->max_qinputs; + gint con_inputs=f->qinputs; + MSQueue *q; + /* test queues */ + for(i=0,j=0; (iinqueues[i]; + if (q!=NULL) + { + j++; + if (ms_queue_can_get(q)) return 1; + } + } + return 0; +} + + + +void ms_filter_destroy(MSFilter *f) +{ + /* first check if the filter is disconnected from any others */ + g_return_if_fail(f->finputs==0); + g_return_if_fail(f->foutputs==0); + g_return_if_fail(f->qinputs==0); + g_return_if_fail(f->qoutputs==0); + f->klass->destroy(f); +} + +GList *filter_list=NULL; + +void ms_filter_register(MSFilterInfo *info) +{ + gpointer tmp; + tmp=g_list_find(filter_list,info); + if (tmp==NULL) filter_list=g_list_append(filter_list,(gpointer)info); +} + +void ms_filter_unregister(MSFilterInfo *info) +{ + filter_list=g_list_remove(filter_list,(gpointer)info); +} + +static gint compare_names(gpointer info, gpointer name) +{ + MSFilterInfo *i=(MSFilterInfo*) info; + return (strcmp(i->name,name)); +} + +MSFilterInfo * ms_filter_get_by_name(const gchar *name) +{ + GList *elem=g_list_find_custom(filter_list, + (gpointer)name,(GCompareFunc)compare_names); + if (elem!=NULL){ + return (MSFilterInfo*)elem->data; + } + return NULL; +} + + + +MSFilter * ms_filter_new_with_name(const gchar *name) +{ + MSFilterInfo *info=ms_filter_get_by_name(name); + if (info!=NULL) return info->constructor(); + g_warning("ms_filter_new_with_name: no filter named %s found.",name); + return NULL; +} + + +/* find the first codec in the left part of the stream */ +MSFilter * ms_filter_search_upstream_by_type(MSFilter *f,MSFilterType type) +{ + MSFilter *tmp=f; + MSFilterInfo *info; + + if ((tmp->infifos!=NULL) && (tmp->infifos[0]!=NULL)){ + tmp=(MSFilter*) tmp->infifos[0]->prev_data; + while(1){ + info=MS_FILTER_GET_CLASS(tmp)->info; + if (info!=NULL){ + if ( (info->type==type) ){ + return tmp; + } + } + if ((tmp->infifos!=NULL) && (tmp->infifos[0]!=NULL)) + tmp=(MSFilter*) tmp->infifos[0]->prev_data; + else break; + } + } + tmp=f; + if ((tmp->inqueues!=NULL) && (tmp->inqueues[0]!=NULL)){ + tmp=(MSFilter*) tmp->inqueues[0]->prev_data; + while(1){ + + info=MS_FILTER_GET_CLASS(tmp)->info; + if (info!=NULL){ + if ( (info->type==type)){ + return tmp; + } + }else g_warning("ms_filter_search_upstream_by_type: filter %s has no info." + ,MS_FILTER_GET_CLASS(tmp)->name); + if ((tmp->inqueues!=NULL) && (tmp->inqueues[0]!=NULL)) + tmp=(MSFilter*) tmp->inqueues[0]->prev_data; + else break; + } + } + return NULL; +} + + +int ms_filter_set_property(MSFilter *f, MSFilterProperty prop,void *value) +{ + if (f->klass->set_property!=NULL){ + return f->klass->set_property(f,prop,value); + } + return 0; +} + +int ms_filter_get_property(MSFilter *f, MSFilterProperty prop,void *value) +{ + if (f->klass->get_property!=NULL){ + return f->klass->get_property(f,prop,value); + } + return -1; +} + +void ms_filter_set_notify_func(MSFilter* filter,MSFilterNotifyFunc func, gpointer userdata) +{ + filter->notify_event=func; + filter->userdata=userdata; +} + +void ms_filter_notify_event(MSFilter *filter,gint event, gpointer arg) +{ + if (filter->notify_event!=NULL){ + filter->notify_event(filter,event,arg,filter->userdata); + } +} + +void swap_buffer(gchar *buffer, gint len) +{ + int i; + gchar tmp; + for (i=0;i +#endif + +#ifdef HAVE_GLIB +#include +#else +#undef VERSION +#undef PACKAGE +#include +#endif + +#include +#include "msutils.h" +#include "msfifo.h" +#include "msqueue.h" + +struct _MSFilter; +/*this is the abstract object and class for all filter types*/ +typedef gint (*MSFilterNotifyFunc)(struct _MSFilter*, gint event, gpointer arg, gpointer userdata); + +struct _MSFilter +{ + struct _MSFilterClass *klass; + GMutex *lock; + guchar finputs; /* number of connected fifo inputs*/ + guchar foutputs; /* number of connected fifo outputs*/ + guchar qinputs; /* number of connected queue inputs*/ + guchar qoutputs; /* number of connected queue outputs*/ + gint min_fifo_size; /* set when linking*/ + gint r_mingran; /* read minimum granularity (for fifos). + It can be zero so that the filter can accept any size of reading data*/ + MSFifo **infifos; /*pointer to a table of pointer to input fifos*/ + MSFifo **outfifos; /*pointer to a table of pointer to output fifos*/ + MSQueue **inqueues; /*pointer to a table of pointer to input queues*/ + MSQueue **outqueues; /*pointer to a table of pointer to output queues*/ + MSFilterNotifyFunc notify_event; + gpointer userdata; +}; + +typedef struct _MSFilter MSFilter; + +typedef enum{ + MS_FILTER_PROPERTY_FREQ, /* value is int */ + MS_FILTER_PROPERTY_BITRATE, /*value is int */ + MS_FILTER_PROPERTY_CHANNELS,/*value is int */ + MS_FILTER_PROPERTY_FMTP /* value is string */ +}MSFilterProperty; + +#define MS_FILTER_PROPERTY_STRING_MAX_SIZE 256 + +typedef MSFilter * (*MSFilterNewFunc)(void); +typedef void (*MSFilterProcessFunc)(MSFilter *); +typedef void (*MSFilterDestroyFunc)(MSFilter *); +typedef int (*MSFilterPropertyFunc)(MSFilter *,int ,void*); +typedef void (*MSFilterSetupFunc)(MSFilter *, void *); /*2nd arg is the sync */ + +typedef struct _MSFilterClass +{ + struct _MSFilterInfo *info; /*pointer to a filter_info */ + gchar *name; + guchar max_finputs; /* maximum number of fifo inputs*/ + guchar max_foutputs; /* maximum number of fifo outputs*/ + guchar max_qinputs; /* maximum number of queue inputs*/ + guchar max_qoutputs; /* maximum number of queue outputs*/ + gint r_maxgran; /* read maximum granularity (for fifos)*/ + gint w_maxgran; /* write maximum granularity (for fifos)*/ + gint r_offset; /* size of kept samples behind read pointer (for fifos)*/ + gint w_offset; /* size of kept samples behind write pointer (for fifos)*/ + MSFilterPropertyFunc set_property; + MSFilterPropertyFunc get_property; + MSFilterSetupFunc setup; /* called when attaching to sync */ + void (*process)(MSFilter *filter); + MSFilterSetupFunc unsetup; /* called when detaching from sync */ + void (*destroy)(MSFilter *filter); + guint attributes; +#define FILTER_HAS_FIFOS (0x0001) +#define FILTER_HAS_QUEUES (0x0001<<1) +#define FILTER_IS_SOURCE (0x0001<<2) +#define FILTER_IS_SINK (0x0001<<3) +#define FILTER_CAN_SYNC (0x0001<<4) + guint ref_count; /*number of object using the class*/ +} MSFilterClass; + + + +#define MS_FILTER(obj) ((MSFilter*)obj) +#define MS_FILTER_CLASS(klass) ((MSFilterClass*)klass) +#define MS_FILTER_GET_CLASS(obj) ((MSFilterClass*)((MS_FILTER(obj)->klass))) + +void ms_filter_class_init(MSFilterClass *filterclass); +void ms_filter_init(MSFilter *filter); + +#define ms_filter_class_set_attr(filter,flag) ((filter)->attributes|=(flag)) +#define ms_filter_class_unset_attr(filter,flag) ((filter)->attributes&=~(flag)) + +#define ms_filter_class_set_name(__klass,__name) (__klass)->name=g_strdup((__name)) +#define ms_filter_class_set_info(_klass,_info) (_klass)->info=(_info) +/* public*/ + +#define ms_filter_process(filter) ((filter)->klass->process((filter))) + +#define ms_filter_lock(filter) g_mutex_lock((filter)->lock) +#define ms_filter_unlock(filter) g_mutex_unlock((filter)->lock) +/* low level connect functions */ +int ms_filter_link(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2, gint linktype); +int ms_filter_unlink(MSFilter *m1, gint pin1, MSFilter *m2,gint pin2,gint linktype); + +/* high level connect functions */ +int ms_filter_add_link(MSFilter *m1, MSFilter *m2); +int ms_filter_remove_links(MSFilter *m1, MSFilter *m2); + +void ms_filter_set_notify_func(MSFilter* filter,MSFilterNotifyFunc func, gpointer userdata); +void ms_filter_notify_event(MSFilter *filter,gint event, gpointer arg); + +int ms_filter_set_property(MSFilter *f,MSFilterProperty property, void *value); +int ms_filter_get_property(MSFilter *f,MSFilterProperty property, void *value); + + +gint ms_filter_fifos_have_data(MSFilter *f); +gint ms_filter_queues_have_data(MSFilter *f); + +void ms_filter_uninit(MSFilter *obj); +void ms_filter_destroy(MSFilter *f); + +#define ms_filter_get_mingran(f) ((f)->r_mingran) +#define ms_filter_set_mingran(f,gran) ((f)->r_mingran=(gran)) + +#define LINK_DEFAULT 0 +#define LINK_FIFO 1 +#define LINK_QUEUE 2 + + +#define MSFILTER_VERSION(a,b,c) (((a)<<2)|((b)<<1)|(c)) + +enum _MSFilterType +{ + MS_FILTER_DISK_IO, + MS_FILTER_AUDIO_CODEC, + MS_FILTER_VIDEO_CODEC, + MS_FILTER_NET_IO, + MS_FILTER_VIDEO_IO, + MS_FILTER_AUDIO_IO, + MS_FILTER_OTHER +}; + +typedef enum _MSFilterType MSFilterType; + + +/* find the first codec in the left part of the stream */ +MSFilter * ms_filter_search_upstream_by_type(MSFilter *f,MSFilterType type); + +struct _MSFilterInfo +{ + gchar *name; + gint version; + MSFilterType type; + MSFilterNewFunc constructor; + char *description; /*some textual information*/ +}; + +typedef struct _MSFilterInfo MSFilterInfo; + +void ms_filter_register(MSFilterInfo *finfo); +void ms_filter_unregister(MSFilterInfo *finfo); +MSFilterInfo * ms_filter_get_by_name(const gchar *name); + +MSFilter * ms_filter_new_with_name(const gchar *name); + + + +extern GList *filter_list; +#define MS_FILTER_INFO(obj) ((MSFilterInfo*)obj) + +void swap_buffer(gchar *buffer, gint len); + + +#endif diff --git a/linphone/mediastreamer/msnosync.c b/linphone/mediastreamer/msnosync.c new file mode 100644 index 000000000..af5141c0b --- /dev/null +++ b/linphone/mediastreamer/msnosync.c @@ -0,0 +1,82 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msnosync.h" + +static MSNoSyncClass *ms_nosync_class=NULL; + +void ms_nosync_init(MSNoSync *sync) +{ + ms_sync_init(MS_SYNC(sync)); + MS_SYNC(sync)->attached_filters=sync->filters; + memset(sync->filters,0,MSNOSYNC_MAX_FILTERS*sizeof(MSFilter*)); + MS_SYNC(sync)->samples_per_tick=160; + sync->started=0; +} + +void ms_nosync_class_init(MSNoSyncClass *klass) +{ + ms_sync_class_init(MS_SYNC_CLASS(klass)); + MS_SYNC_CLASS(klass)->max_filters=MSNOSYNC_MAX_FILTERS; + MS_SYNC_CLASS(klass)->synchronize=(MSSyncSyncFunc)ms_nosync_synchronize; + MS_SYNC_CLASS(klass)->destroy=(MSSyncDestroyFunc)ms_nosync_destroy; + /* no need to overload these function*/ + MS_SYNC_CLASS(klass)->attach=ms_sync_attach_generic; + MS_SYNC_CLASS(klass)->detach=ms_sync_detach_generic; +} + +void ms_nosync_destroy(MSNoSync *nosync) +{ + g_free(nosync); +} + +/* the synchronization function that does nothing*/ +void ms_nosync_synchronize(MSNoSync *nosync) +{ + gint32 time; + if (nosync->started==0){ + gettimeofday(&nosync->start,NULL); + nosync->started=1; + } + gettimeofday(&nosync->current,NULL); + MS_SYNC(nosync)->ticks++; + /* update the time, we are supposed to work at 8000 Hz */ + time=((nosync->current.tv_sec-nosync->start.tv_sec)*1000) + + ((nosync->current.tv_usec-nosync->start.tv_usec)/1000); + MS_SYNC(nosync)->time=time; + return; +} + + +MSSync *ms_nosync_new() +{ + MSNoSync *nosync; + + nosync=g_malloc(sizeof(MSNoSync)); + ms_nosync_init(nosync); + if (ms_nosync_class==NULL) + { + ms_nosync_class=g_new(MSNoSyncClass,1); + ms_nosync_class_init(ms_nosync_class); + } + MS_SYNC(nosync)->klass=MS_SYNC_CLASS(ms_nosync_class); + return(MS_SYNC(nosync)); +} diff --git a/linphone/mediastreamer/msnosync.h b/linphone/mediastreamer/msnosync.h new file mode 100644 index 000000000..eef52d457 --- /dev/null +++ b/linphone/mediastreamer/msnosync.h @@ -0,0 +1,60 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mssync.h" + +#include +#define MSNOSYNC_MAX_FILTERS 10 + +/* MSNoSync derivates from MSSync base class*/ + +typedef struct _MSNoSync +{ + /* the MSSync must be the first field of the object in order to the object mechanism to work*/ + MSSync sync; + MSFilter *filters[MSNOSYNC_MAX_FILTERS]; + int started; + struct timeval start,current; +} MSNoSync; + + +typedef struct _MSNoSyncClass +{ + /* the MSSyncClass must be the first field of the class in order to the class mechanism to work*/ + MSSyncClass parent_class; +} MSNoSyncClass; + + +/*private*/ + +void ms_nosync_init(MSNoSync *sync); +void ms_nosync_class_init(MSNoSyncClass *sync); + +void ms_nosync_destroy(MSNoSync *nosync); +void ms_nosync_synchronize(MSNoSync *nosync); + +/*public*/ + +/* casts a MSSync object into a MSNoSync */ +#define MS_NOSYNC(sync) ((MSNoSync*)(sync)) +/* casts a MSSync class into a MSNoSync class */ +#define MS_NOSYNC_CLASS(klass) ((MSNoSyncClass*)(klass)) + +MSSync *ms_nosync_new(); diff --git a/linphone/mediastreamer/msossread.c b/linphone/mediastreamer/msossread.c new file mode 100644 index 000000000..4f486f14b --- /dev/null +++ b/linphone/mediastreamer/msossread.c @@ -0,0 +1,150 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msossread.h" +#include "mssync.h" +#include +#include +#include +#include + +MSFilterInfo oss_read_info={ + "OSS read", + 0, + MS_FILTER_AUDIO_IO, + ms_oss_read_new, + NULL +}; + +static MSOssReadClass *msossreadclass=NULL; + +MSFilter * ms_oss_read_new() +{ + MSOssRead *w; + + if (msossreadclass==NULL) + { + msossreadclass=g_new(MSOssReadClass,1); + ms_oss_read_class_init( msossreadclass ); + } + + w=g_new(MSOssRead,1); + MS_FILTER(w)->klass=MS_FILTER_CLASS(msossreadclass); + ms_oss_read_init(w); + + return(MS_FILTER(w)); +} + +/* FOR INTERNAL USE*/ +void ms_oss_read_init(MSOssRead *w) +{ + ms_sound_read_init(MS_SOUND_READ(w)); + MS_FILTER(w)->outfifos=w->f_outputs; + MS_FILTER(w)->outfifos[0]=NULL; + w->devid=0; + w->sndcard=NULL; + w->freq=8000; +} + +gint ms_oss_read_set_property(MSOssRead *f,MSFilterProperty prop, void *value) +{ + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + f->freq=((gint*)value)[0]; + break; + default: + break; + } + return 0; +} +void ms_oss_read_class_init(MSOssReadClass *klass) +{ + ms_sound_read_class_init(MS_SOUND_READ_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_foutputs=1; /* one fifo output only */ + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_oss_read_setup; + MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_oss_read_stop; + MS_FILTER_CLASS(klass)->process= (MSFilterProcessFunc)ms_oss_read_process; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_oss_read_set_property; + MS_FILTER_CLASS(klass)->destroy= (MSFilterDestroyFunc)ms_oss_read_destroy; + MS_FILTER_CLASS(klass)->w_maxgran=MS_OSS_READ_MAX_GRAN; + MS_FILTER_CLASS(klass)->info=&oss_read_info; + MS_SOUND_READ_CLASS(klass)->set_device=(gint (*)(MSSoundRead*,gint))ms_oss_read_set_device; + MS_SOUND_READ_CLASS(klass)->start=(void (*)(MSSoundRead*))ms_oss_read_start; + MS_SOUND_READ_CLASS(klass)->stop=(void (*)(MSSoundRead*))ms_oss_read_stop; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"OssRead"); + //ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_CAN_SYNC|FILTER_IS_SOURCE); +} + +void ms_oss_read_destroy( MSOssRead *obj) +{ + g_free(obj); +} + +void ms_oss_read_process(MSOssRead *f) +{ + MSFifo *fifo; + char *p; + fifo=f->f_outputs[0]; + + g_return_if_fail(f->sndcard!=NULL); + g_return_if_fail(f->gran>0); + + if (snd_card_can_read(f->sndcard)){ + int got; + ms_fifo_get_write_ptr(fifo,f->gran,(void**)&p); + g_return_if_fail(p!=NULL); + got=snd_card_read(f->sndcard,p,f->gran); + if (got>=0 && got!=f->gran) ms_fifo_update_write_ptr(fifo,got); + } +} + + +void ms_oss_read_start(MSOssRead *r) +{ + g_return_if_fail(r->devid!=-1); + r->sndcard=snd_card_manager_get_card(snd_card_manager,r->devid); + g_return_if_fail(r->sndcard!=NULL); + /* open the device for an audio telephony signal with minimum latency */ + snd_card_open_r(r->sndcard,16,0,r->freq); + r->gran=(512*r->freq)/8000; + +} + +void ms_oss_read_stop(MSOssRead *w) +{ + g_return_if_fail(w->devid!=-1); + g_return_if_fail(w->sndcard!=NULL); + snd_card_close_r(w->sndcard); + w->sndcard=NULL; +} + + +void ms_oss_read_setup(MSOssRead *f, MSSync *sync) +{ + f->sync=sync; + ms_oss_read_start(f); +} + + +gint ms_oss_read_set_device(MSOssRead *r,gint devid) +{ + r->devid=devid; + return 0; +} diff --git a/linphone/mediastreamer/msossread.h b/linphone/mediastreamer/msossread.h new file mode 100644 index 000000000..89d5a40b1 --- /dev/null +++ b/linphone/mediastreamer/msossread.h @@ -0,0 +1,77 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSOSSREAD_H +#define MSOSSREAD_H + +#include "mssoundread.h" +#include "sndcard.h" +#include "mssync.h" + + +/*this is the class that implements oss writing sink filter*/ + +#define MS_OSS_READ_MAX_INPUTS 1 /* max output per filter*/ + +#define MS_OSS_READ_MAX_GRAN (512*2) /* the maximum granularity*/ + +struct _MSOssRead +{ + /* the MSOssRead derivates from MSSoundRead so the MSSoundRead object MUST be the first of the MSOssRead object + in order to the object mechanism to work*/ + MSSoundRead filter; + MSFifo *f_outputs[MS_OSS_READ_MAX_INPUTS]; + MSSync *sync; + SndCard *sndcard; + gint freq; + gint devid; /* the sound device id it depends on*/ + gint gran; + gint flags; +#define START_REQUESTED 1 +#define STOP_REQUESTED 2 +}; + +typedef struct _MSOssRead MSOssRead; + +struct _MSOssReadClass +{ + /* the MSOssRead derivates from MSSoundRead, so the MSSoundRead class MUST be the first of the MSOssRead class + in order to the class mechanism to work*/ + MSSoundReadClass parent_class; +}; + +typedef struct _MSOssReadClass MSOssReadClass; + +/* PUBLIC */ +#define MS_OSS_READ(filter) ((MSOssRead*)(filter)) +#define MS_OSS_READ_CLASS(klass) ((MSOssReadClass*)(klass)) +MSFilter * ms_oss_read_new(void); +gint ms_oss_read_set_device(MSOssRead *w,gint devid); +void ms_oss_read_start(MSOssRead *w); +void ms_oss_read_stop(MSOssRead *w); + +/* FOR INTERNAL USE*/ +void ms_oss_read_init(MSOssRead *r); +void ms_oss_read_class_init(MSOssReadClass *klass); +void ms_oss_read_destroy( MSOssRead *obj); +void ms_oss_read_process(MSOssRead *f); +void ms_oss_read_setup(MSOssRead *f, MSSync *sync); + + +#endif diff --git a/linphone/mediastreamer/msosswrite.c b/linphone/mediastreamer/msosswrite.c new file mode 100644 index 000000000..bfd78dc50 --- /dev/null +++ b/linphone/mediastreamer/msosswrite.c @@ -0,0 +1,249 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msosswrite.h" +#include "mssync.h" +#include +#include + +MSFilterInfo oss_write_info={ + "OSS write", + 0, + MS_FILTER_OTHER, + ms_oss_write_new, + NULL +}; + + +static MSOssWriteClass *msosswriteclass=NULL; + +MSFilter * ms_oss_write_new() +{ + MSOssWrite *w; + + if (msosswriteclass==NULL) + { + msosswriteclass=g_new(MSOssWriteClass,1); + ms_oss_write_class_init( msosswriteclass ); + } + w=g_new(MSOssWrite,1); + MS_FILTER(w)->klass=MS_FILTER_CLASS(msosswriteclass); + ms_oss_write_init(w); + return(MS_FILTER(w)); +} + +/* FOR INTERNAL USE*/ +void ms_oss_write_init(MSOssWrite *w) +{ + ms_sound_write_init(MS_SOUND_WRITE(w)); + MS_FILTER(w)->infifos=w->f_inputs; + MS_FILTER(w)->infifos[0]=NULL; + MS_FILTER(w)->r_mingran=512; /* very few cards can do that...*/ + w->devid=0; + w->sndcard=NULL; + w->freq=8000; + w->channels=1; + w->dtmf_time=-1; +} + +gint ms_oss_write_set_property(MSOssWrite *f,MSFilterProperty prop, void *value) +{ + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + f->freq=((gint*)value)[0]; + break; + case MS_FILTER_PROPERTY_CHANNELS: + f->channels=((gint*)value)[0]; + break; + default: + break; + } + return 0; +} + +void ms_oss_write_class_init(MSOssWriteClass *klass) +{ + ms_sound_write_class_init(MS_SOUND_WRITE_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_finputs=1; /* one fifo input only */ + MS_FILTER_CLASS(klass)->r_maxgran=MS_OSS_WRITE_DEF_GRAN; + MS_FILTER_CLASS(klass)->process= (MSFilterProcessFunc)ms_oss_write_process; + MS_FILTER_CLASS(klass)->destroy= (MSFilterDestroyFunc)ms_oss_write_destroy; + MS_FILTER_CLASS(klass)->setup= (MSFilterSetupFunc)ms_oss_write_setup; + MS_FILTER_CLASS(klass)->unsetup= (MSFilterSetupFunc)ms_oss_write_stop; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_oss_write_set_property; + MS_FILTER_CLASS(klass)->info=&oss_write_info; + MS_SOUND_WRITE_CLASS(klass)->set_device=(gint (*)(MSSoundWrite*,gint))ms_oss_write_set_device; + MS_SOUND_WRITE_CLASS(klass)->start=(void (*)(MSSoundWrite*))ms_oss_write_start; + MS_SOUND_WRITE_CLASS(klass)->stop=(void (*)(MSSoundWrite*))ms_oss_write_stop; + MS_SOUND_WRITE_CLASS(klass)->set_level=(void (*)(MSSoundWrite*, gint))ms_oss_write_set_level; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"OssWrite"); +} + +void ms_oss_write_destroy( MSOssWrite *obj) +{ + + g_free(obj); +} + +void ms_oss_write_process(MSOssWrite *f) +{ + MSFifo *fifo; + void *p; + int i; + gint gran=ms_filter_get_mingran(MS_FILTER(f)); + + /* always consume something */ + fifo=f->f_inputs[0]; + ms_fifo_get_read_ptr(fifo,gran,&p); + if (p==NULL) { + g_warning("Not enough data: gran=%i.",gran); + return; + } + g_return_if_fail(f->sndcard!=NULL); + if (f->dtmf_time!=-1){ + gint16 *buf=(gint16*)p; + /* generate a DTMF*/ + for(i=0;idtmf_time*f->lowfreq)); + buf[i]+=(gint16)(10000.0*sin(2*M_PI*(double)f->dtmf_time*f->highfreq)); + f->dtmf_time++; + //printf("buf[%i]=%i\n",i,buf[i]); + } + if (f->dtmf_time>f->dtmf_duration) f->dtmf_time=-1; /*finished*/ + } + snd_card_write(f->sndcard,p,gran); +} + +void ms_oss_write_start(MSOssWrite *w) +{ + //gint bsize; + g_return_if_fail(w->devid!=-1); + w->sndcard=snd_card_manager_get_card(snd_card_manager,w->devid); + g_return_if_fail(w->sndcard!=NULL); + /* open the device for an audio telephony signal with minimum latency */ + snd_card_open_w(w->sndcard,16,w->channels==2,w->freq); + w->bsize=snd_card_get_bsize(w->sndcard); + //MS_FILTER(w)->r_mingran=w->bsize; + //ms_sync_set_samples_per_tick(MS_FILTER(w)->sync,bsize); +} + +void ms_oss_write_stop(MSOssWrite *w) +{ + g_return_if_fail(w->devid!=-1); + g_return_if_fail(w->sndcard!=NULL); + snd_card_close_w(w->sndcard); + w->sndcard=NULL; +} + +void ms_oss_write_set_level(MSOssWrite *w,gint a) +{ + +} + +gint ms_oss_write_set_device(MSOssWrite *w, gint devid) +{ + w->devid=devid; + return 0; +} + +void ms_oss_write_setup(MSOssWrite *r) +{ + //g_message("starting MSOssWrite.."); + ms_oss_write_start(r); +} + + + +void ms_oss_write_play_dtmf(MSOssWrite *w, char dtmf){ + + w->dtmf_duration=0.1*w->freq; + switch(dtmf){ + case '0': + w->lowfreq=941; + w->highfreq=1336; + break; + case '1': + w->lowfreq=697; + w->highfreq=1209; + break; + case '2': + w->lowfreq=697; + w->highfreq=1336; + break; + case '3': + w->lowfreq=697; + w->highfreq=1477; + break; + case '4': + w->lowfreq=770; + w->highfreq=1209; + break; + case '5': + w->lowfreq=770; + w->highfreq=1336; + break; + case '6': + w->lowfreq=770; + w->highfreq=1477; + break; + case '7': + w->lowfreq=852; + w->highfreq=1209; + break; + case '8': + w->lowfreq=852; + w->highfreq=1336; + break; + case '9': + w->lowfreq=852; + w->highfreq=1477; + break; + case '*': + w->lowfreq=941; + w->highfreq=1209; + break; + case '#': + w->lowfreq=941; + w->highfreq=1477; + break; + case 'A': + w->lowfreq=697; + w->highfreq=1633; + break; + case 'B': + w->lowfreq=770; + w->highfreq=1633; + break; + case 'C': + w->lowfreq=852; + w->highfreq=1633; + break; + case 'D': + w->lowfreq=941; + w->highfreq=1633; + break; + default: + g_warning("Not a dtmf key."); + return; + } + w->lowfreq=w->lowfreq/w->freq; + w->highfreq=w->highfreq/w->freq; + w->dtmf_time=0; +} diff --git a/linphone/mediastreamer/msosswrite.h b/linphone/mediastreamer/msosswrite.h new file mode 100644 index 000000000..d47753414 --- /dev/null +++ b/linphone/mediastreamer/msosswrite.h @@ -0,0 +1,78 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSOSSWRITE_H +#define MSOSSWRITE_H + +#include "mssoundwrite.h" +#include "sndcard.h" + +/*this is the class that implements oss writing sink filter*/ + +#define MS_OSS_WRITE_MAX_INPUTS 1 /* max output per filter*/ + +#define MS_OSS_WRITE_DEF_GRAN (512*2) /* the default granularity*/ + +struct _MSOssWrite +{ + /* the MSOssWrite derivates from MSSoundWrite, so the MSSoundWrite object MUST be the first of the MSOssWrite object + in order to the object mechanism to work*/ + MSSoundWrite filter; + MSFifo *f_inputs[MS_OSS_WRITE_MAX_INPUTS]; + gint devid; /* the sound device id it depends on*/ + SndCard *sndcard; + gint bsize; + gint freq; + gint channels; + gdouble lowfreq; + gdouble highfreq; + gint dtmf_time; + gint dtmf_duration; +}; + +typedef struct _MSOssWrite MSOssWrite; + +struct _MSOssWriteClass +{ + /* the MSOssWrite derivates from MSSoundWrite, so the MSSoundWrite class MUST be the first of the MSOssWrite class + in order to the class mechanism to work*/ + MSSoundWriteClass parent_class; +}; + +typedef struct _MSOssWriteClass MSOssWriteClass; + +/* PUBLIC */ +#define MS_OSS_WRITE(filter) ((MSOssWrite*)(filter)) +#define MS_OSS_WRITE_CLASS(klass) ((MSOssWriteClass*)(klass)) +MSFilter * ms_oss_write_new(void); +gint ms_oss_write_set_device(MSOssWrite *w,gint devid); +void ms_oss_write_start(MSOssWrite *w); +void ms_oss_write_stop(MSOssWrite *w); +void ms_oss_write_set_level(MSOssWrite *w, gint level); +void ms_oss_write_play_dtmf(MSOssWrite *w, char dtmf); + +/* FOR INTERNAL USE*/ +void ms_oss_write_init(MSOssWrite *r); +void ms_oss_write_setup(MSOssWrite *r); +void ms_oss_write_class_init(MSOssWriteClass *klass); +void ms_oss_write_destroy( MSOssWrite *obj); +void ms_oss_write_process(MSOssWrite *f); + + +#endif diff --git a/linphone/mediastreamer/msqdispatcher.c b/linphone/mediastreamer/msqdispatcher.c new file mode 100644 index 000000000..6bd073b9b --- /dev/null +++ b/linphone/mediastreamer/msqdispatcher.c @@ -0,0 +1,91 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a dispatcher of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msqdispatcher.h" + +static MSQdispatcherClass *ms_qdispatcher_class=NULL; + +MSFilter * ms_qdispatcher_new(void) +{ + MSQdispatcher *obj; + obj=g_malloc(sizeof(MSQdispatcher)); + if (ms_qdispatcher_class==NULL){ + ms_qdispatcher_class=g_malloc0(sizeof(MSQdispatcherClass)); + ms_qdispatcher_class_init(ms_qdispatcher_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_qdispatcher_class); + ms_qdispatcher_init(obj); + return MS_FILTER(obj); +} + + +void ms_qdispatcher_init(MSQdispatcher *obj) +{ + ms_filter_init(MS_FILTER(obj)); + + MS_FILTER(obj)->inqueues=obj->q_inputs; + MS_FILTER(obj)->outqueues=obj->q_outputs; + memset(obj->q_inputs,0,sizeof(MSQueue*)*MS_QDISPATCHER_MAX_INPUTS); + memset(obj->q_outputs,0,sizeof(MSQueue*)*MS_QDISPATCHER_MAX_OUTPUTS); +} + + + +void ms_qdispatcher_class_init(MSQdispatcherClass *klass) +{ + MSFilterClass *parent_class=MS_FILTER_CLASS(klass); + ms_filter_class_init(parent_class); + ms_filter_class_set_name(parent_class,"qdispatcher"); + parent_class->max_qinputs=MS_QDISPATCHER_MAX_INPUTS; + parent_class->max_qoutputs=MS_QDISPATCHER_MAX_OUTPUTS; + + parent_class->destroy=(MSFilterDestroyFunc)ms_qdispatcher_destroy; + parent_class->process=(MSFilterProcessFunc)ms_qdispatcher_process; +} + + +void ms_qdispatcher_destroy( MSQdispatcher *obj) +{ + g_free(obj); +} + +void ms_qdispatcher_process(MSQdispatcher *obj) +{ + gint i; + MSQueue *inq=obj->q_inputs[0]; + + if (inq!=NULL){ + MSQueue *outq; + MSMessage *m1,*m2; + while ( (m1=ms_queue_get(inq))!=NULL){ + /* dispatch incoming messages to output queues */ + for (i=0;iq_outputs[i]; + if (outq!=NULL){ + m2=ms_message_dup(m1); + ms_queue_put(outq,m2); + } + } + ms_message_destroy(m1); + } + } + +} diff --git a/linphone/mediastreamer/msqdispatcher.h b/linphone/mediastreamer/msqdispatcher.h new file mode 100644 index 000000000..3b0c566d9 --- /dev/null +++ b/linphone/mediastreamer/msqdispatcher.h @@ -0,0 +1,60 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a dispatcher of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSQDISPATCHER_H +#define MSQDISPATCHER_H + +#include "msfilter.h" + + +/*this is the class that implements a qdispatcher filter*/ + +#define MS_QDISPATCHER_MAX_INPUTS 1 +#define MS_QDISPATCHER_MAX_OUTPUTS 5 + +typedef struct _MSQdispatcher +{ + /* the MSQdispatcher derivates from MSFilter, so the MSFilter object MUST be the first of the MSQdispatcher object + in order to the object mechanism to work*/ + MSFilter filter; + MSQueue *q_inputs[MS_QDISPATCHER_MAX_INPUTS]; + MSQueue *q_outputs[MS_QDISPATCHER_MAX_OUTPUTS]; +} MSQdispatcher; + +typedef struct _MSQdispatcherClass +{ + /* the MSQdispatcher derivates from MSFilter, so the MSFilter class MUST be the first of the MSQdispatcher class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSQdispatcherClass; + +/* PUBLIC */ +#define MS_QDISPATCHER(filter) ((MSQdispatcher*)(filter)) +#define MS_QDISPATCHER_CLASS(klass) ((MSQdispatcherClass*)(klass)) +MSFilter * ms_qdispatcher_new(void); + +/* FOR INTERNAL USE*/ +void ms_qdispatcher_init(MSQdispatcher *r); +void ms_qdispatcher_class_init(MSQdispatcherClass *klass); +void ms_qdispatcher_destroy( MSQdispatcher *obj); +void ms_qdispatcher_process(MSQdispatcher *r); + +#endif diff --git a/linphone/mediastreamer/msqueue.c b/linphone/mediastreamer/msqueue.c new file mode 100644 index 000000000..703fab6cb --- /dev/null +++ b/linphone/mediastreamer/msqueue.c @@ -0,0 +1,58 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msqueue.h" +#include + +MSQueue * ms_queue_new() +{ + MSQueue *q=g_malloc(sizeof(MSQueue)); + memset(q,0,sizeof(MSQueue)); + return q; +} + +MSMessage *ms_queue_get(MSQueue *q) +{ + MSMessage *b=q->last; + if (b==NULL) return NULL; + q->last=b->prev; + if (b->prev==NULL) q->first=NULL; /* it was the only element of the queue*/ + q->size--; + b->next=b->prev=NULL; + return(b); +} + +void ms_queue_put(MSQueue *q, MSMessage *m) +{ + MSMessage *mtmp=q->first; + g_return_if_fail(m!=NULL); + q->first=m; + m->next=mtmp; + if (mtmp!=NULL) + { + mtmp->prev=m; + } + else q->last=m; /* it was the first element of the q */ + q->size++; +} + +MSMessage *ms_queue_peek_last(MSQueue *q){ + return q->last; +} diff --git a/linphone/mediastreamer/msqueue.h b/linphone/mediastreamer/msqueue.h new file mode 100644 index 000000000..10bb8791b --- /dev/null +++ b/linphone/mediastreamer/msqueue.h @@ -0,0 +1,51 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSQUEUE_H +#define MSQUEUE_H + +#include "msbuffer.h" + +/* for the moment these are stupid queues limited to one element*/ + +typedef struct _MSQueue +{ + MSMessage *first; + MSMessage *last; + gint size; + void *prev_data; /*user data, usually the writting filter*/ + void *next_data; /* user data, usually the reading filter*/ +}MSQueue; + + +MSQueue * ms_queue_new(); + +MSMessage *ms_queue_get(MSQueue *q); + +void ms_queue_put(MSQueue *q, MSMessage *m); + +MSMessage *ms_queue_peek_last(MSQueue *q); + +#define ms_queue_can_get(q) ( (q)->size!=0 ) + +#define ms_queue_destroy(q) g_free(q) + + +#endif diff --git a/linphone/mediastreamer/msread.c b/linphone/mediastreamer/msread.c new file mode 100644 index 000000000..f05e85e0d --- /dev/null +++ b/linphone/mediastreamer/msread.c @@ -0,0 +1,186 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msread.h" +#include "mssync.h" +#include +#include +#include +#include +#include + +static MSReadClass *ms_read_class=NULL; + +gint ms_read_open(MSRead *r, gchar *name); + +MSFilter * ms_read_new(char *name) +{ + MSRead *r; + + r=g_new(MSRead,1); + ms_read_init(r); + if (ms_read_class==NULL) + { + ms_read_class=g_new(MSReadClass,1); + ms_read_class_init(ms_read_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_read_class); + r->fd=-1; + if (name!=NULL) ms_read_open(r,name); + return(MS_FILTER(r)); +} + + + +gint ms_read_open(MSRead *r, gchar *name) +{ + gint fd; + fd=open(name,O_RDONLY); + if (fd<0) { + r->fd=-1; + g_warning("ms_read_new: cannot open %s : %s",name,strerror(errno)); + return -1; + } + r->fd=fd; + if (strstr(name,".wav")!=NULL){ + /* skip the header */ + lseek(fd,20,SEEK_SET); +#ifdef WORDS_BIGENDIAN + r->need_swap=1; +#else + r->need_swap=0; +#endif + } + r->state=MS_READ_STATE_STARTED; + return 0; +} + +/* FOR INTERNAL USE*/ +void ms_read_init(MSRead *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->outfifos=r->foutputs; + MS_FILTER(r)->outqueues=r->qoutputs; + memset(r->foutputs,0,sizeof(MSFifo*)*MSREAD_MAX_OUTPUTS); + memset(r->qoutputs,0,sizeof(MSQueue*)*MSREAD_MAX_OUTPUTS); + r->fd=-1; + r->gran=320; + r->state=MS_READ_STATE_STOPPED; + r->need_swap=0; + r->rate=8000; +} + +gint ms_read_set_property(MSRead *f,MSFilterProperty prop, void *value) +{ + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + f->rate=((gint*)value)[0]; + break; + default: + break; + } + return 0; +} + +void ms_read_class_init(MSReadClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"dskreader"); + ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE); + MS_FILTER_CLASS(klass)->max_foutputs=MSREAD_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->max_qoutputs=MSREAD_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->w_maxgran=MSREAD_DEF_GRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_read_destroy; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_read_setup; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_read_process; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_read_set_property; +} + +void ms_read_process(MSRead *r) +{ + MSFifo *f; + MSQueue *q; + MSMessage *msg=NULL; + int err; + gint gran=r->gran; + void *p; + + f=r->foutputs[0]; + if ((f!=NULL) && (r->state==MS_READ_STATE_STARTED)) + { + ms_fifo_get_write_ptr(f,gran,&p); + if (p!=NULL) + { + err=read(r->fd,p,gran); + if (err<0) + { + /* temp: */ + g_warning("ms_read_process: failed to read: %s.\n",strerror(errno)); + } + else if (errstate=MS_READ_STATE_STOPPED; + close(r->fd); + r->fd=-1; + } + if (r->need_swap) swap_buffer(p,gran); + } + } + /* process output queues*/ + q=r->qoutputs[0]; + if ((q!=NULL) && (r->fd>0)) + { + msg=ms_message_new(r->gran); + err=read(r->fd,msg->data,r->gran); + if (err>0){ + msg->size=err; + ms_queue_put(q,msg); + if (r->need_swap) swap_buffer(msg->data,r->gran); + }else{ + ms_filter_notify_event(MS_FILTER(r),MS_READ_EVENT_EOF,NULL); + ms_trace("End of file reached."); + r->state=MS_READ_STATE_STOPPED; + } + } +} + +void ms_read_destroy( MSRead *obj) +{ + if (obj->fd!=0) close(obj->fd); + g_free(obj); +} + +gint ms_read_close(MSRead *obj) +{ + if (obj->fd!=0) { + close(obj->fd); + obj->fd=-1; + obj->state=MS_READ_STATE_STOPPED; + } + return 0; +} + + +void ms_read_setup(MSRead *r, MSSync *sync) +{ + r->sync=sync; + r->gran=(r->rate*sync->interval/1000)*2; +} diff --git a/linphone/mediastreamer/msread.h b/linphone/mediastreamer/msread.h new file mode 100644 index 000000000..93177f38b --- /dev/null +++ b/linphone/mediastreamer/msread.h @@ -0,0 +1,80 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSREAD_H +#define MSREAD_H + +#include "msfilter.h" +#include "mssync.h" + +/*this is the class that implements file reading source filter*/ + +#define MSREAD_MAX_OUTPUTS 1 /* max output per filter*/ + +#define MSREAD_DEF_GRAN 640 /* the default granularity*/ + +typedef enum{ + MS_READ_STATE_STARTED, + MS_READ_STATE_STOPPED, + MS_READ_STATE_EOF +}MSReadState; + +typedef struct _MSRead +{ + /* the MSRead derivates from MSFilter, so the MSFilter object MUST be the first of the MSRead object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *foutputs[MSREAD_MAX_OUTPUTS]; + MSQueue *qoutputs[MSREAD_MAX_OUTPUTS]; + MSSync *sync; + gint rate; + gint fd; /* the file descriptor of the file being read*/ + gint gran; /*granularity*/ /* for use with queues */ + gint need_swap; + gint state; +} MSRead; + +typedef struct _MSReadClass +{ + /* the MSRead derivates from MSFilter, so the MSFilter class MUST be the first of the MSRead class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSReadClass; + +/* PUBLIC */ +#define MS_READ(filter) ((MSRead*)(filter)) +#define MS_READ_CLASS(klass) ((MSReadClass*)(klass)) +MSFilter * ms_read_new(char *name); +/* set the granularity for reading file on disk */ +#define ms_read_set_bufsize(filter,sz) (filter)->gran=(sz) + +/* FOR INTERNAL USE*/ +void ms_read_init(MSRead *r); +void ms_read_class_init(MSReadClass *klass); +void ms_read_destroy( MSRead *obj); +void ms_read_process(MSRead *r); +void ms_read_setup(MSRead *r, MSSync *sync); + +typedef enum{ + MS_READ_EVENT_EOF /* end of file */ +} MSReadEvent; + + +#endif diff --git a/linphone/mediastreamer/msringplayer.c b/linphone/mediastreamer/msringplayer.c new file mode 100644 index 000000000..dae8e7594 --- /dev/null +++ b/linphone/mediastreamer/msringplayer.c @@ -0,0 +1,255 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msringplayer.h" +#include "mssync.h" +#include +#include +#include +#include +#include +#include +#include + +#include "waveheader.h" + +#define WAVE_HEADER_OFFSET sizeof(wave_header_t) + +enum { PLAY_RING, PLAY_SILENCE}; + +static int supported_freq[6]={8000,11025,16000,22050,32000,44100}; + +gint ms_ring_player_set_property(MSRingPlayer *f,MSFilterProperty prop, void *value); + +gint freq_is_supported(gint freq){ + int i; + for (i=0;i<6;i++){ + if (abs(supported_freq[i]-freq)<50) return supported_freq[i]; + } + return 0; +} + +static MSRingPlayerClass *ms_ring_player_class=NULL; + +/** + * ms_ring_player_new: + * @name: The path to the 16-bit 8khz raw file to be played as a ring. + * @seconds: The number of seconds that separates two rings. + * + * Allocates a new MSRingPlayer object. + * + * + * Returns: a pointer the the object, NULL if name could not be open. + */ +MSFilter * ms_ring_player_new(char *name, gint seconds) +{ + MSRingPlayer *r; + int fd=-1; + + if ((name!=NULL) && (strlen(name)!=0)) + { + fd=open(name,O_RDONLY); + if (fd<0) + { + g_warning("ms_ring_player_new: failed to open %s.\n",name); + return NULL; + } + + }else { + g_warning("ms_ring_player_new: Bad file name"); + return NULL; + } + + r=g_new(MSRingPlayer,1); + ms_ring_player_init(r); + if (ms_ring_player_class==NULL) + { + ms_ring_player_class=g_new(MSRingPlayerClass,1); + ms_ring_player_class_init(ms_ring_player_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_ring_player_class); + + r->fd=fd; + r->silence=seconds; + r->freq=8000; + if (strstr(name,".wav")!=NULL){ + wave_header_t header; + int freq,freq2; + /* read the header */ + size_t ret = read(fd,&header,sizeof(wave_header_t)); + assert( ret == sizeof(wave_header_t) ); + freq=wave_header_get_rate(&header); + if ((freq2=freq_is_supported(freq))>0){ + r->freq=freq2; + }else { + g_warning("Unsupported sampling rate %i",freq); + r->freq=8000; + } + r->channel=wave_header_get_channel(&header); + lseek(fd,WAVE_HEADER_OFFSET,SEEK_SET); +#ifdef WORDS_BIGENDIAN + r->need_swap=1; +#else + r->need_swap=0; +#endif + } + ms_ring_player_set_property(r, MS_FILTER_PROPERTY_FREQ,&r->freq); + r->state=PLAY_RING; + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_ring_player_init(MSRingPlayer *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->outfifos=r->foutputs; + MS_FILTER(r)->outqueues=r->qoutputs; + memset(r->foutputs,0,sizeof(MSFifo*)*MS_RING_PLAYER_MAX_OUTPUTS); + memset(r->qoutputs,0,sizeof(MSQueue*)*MS_RING_PLAYER_MAX_OUTPUTS); + r->fd=-1; + r->current_pos=0; + r->need_swap=0; + r->sync=NULL; +} + +gint ms_ring_player_set_property(MSRingPlayer *f,MSFilterProperty prop, void *value) +{ + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + f->rate=((gint*)value)[0]*2; + f->silence_bytes=f->silence*f->rate; + if (f->sync!=NULL) + f->gran=(f->rate*f->sync->interval/1000)*2; + break; + default: + break; + } + return 0; +} + +gint ms_ring_player_get_property(MSRingPlayer *f,MSFilterProperty prop, void *value) +{ + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + ((gint*)value)[0]=f->freq; + + break; + case MS_FILTER_PROPERTY_CHANNELS: + ((gint*)value)[0]=f->channel; + break; + default: + break; + } + return 0; +} + +gint ms_ring_player_get_sample_freq(MSRingPlayer *obj){ + return obj->freq; +} + + +void ms_ring_player_class_init(MSRingPlayerClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"ringplay"); + ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE); + MS_FILTER_CLASS(klass)->max_foutputs=MS_RING_PLAYER_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->max_qoutputs=MS_RING_PLAYER_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->w_maxgran=MS_RING_PLAYER_DEF_GRAN; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_ring_player_setup; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_ring_player_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_ring_player_process; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_ring_player_set_property; + MS_FILTER_CLASS(klass)->get_property=(MSFilterPropertyFunc)ms_ring_player_get_property; +} + +void ms_ring_player_process(MSRingPlayer *r) +{ + MSFifo *f; + gint err; + gint processed=0; + gint gran=r->gran; + char *p; + + g_return_if_fail(gran>0); + /* process output fifos*/ + + f=r->foutputs[0]; + ms_fifo_get_write_ptr(f,gran,(void**)&p); + g_return_if_fail(p!=NULL); + for (processed=0;processedstate){ + case PLAY_RING: + err=read(r->fd,&p[processed],gran-processed); + if (err<0) + { + memset(&p[processed],0,gran-processed); + processed=gran; + g_warning("ms_ring_player_process: failed to read: %s.\n",strerror(errno)); + return; + } + else if (errcurrent_pos=r->silence_bytes; + lseek(r->fd,WAVE_HEADER_OFFSET,SEEK_SET); + r->state=PLAY_SILENCE; + ms_filter_notify_event(MS_FILTER(r),MS_RING_PLAYER_END_OF_RING_EVENT,NULL); + } + if (r->need_swap) swap_buffer(&p[processed],err); + processed+=err; + break; + case PLAY_SILENCE: + err=gran-processed; + if (r->current_pos>err){ + memset(&p[processed],0,err); + r->current_pos-=gran; + processed=gran; + }else{ + memset(&p[processed],0,r->current_pos); + processed+=r->current_pos; + r->state=PLAY_RING; + } + break; + } + } +} + +/** + * ms_ring_player_destroy: + * @obj: A valid MSRingPlayer object. + * + * Destroy a MSRingPlayer object. + * + * + */ + +void ms_ring_player_destroy( MSRingPlayer *obj) +{ + if (obj->fd!=0) close(obj->fd); + g_free(obj); +} + +void ms_ring_player_setup(MSRingPlayer *r,MSSync *sync) +{ + r->sync=sync; + r->gran=(r->rate*r->sync->interval/1000)*r->channel; +} diff --git a/linphone/mediastreamer/msringplayer.h b/linphone/mediastreamer/msringplayer.h new file mode 100644 index 000000000..1f5e67daf --- /dev/null +++ b/linphone/mediastreamer/msringplayer.h @@ -0,0 +1,81 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSRINGPLAYER_H +#define MSRINGPLAYER_H + +#include "msfilter.h" +#include "mssync.h" + + +/*this is the class that implements file reading source filter*/ + +#define MS_RING_PLAYER_MAX_OUTPUTS 1 /* max output per filter*/ + +#define MS_RING_PLAYER_DEF_GRAN 8192 /* the default granularity*/ + +#define MS_RING_PLAYER_END_OF_RING_EVENT 1 + +struct _MSRingPlayer +{ + /* the MSRingPlayer derivates from MSFilter, so the MSFilter object MUST be the first of the MSRingPlayer object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *foutputs[MS_RING_PLAYER_MAX_OUTPUTS]; + MSQueue *qoutputs[MS_RING_PLAYER_MAX_OUTPUTS];\ + MSSync *sync; + gint gran; + gint freq; + gint rate; + gint channel; /* number of interleaved channels */ + gint silence; /* silence time between each ring, in seconds */ + gint state; + gint fd; /* the file descriptor of the file being read*/ + gint silence_bytes; /*silence in number of bytes between each ring */ + gint current_pos; + gint need_swap; +}; + +typedef struct _MSRingPlayer MSRingPlayer; + +struct _MSRingPlayerClass +{ + /* the MSRingPlayer derivates from MSFilter, so the MSFilter class MUST be the first of the MSRingPlayer class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +}; + +typedef struct _MSRingPlayerClass MSRingPlayerClass; + +/* PUBLIC */ +#define MS_RING_PLAYER(filter) ((MSRingPlayer*)(filter)) +#define MS_RING_PLAYER_CLASS(klass) ((MSRingPlayerClass*)(klass)) +MSFilter * ms_ring_player_new(char *name, gint seconds); +gint ms_ring_player_get_sample_freq(MSRingPlayer *obj); + + +/* FOR INTERNAL USE*/ +void ms_ring_player_init(MSRingPlayer *r); +void ms_ring_player_class_init(MSRingPlayerClass *klass); +void ms_ring_player_destroy( MSRingPlayer *obj); +void ms_ring_player_process(MSRingPlayer *r); +#define ms_ring_player_set_bufsize(filter,sz) (filter)->gran=(sz) +void ms_ring_player_setup(MSRingPlayer *r,MSSync *sync); +#endif diff --git a/linphone/mediastreamer/msrtprecv.c b/linphone/mediastreamer/msrtprecv.c new file mode 100644 index 000000000..2c7d40a58 --- /dev/null +++ b/linphone/mediastreamer/msrtprecv.c @@ -0,0 +1,182 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msrtprecv.h" + + +/* some utilities to convert mblk_t to MSMessage and vice-versa */ +MSMessage *msgb_2_ms_message(mblk_t* mp){ + MSMessage *msg; + MSBuffer *msbuf; + if (mp->b_datap->ref_count!=1) return NULL; /* cannot handle properly non-unique buffers*/ + /* create a MSBuffer using the mblk_t buffer */ + msg=ms_message_alloc(); + msbuf=ms_buffer_new_with_buf(mp->b_datap->db_base,mp->b_datap->db_lim-mp->b_datap->db_base, + freemsg,mp); + ms_message_set_buf(msg,msbuf); + msg->size=mp->b_wptr-mp->b_rptr; + msg->data=mp->b_rptr; + return msg; +} + + +static MSRtpRecvClass *ms_rtp_recv_class=NULL; + +MSFilter * ms_rtp_recv_new(void) +{ + MSRtpRecv *r; + + r=g_new(MSRtpRecv,1); + ms_rtp_recv_init(r); + if (ms_rtp_recv_class==NULL) + { + ms_rtp_recv_class=g_new0(MSRtpRecvClass,1); + ms_rtp_recv_class_init(ms_rtp_recv_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_recv_class); + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_rtp_recv_init(MSRtpRecv *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->outfifos=r->f_outputs; + MS_FILTER(r)->outqueues=r->q_outputs; + memset(r->f_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS); + memset(r->q_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS); + r->rtpsession=NULL; + r->stream_started=0; + r->ignore=FALSE; + r->payload_expected=0; +} + +void ms_rtp_recv_class_init(MSRtpRecvClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPRecv"); + MS_FILTER_CLASS(klass)->max_qoutputs=MSRTPRECV_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->max_foutputs=MSRTPRECV_MAX_OUTPUTS; + MS_FILTER_CLASS(klass)->w_maxgran=MSRTPRECV_DEF_GRAN; + ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE); + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_recv_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_recv_process; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_recv_setup; +} + +void ms_rtp_recv_process(MSRtpRecv *r) +{ + MSFifo *fo; + MSQueue *qo; + MSSync *sync= r->sync; + void *d; + mblk_t *mp; + gint len; + gint gran=ms_sync_get_samples_per_tick(MS_SYNC(sync)); + + if (r->rtpsession==NULL) return; + /* process output fifo and output queue*/ + fo=r->f_outputs[0]; + if (fo!=NULL) + { + while( (mp=rtp_session_recvm_with_ts(r->rtpsession,r->prev_ts))!=NULL) { + /* try to get rtp packets and paste them to the output fifo */ + r->stream_started=1; + len=mp->b_cont->b_wptr-mp->b_cont->b_rptr; + ms_fifo_get_write_ptr(fo,len,&d); + if (d!=NULL){ + memcpy(d,mp->b_cont->b_rptr,len); + }else ms_warning("ms_rtp_recv_process: no space on output fifo !"); + freemsg(mp); + } + r->prev_ts+=gran; + + } + qo=r->q_outputs[0]; + if (qo!=NULL) + { + guint32 clock; + gint got=0; + /* we are connected with queues (surely for video)*/ + /* use the sync system time to compute a timestamp */ + PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->send_pt); + if (pt==NULL) { + ms_warning("ms_rtp_recv_process(): NULL RtpPayload- skipping."); + return; + } + clock=(guint32)(((double)sync->time*(double)pt->clock_rate)/1000.0); + /*g_message("Querying packet with timestamp %u",clock);*/ + /* get rtp packet, and send them through the output queue */ + while ( (mp=rtp_session_recvm_with_ts(r->rtpsession,clock))!=NULL ){ + MSMessage *msg; + mblk_t *mdata; + /*g_message("Got packet with timestamp %u",clock);*/ + got++; + r->stream_started=1; + if (!r->ignore){ + gboolean markbit=((rtp_header_t*)mp->b_rptr)->markbit; + mdata=mp->b_cont; + freeb(mp); + msg=msgb_2_ms_message(mdata); + msg->markbit=markbit; + ms_queue_put(qo,msg); + + }else{ + freemsg(mp); + } + } + } +} + +void ms_rtp_recv_destroy( MSRtpRecv *obj) +{ + g_free(obj); +} + +static void __payload_type_changed(RtpSession *session,MSRtpRecv *obj){ + int pt_num=rtp_session_get_recv_payload_type(session); + PayloadType *pt=rtp_profile_get_payload(rtp_session_get_profile(session),pt_num); + if (pt==NULL){ + /* sip phone should ignore payload types they don't understand */ + g_warning("Ignoring payload type %i",pt_num); + obj->ignore=TRUE; + }else{ + if (obj->ignore) g_warning("payload type is coming back to something known"); + obj->ignore=FALSE; + } +} + +RtpSession * ms_rtp_recv_set_session(MSRtpRecv *obj,RtpSession *session) +{ + RtpSession *old=obj->rtpsession; + obj->rtpsession=session; + rtp_session_signal_connect(session,"payload_type_changed",(RtpCallback)__payload_type_changed,(unsigned long)obj); + obj->prev_ts=0; + return old; +} + + +void ms_rtp_recv_setup(MSRtpRecv *r,MSSync *sync) +{ + r->sync=sync; + r->stream_started=0; +} diff --git a/linphone/mediastreamer/msrtprecv.h b/linphone/mediastreamer/msrtprecv.h new file mode 100644 index 000000000..e2c91083f --- /dev/null +++ b/linphone/mediastreamer/msrtprecv.h @@ -0,0 +1,82 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSRTPRECV_H +#define MSRTPRECV_H + +#include "msfilter.h" +#include "mssync.h" + +/* because of a conflict between config.h from oRTP and config.h from linphone:*/ +#undef PACKAGE +#undef VERSION +#include + +/*this is the class that implements a copy filter*/ + +#define MSRTPRECV_MAX_OUTPUTS 1 /* max output per filter*/ + +#define MSRTPRECV_DEF_GRAN 320 /* the default granularity*/ + +struct _MSRtpRecv +{ + /* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_outputs[MSRTPRECV_MAX_OUTPUTS]; + MSQueue *q_outputs[MSRTPRECV_MAX_OUTPUTS]; + MSSync *sync; + RtpSession *rtpsession; + guint32 prev_ts; + gint stream_started; + gint payload_expected; + gboolean ignore; +}; + +typedef struct _MSRtpRecv MSRtpRecv; + +struct _MSRtpRecvClass +{ + /* the MSCopy derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +}; + +typedef struct _MSRtpRecvClass MSRtpRecvClass; + +/* PUBLIC */ +#define MS_RTP_RECV(filter) ((MSRtpRecv*)(filter)) +#define MS_RTP_RECV_CLASS(klass) ((MSRtpRecvClass*)(klass)) +MSFilter * ms_rtp_recv_new(void); +RtpSession * ms_rtp_recv_set_session(MSRtpRecv *obj,RtpSession *session); +#define ms_rtp_recv_unset_session(obj) (ms_rtp_recv_set_session((obj),NULL)) +#define ms_rtp_recv_get_session(obj) ((obj)->rtpsession) + + + +/* FOR INTERNAL USE*/ +void ms_rtp_recv_init(MSRtpRecv *r); +void ms_rtp_recv_class_init(MSRtpRecvClass *klass); +void ms_rtp_recv_destroy( MSRtpRecv *obj); +void ms_rtp_recv_process(MSRtpRecv *r); +void ms_rtp_recv_setup(MSRtpRecv *r,MSSync *sync); + +#endif diff --git a/linphone/mediastreamer/msrtpsend.c b/linphone/mediastreamer/msrtpsend.c new file mode 100644 index 000000000..414bf597c --- /dev/null +++ b/linphone/mediastreamer/msrtpsend.c @@ -0,0 +1,213 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msrtpsend.h" +#include +#include "mssync.h" +#include "mscodec.h" + + + +static MSRtpSendClass *ms_rtp_send_class=NULL; + +MSFilter * ms_rtp_send_new(void) +{ + MSRtpSend *r; + + r=g_new(MSRtpSend,1); + + if (ms_rtp_send_class==NULL) + { + ms_rtp_send_class=g_new(MSRtpSendClass,1); + ms_rtp_send_class_init(ms_rtp_send_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_send_class); + ms_rtp_send_init(r); + return(MS_FILTER(r)); +} + + +void ms_rtp_send_init(MSRtpSend *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->inqueues=r->q_inputs; + MS_FILTER(r)->r_mingran=MSRTPSEND_DEF_GRAN; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS); + memset(r->q_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS); + r->rtpsession=NULL; + r->ts=0; + r->ts_inc=0; + r->flags=0; + r->delay=0; +} + +void ms_rtp_send_class_init(MSRtpSendClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPSend"); + MS_FILTER_CLASS(klass)->max_qinputs=MSRTPSEND_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_finputs=MSRTPSEND_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=MSRTPSEND_DEF_GRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_send_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_send_process; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_send_setup; +} + +void ms_rtp_send_set_timing(MSRtpSend *r, guint32 ts_inc, gint payload_size) +{ + r->ts_inc=ts_inc; + r->packet_size=payload_size; + if (r->ts_inc!=0) r->flags|=RTPSEND_CONFIGURED; + else r->flags&=~RTPSEND_CONFIGURED; + MS_FILTER(r)->r_mingran=payload_size; + /*g_message("ms_rtp_send_set_timing: ts_inc=%i",ts_inc);*/ +} + +guint32 get_new_timestamp(MSRtpSend *r,guint32 synctime) +{ + guint32 clockts; + /* use the sync system time to compute a timestamp */ + PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->send_pt); + g_return_val_if_fail(pt!=NULL,0); + clockts=(guint32)(((double)synctime * (double)pt->clock_rate)/1000.0); + ms_trace("ms_rtp_send_process: sync->time=%i clock=%i",synctime,clockts); + if (r->flags & RTPSEND_CONFIGURED){ + if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(clockts,r->ts+(2*r->ts_inc) )){ + r->ts=clockts; + } + else r->ts+=r->ts_inc; + }else{ + r->ts=clockts; + } + return r->ts; +} + + +void ms_rtp_send_process(MSRtpSend *r) +{ + MSFifo *fi; + MSQueue *qi; + MSSync *sync= r->sync; + int gran=ms_sync_get_samples_per_tick(sync); + guint32 ts; + void *s; + guint skip; + guint32 synctime=sync->time; + + g_return_if_fail(gran>0); + if (r->rtpsession==NULL) return; + + ms_filter_lock(MS_FILTER(r)); + skip=r->delay!=0; + if (skip) r->delay--; + /* process output fifo and output queue*/ + fi=r->f_inputs[0]; + if (fi!=NULL) + { + ts=get_new_timestamp(r,synctime); + /* try to read r->packet_size bytes and send them in a rtp packet*/ + ms_fifo_get_read_ptr(fi,r->packet_size,&s); + if (!skip){ + rtp_session_send_with_ts(r->rtpsession,s,r->packet_size,ts); + ms_trace("len=%i, ts=%i ",r->packet_size,ts); + } + } + qi=r->q_inputs[0]; + if (qi!=NULL) + { + MSMessage *msg; + /* read a MSMessage and send it through the network*/ + while ( (msg=ms_queue_get(qi))!=NULL){ + ts=get_new_timestamp(r,synctime); + if (!skip) { + /*g_message("Sending packet with ts=%u",ts);*/ + mblk_t *packet=rtp_session_create_packet_with_data(r->rtpsession,msg->data,msg->size,NULL); + rtp_set_markbit(packet,msg->markbit); + rtp_session_sendm_with_ts(r->rtpsession,packet,ts); + + } + ms_message_destroy(msg); + } + } + ms_filter_unlock(MS_FILTER(r)); +} + +void ms_rtp_send_destroy( MSRtpSend *obj) +{ + g_free(obj); +} + +RtpSession * ms_rtp_send_set_session(MSRtpSend *obj,RtpSession *session) +{ + RtpSession *old=obj->rtpsession; + obj->rtpsession=session; + obj->ts=0; + obj->ts_inc=0; + return old; +} + +void ms_rtp_send_setup(MSRtpSend *r, MSSync *sync) +{ + MSFilter *codec; + MSCodecInfo *info; + r->sync=sync; + codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_AUDIO_CODEC); + if (codec==NULL) codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_VIDEO_CODEC); + if (codec==NULL){ + g_warning("ms_rtp_send_setup: could not find upstream codec."); + return; + } + info=MS_CODEC_INFO(codec->klass->info); + if (info->info.type==MS_FILTER_AUDIO_CODEC){ + int ts_inc=info->fr_size/2; + int psize=info->dt_size; + if (ts_inc==0){ + /* dont'use the normal frame size: this is a variable frame size codec */ + /* use the MS_FILTER(codec)->r_mingran */ + ts_inc=MS_FILTER(codec)->r_mingran/2; + psize=0; + } + ms_rtp_send_set_timing(r,ts_inc,psize); + } +} + +gint ms_rtp_send_dtmf(MSRtpSend *r, gchar dtmf) +{ + gint res; + + if (r->rtpsession==NULL) return -1; + if (rtp_session_telephone_events_supported(r->rtpsession)==-1){ + g_warning("ERROR : telephone events not supported.\n"); + return -1; + } + + ms_filter_lock(MS_FILTER(r)); + g_message("Sending DTMF."); + res=rtp_session_send_dtmf(r->rtpsession, dtmf, r->ts); + if (res==0){ + //r->ts+=r->ts_inc; + r->delay+=2; + }else g_warning("Could not send dtmf."); + + ms_filter_unlock(MS_FILTER(r)); + + return res; +} diff --git a/linphone/mediastreamer/msrtpsend.h b/linphone/mediastreamer/msrtpsend.h new file mode 100644 index 000000000..072879acb --- /dev/null +++ b/linphone/mediastreamer/msrtpsend.h @@ -0,0 +1,85 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSRTPSEND_H +#define MSRTPSEND_H + +#include "msfilter.h" +#include "mssync.h" + +#undef PACKAGE +#undef VERSION +#include + + +/*this is the class that implements a sending through rtp filter*/ + +#define MSRTPSEND_MAX_INPUTS 1 /* max input per filter*/ + +#define MSRTPSEND_DEF_GRAN 160/* the default granularity*/ + +struct _MSRtpSend +{ + /* the MSCopy derivates from MSFilter, so the MSFilter object MUST be the first of the MSCopy object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSRTPSEND_MAX_INPUTS]; + MSQueue *q_inputs[MSRTPSEND_MAX_INPUTS]; + MSSync *sync; + RtpSession *rtpsession; + guint32 ts; + guint32 ts_inc; /* the timestamp increment */ + gint packet_size; + guint flags; + guint delay; /* number of _proccess call which must be skipped */ +#define RTPSEND_CONFIGURED (1) +}; + +typedef struct _MSRtpSend MSRtpSend; + +struct _MSRtpSendClass +{ + /* the MSRtpSend derivates from MSFilter, so the MSFilter class MUST be the first of the MSCopy class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +}; + +typedef struct _MSRtpSendClass MSRtpSendClass; + +/* PUBLIC */ +#define MS_RTP_SEND(filter) ((MSRtpSend*)(filter)) +#define MS_RTP_SEND_CLASS(klass) ((MSRtpSendClass*)(klass)) +MSFilter * ms_rtp_send_new(void); +RtpSession * ms_rtp_send_set_session(MSRtpSend *obj,RtpSession *session); +#define ms_rtp_send_unset_session(obj) (ms_rtp_send_set_session((obj),NULL)) +#define ms_rtp_send_get_session(obj) ((obj)->rtpsession) +void ms_rtp_send_set_timing(MSRtpSend *r, guint32 ts_inc, gint payload_size); +gint ms_rtp_send_dtmf(MSRtpSend *r, gchar dtmf); + + +/* FOR INTERNAL USE*/ +void ms_rtp_send_init(MSRtpSend *r); +void ms_rtp_send_class_init(MSRtpSendClass *klass); +void ms_rtp_send_destroy( MSRtpSend *obj); +void ms_rtp_send_process(MSRtpSend *r); +void ms_rtp_send_setup(MSRtpSend *r, MSSync *sync); + +#endif diff --git a/linphone/mediastreamer/mssdlout.c b/linphone/mediastreamer/mssdlout.c new file mode 100644 index 000000000..8e49cd338 --- /dev/null +++ b/linphone/mediastreamer/mssdlout.c @@ -0,0 +1,303 @@ +/*************************************************************************** + * mssdlout.c + * + * Mon Jul 11 16:17:59 2005 + * Copyright 2005 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ + +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mssdlout.h" + +MSSdlOutClass *ms_sdl_out_class=NULL; + +void ms_sdl_out_init(MSSdlOut *obj){ + ms_filter_init(MS_FILTER(obj)); + obj->width=VIDEO_SIZE_CIF_W; + obj->height=VIDEO_SIZE_CIF_H; + obj->format="RGB24"; + obj->use_yuv=FALSE; + obj->oldinm1=NULL; + MS_FILTER(obj)->inqueues=obj->input; +} + +void ms_sdl_out_set_format(MSSdlOut *obj, const char *fmt){ + obj->format=fmt; + if (strcmp(fmt,"YUV420P")==0) obj->use_yuv=TRUE; + else obj->use_yuv=FALSE; +} + +void ms_sdl_uninit_sdl(MSSdlOut *obj){ + if (obj->overlay!=NULL){ + SDL_FreeYUVOverlay(obj->overlay); + obj->overlay=NULL; + } + if (obj->screen!=NULL){ + SDL_FreeSurface(obj->screen); + obj->screen=NULL; + } + +} + +void ms_sdl_out_uninit(MSSdlOut *obj){ + ms_sdl_uninit_sdl(obj); +} + +void ms_sdl_out_destroy(MSSdlOut *obj){ + ms_sdl_out_uninit(obj); + if (obj->oldinm1!=NULL) ms_message_destroy(obj->oldinm1); + g_free(obj); +} + +void ms_sdl_init_sdl(MSSdlOut *obj){ + if (strcmp(obj->format,"RGB24")==0){ + }else{ + obj->use_yuv=TRUE; + } + obj->screen = SDL_SetVideoMode(obj->width, obj->height, 0,SDL_HWSURFACE|SDL_ANYFORMAT); + if ( obj->screen == NULL ) { + g_warning("Couldn't set video mode: %s\n", + SDL_GetError()); + return ; + } + if (obj->screen->flags & SDL_HWSURFACE) g_message("SDL surface created in hardware"); + SDL_WM_SetCaption("Linphone Video", NULL); + + if (obj->use_yuv){ + g_message("Using yuv overlay."); + obj->overlay=SDL_CreateYUVOverlay(obj->width,obj->height,SDL_IYUV_OVERLAY,obj->screen); + if (obj->overlay==NULL){ + g_warning("Couldn't create yuv overlay: %s\n", + SDL_GetError()); + }else{ + if (obj->overlay->hw_overlay) g_message("YUV overlay using hardware acceleration."); + } + } + +} + +static void resize_yuv_small(char *pict, int w, int h, int scale){ + int i,j,id,jd; + int nh,nw; + char *smallpict; + int ysize,usize,ydsize,udsize; + int smallpict_sz; + char *dptr,*sptr; + nw=w/scale; + nh=h/scale; + ysize=w*h; + usize=ysize/4; + ydsize=nw*nh; + udsize=ydsize/4; + smallpict_sz=(ydsize*3)/2; + smallpict=(char*)alloca(smallpict_sz); + memset(smallpict,0,smallpict_sz); + + + dptr=smallpict; + sptr=pict; + for (j=0,jd=0;jdata; + int i,j; + int jlim,ilim; + int off; + char *dptr; + + ilim=MIN(x+w,lay->w); + jlim=MIN(y+h,lay->h); + SDL_LockYUVOverlay(lay); + /* set Y */ + dptr=lay->pixels[0]; + for (j=y;jw; + for (i=x;ipixels[1]; + for (j=y/2;jw/2); + for (i=x/2;ipixels[2]; + for (j=y/2;jw/2); + for (i=x/2;idata; + int ysize=lay->w*lay->h; + int usize; + w2=lay->w/2; + h2=lay->h/2; + usize=w2*h2; + SDL_LockYUVOverlay(lay); + memcpy(lay->pixels[0],data,ysize); + memcpy(lay->pixels[1],data+ysize,usize); + memcpy(lay->pixels[2],data+ysize+usize,usize); + SDL_UnlockYUVOverlay(lay); +} + +#define SCALE_FACTOR 6 + +void ms_sdl_out_process(MSSdlOut *obj){ + MSQueue *q0=obj->input[0]; + MSQueue *q1=obj->input[1]; + MSMessage *inm0=NULL; + MSMessage *inm1=NULL; + int err; + SDL_Rect smallrect; + SDL_Rect rect; + rect.w=obj->width; + rect.h=obj->height; + rect.x=0; + rect.y=0; + smallrect.w=obj->width/SCALE_FACTOR; + smallrect.h=obj->height/SCALE_FACTOR; + smallrect.x=obj->width - smallrect.w ; + smallrect.y=obj->height -smallrect.h; + + if (obj->screen==NULL){ + ms_sdl_init_sdl(obj); + } + + if (q0!=NULL) + inm0=ms_queue_get(q0); + if (q1!=NULL) + inm1=ms_queue_get(q1); + + if (inm0!=NULL){ + SDL_Surface *surf; + if (obj->use_yuv){ + + fill_overlay(obj->overlay,inm0); + + }else { + surf=SDL_CreateRGBSurfaceFrom(inm0->data,obj->width,obj->height,24,obj->width*3,0,0,0,0); + + err=SDL_BlitSurface(surf,NULL,obj->screen,NULL); + if (err<0) g_warning("Fail to blit surface: %s",SDL_GetError()); + SDL_FreeSurface(surf); + } + ms_message_destroy(inm0); + } + if (inm1!=NULL){ + /* this message is blitted on the right,bottom corner of the screen */ + SDL_Surface *surf; + + if (obj->use_yuv){ + resize_yuv_small(inm1->data,rect.w,rect.h,SCALE_FACTOR); + fill_overlay_at_pos(obj->overlay,inm1,smallrect.x, smallrect.y, smallrect.w, smallrect.h); + }else { + surf=SDL_CreateRGBSurfaceFrom(inm1->data,obj->width,obj->height,24,obj->width*3,0,0,0,0); + + err=SDL_BlitSurface(surf,NULL,obj->screen,&smallrect); + if (err<0) g_warning("Fail to blit surface: %s",SDL_GetError()); + SDL_FreeSurface(surf); + } + if (obj->oldinm1!=NULL) { + ms_message_destroy(obj->oldinm1); + } + obj->oldinm1=inm1; + + }else{ + /* this is the case were we have only inm0, we have to redisplay inm1 */ + if (obj->use_yuv){ + if (obj->oldinm1!=NULL){ + fill_overlay_at_pos(obj->overlay,obj->oldinm1,smallrect.x, smallrect.y, smallrect.w, smallrect.h); + } + } + } + + if (obj->use_yuv) SDL_DisplayYUVOverlay(obj->overlay,&rect); + SDL_UpdateRect(obj->screen,0,0,obj->width,obj->height); + +} + +void ms_sdl_out_class_init(MSSdlOutClass *klass){ + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_sdl_out_process; + MS_FILTER_CLASS(klass)->max_qinputs=2; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_sdl_out_destroy; + MS_FILTER_CLASS(klass)->name="MSSdlOut"; + /* Initialize the SDL library */ + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + fprintf(stderr, + "Couldn't initialize SDL: %s\n", SDL_GetError()); + return; + } + /* Clean up on exit */ + atexit(SDL_Quit); +} + +MSFilter * ms_sdl_out_new(void){ + MSSdlOut *obj=g_new0(MSSdlOut,1); + if (ms_sdl_out_class==NULL){ + ms_sdl_out_class=g_new0(MSSdlOutClass,1); + ms_sdl_out_class_init(ms_sdl_out_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_sdl_out_class); + ms_sdl_out_init(obj); + return MS_FILTER(obj); +} diff --git a/linphone/mediastreamer/mssdlout.h b/linphone/mediastreamer/mssdlout.h new file mode 100644 index 000000000..fd6ec547a --- /dev/null +++ b/linphone/mediastreamer/mssdlout.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * mssdlout.h + * + * Mon Jul 11 16:18:55 2005 + * Copyright 2005 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ + +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef mssdlout_h +#define mssdlout_h + +#include "msfilter.h" + +#include +#include + +struct _MSSdlOut +{ + MSFilter parent; + MSQueue *input[2]; + gint width,height; + const gchar *format; + SDL_Surface *screen; + SDL_Overlay *overlay; + MSMessage *oldinm1; + gboolean use_yuv; +}; + + +typedef struct _MSSdlOut MSSdlOut; + +struct _MSSdlOutClass +{ + MSFilterClass parent_class; +}; + +typedef struct _MSSdlOutClass MSSdlOutClass; + +MSFilter * ms_sdl_out_new(void); +void ms_sdl_out_set_format(MSSdlOut *obj, const char *fmt); + +#define MS_SDL_OUT(obj) ((MSSdlOut*)obj) + +#endif diff --git a/linphone/mediastreamer/mssmpeg.c b/linphone/mediastreamer/mssmpeg.c new file mode 100644 index 000000000..5eb2cd9f3 --- /dev/null +++ b/linphone/mediastreamer/mssmpeg.c @@ -0,0 +1,181 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mssmpeg.h" +#include +#include + + +static MSSmpegClass *ms_smpeg_class=NULL; + + +int seek_mpeg_data(struct SDL_RWops *context, int offset, int whence) +{ + MSSmpeg *obj=context->hidden.unknown.data1; + g_message("Entering seek function offset=%i whence=%i",offset,whence); + switch (whence) + { + case SEEK_SET: + obj->pos=offset; + break; + case SEEK_CUR: + return obj->pos; + break; + case SEEK_END: + return obj->end_pos; + break; + } + return 0; +} + +int read_mpeg_data(struct SDL_RWops *context, void *ptr, int size, int maxnum) +{ + MSSmpeg *obj=context->hidden.unknown.data1; + gint bytes; + g_message("Entering read function: size=%i maxnum=%i",size,maxnum); + if (obj->pos>=obj->end_pos) + { + g_message("End of file"); + return 0; + } + if (obj->current==NULL) + { + g_message("Nothing to read."); + return 0; + } + bytes=MIN(maxnum,obj->current->size); + memcpy(ptr,obj->current->data,bytes); + obj->pos+=bytes; + //obj->current; + return bytes; +} + +void ms_smpeg_init(MSSmpeg *obj) +{ + gint error; + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->inqueues=obj->input; + obj->surface = SDL_SetVideoMode ( 400, 400,0 , SDL_HWSURFACE ); + if (obj->surface==NULL) + { + g_error("Could not create a SDL surface"); + } + /* + error=pipe(obj->fd); + if (error<0) + { + g_error("Could not create pipe !"); + } + fcntl(obj->fd[1],F_SETFL,O_NONBLOCK); + */ + obj->rwops=SDL_AllocRW(); + obj->rwops->read=read_mpeg_data; + obj->rwops->seek=seek_mpeg_data; + obj->rwops->hidden.unknown.data1=(void*)obj; + obj->pos=0; + obj->end_pos=0; +} + +void ms_smpeg_class_init(MSSmpegClass *klass) +{ + int error; + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_qinputs=1; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_smpeg_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_smpeg_process; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MSSmpeg"); + error=SDL_Init(SDL_INIT_VIDEO); + if (error<0){ + g_error("Could not initialize SDL !"); + } + +} + +void ms_smpeg_uninit(MSSmpeg *obj) +{ + +} + +MSFilter * ms_smpeg_new() +{ + MSSmpeg *obj=g_malloc(sizeof(MSSmpeg)); + + if (ms_smpeg_class==NULL) + { + ms_smpeg_class=g_malloc(sizeof(MSSmpegClass)); + ms_smpeg_class_init(ms_smpeg_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_smpeg_class); + ms_smpeg_init(obj); + return MS_FILTER(obj); +} + +void ms_smpeg_start(MSSmpeg *obj) +{ + //SMPEG_play(obj->handle); + obj->first_time=1; + obj->run_cond=1; +} + +void ms_smpeg_stop(MSSmpeg *obj) +{ + SMPEG_stop(obj->handle); + obj->run_cond=0; +} + +void ms_smpeg_process(MSSmpeg *obj) +{ + MSQueue *q=obj->input[0]; + MSMessage *m; + SMPEG_Info info; + + while((m=ms_queue_get(q))!=NULL) + { + g_message("Getting new buffer"); + if (obj->run_cond) + { + obj->current=m; + obj->end_pos+=m->size; + if (obj->first_time) + { + obj->handle=SMPEG_new_rwops(obj->rwops,NULL,0); + if (obj->handle==NULL){ + g_error("Could not create smpeg object."); + } + SMPEG_setdisplay(obj->handle,obj->surface,NULL,NULL); + obj->first_time=0; + //SMPEG_play(obj->handle); + } + SMPEG_getinfo(obj->handle, &info ); + g_message("Current frame is %i",info.current_frame); + SMPEG_renderFrame(obj->handle, info.current_frame+1); + } + ms_message_destroy(m); + obj->current=NULL; + } +} + +void ms_smpeg_destroy(MSSmpeg *obj) +{ + ms_smpeg_uninit(obj); + g_free(obj); +} + diff --git a/linphone/mediastreamer/mssmpeg.h b/linphone/mediastreamer/mssmpeg.h new file mode 100644 index 000000000..331414f81 --- /dev/null +++ b/linphone/mediastreamer/mssmpeg.h @@ -0,0 +1,70 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSSMPEG_H +#define MSSMPEG_H + + +#include "ms.h" +#include "msfilter.h" + +#include +#include + +struct _MSSmpeg +{ + MSFilter parent; + MSQueue *input[1]; + SMPEG *handle; + SDL_Surface *surface; + SDL_RWops *rwops; + int run_cond; + int first_time; + MSMessage *current; + int pos; + int end_pos; +}; + + +typedef struct _MSSmpeg MSSmpeg; + +struct _MSSmpegClass +{ + MSFilterClass parent_class; +}; + +typedef struct _MSSmpegClass MSSmpegClass; + + +#define MS_SMPEG(obj) ((MSSmpeg*)(obj)) +#define MS_SMPEG_CLASS(klass) ((MSSmpegClass*)(klass)) + +void ms_smpeg_init(MSSmpeg *obj); +void ms_smpeg_class_init(MSSmpegClass *klass); +void ms_smpeg_uninit(MSSmpeg *obj); + +MSFilter * ms_smpeg_new(); +void ms_smpeg_start(MSSmpeg *obj); +void ms_smpeg_stop(MSSmpeg *obj); + + +void ms_smpeg_destroy(MSSmpeg *obj); +void ms_smpeg_process(MSSmpeg *obj); +#endif \ No newline at end of file diff --git a/linphone/mediastreamer/mssoundread.c b/linphone/mediastreamer/mssoundread.c new file mode 100644 index 000000000..c77107a3a --- /dev/null +++ b/linphone/mediastreamer/mssoundread.c @@ -0,0 +1,38 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation + + */ + +#include "mssoundread.h" + + +void ms_sound_read_init(MSSoundRead *w) +{ + ms_filter_init(MS_FILTER(w)); + +} + +void ms_sound_read_class_init(MSSoundReadClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_foutputs=1; /* one fifo output only */ + + ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_IS_SOURCE); +} + diff --git a/linphone/mediastreamer/mssoundread.h b/linphone/mediastreamer/mssoundread.h new file mode 100644 index 000000000..7f2cab938 --- /dev/null +++ b/linphone/mediastreamer/mssoundread.h @@ -0,0 +1,80 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSSOUNDREAD_H +#define MSSOUNDREAD_H + +#include "msfilter.h" +#include "mssync.h" + + + +struct _MSSoundRead +{ + /* the MSOssRead derivates from MSFilter, so the MSFilter object MUST be the first of the MSOssRead object + in order to the object mechanism to work*/ + MSFilter filter; +}; + +typedef struct _MSSoundRead MSSoundRead; + +struct _MSSoundReadClass +{ + /* the MSOssRead derivates from MSFilter, so the MSFilter class MUST be the first of the MSOssRead class + in order to the class mechanism to work*/ + MSFilterClass parent_class; + gint (*set_device)(MSSoundRead *, gint devid); + void (*start)(MSSoundRead *); + void (*stop)(MSSoundRead*); + void (*set_level)(MSSoundRead *, gint a); +}; + +typedef struct _MSSoundReadClass MSSoundReadClass; + +/* PUBLIC */ +#define MS_SOUND_READ(filter) ((MSSoundRead*)(filter)) +#define MS_SOUND_READ_CLASS(klass) ((MSSoundReadClass*)(klass)) + +static inline int ms_sound_read_set_device(MSSoundRead *r,gint devid) +{ + return MS_SOUND_READ_CLASS( MS_FILTER(r)->klass )->set_device(r,devid); +} + +static inline void ms_sound_read_start(MSSoundRead *r) +{ + MS_SOUND_READ_CLASS( MS_FILTER(r)->klass )->start(r); +} + +static inline void ms_sound_read_stop(MSSoundRead *w) +{ + MS_SOUND_READ_CLASS( MS_FILTER(w)->klass )->stop(w); +} + +static inline void ms_sound_read_set_level(MSSoundRead *w,gint a) +{ + MS_SOUND_READ_CLASS( MS_FILTER(w)->klass )->set_level(w,a); +} + +/* FOR INTERNAL USE*/ +void ms_sound_read_init(MSSoundRead *r); +void ms_sound_read_class_init(MSSoundReadClass *klass); + + +#endif + diff --git a/linphone/mediastreamer/mssoundwrite.c b/linphone/mediastreamer/mssoundwrite.c new file mode 100644 index 000000000..f1b765ab0 --- /dev/null +++ b/linphone/mediastreamer/mssoundwrite.c @@ -0,0 +1,38 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation + + */ + +#include "mssoundwrite.h" + + +void ms_sound_write_init(MSSoundWrite *w) +{ + ms_filter_init(MS_FILTER(w)); + +} + +void ms_sound_write_class_init(MSSoundWriteClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_finputs=1; /* one fifo output only */ + + ms_filter_class_set_attr( MS_FILTER_CLASS(klass),FILTER_IS_SINK); +} + diff --git a/linphone/mediastreamer/mssoundwrite.h b/linphone/mediastreamer/mssoundwrite.h new file mode 100644 index 000000000..e6d79874e --- /dev/null +++ b/linphone/mediastreamer/mssoundwrite.h @@ -0,0 +1,80 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSSOUNDWRITE_H +#define MSSOUNDWRITE_H + +#include "msfilter.h" +#include "mssync.h" + + + +struct _MSSoundWrite +{ + /* the MSOssWrite derivates from MSFilter, so the MSFilter object MUST be the first of the MSOssWrite object + in order to the object mechanism to work*/ + MSFilter filter; +}; + +typedef struct _MSSoundWrite MSSoundWrite; + +struct _MSSoundWriteClass +{ + /* the MSOssWrite derivates from MSFilter, so the MSFilter class MUST be the first of the MSOssWrite class + in order to the class mechanism to work*/ + MSFilterClass parent_class; + gint (*set_device)(MSSoundWrite *, gint devid); + void (*start)(MSSoundWrite *); + void (*stop)(MSSoundWrite*); + void (*set_level)(MSSoundWrite *, gint a); +}; + +typedef struct _MSSoundWriteClass MSSoundWriteClass; + +/* PUBLIC */ +#define MS_SOUND_WRITE(filter) ((MSSoundWrite*)(filter)) +#define MS_SOUND_WRITE_CLASS(klass) ((MSSoundWriteClass*)(klass)) + +static inline int ms_sound_write_set_device(MSSoundWrite *r,gint devid) +{ + return MS_SOUND_WRITE_CLASS( MS_FILTER(r)->klass )->set_device(r,devid); +} + +static inline void ms_sound_write_start(MSSoundWrite *r) +{ + MS_SOUND_WRITE_CLASS( MS_FILTER(r)->klass )->start(r); +} + +static inline void ms_sound_write_stop(MSSoundWrite *w) +{ + MS_SOUND_WRITE_CLASS( MS_FILTER(w)->klass )->stop(w); +} + +static inline void ms_sound_write_set_level(MSSoundWrite *w,gint a) +{ + MS_SOUND_WRITE_CLASS( MS_FILTER(w)->klass )->set_level(w,a); +} + +/* FOR INTERNAL USE*/ +void ms_sound_write_init(MSSoundWrite *r); +void ms_sound_write_class_init(MSSoundWriteClass *klass); + + +#endif + diff --git a/linphone/mediastreamer/msspeexdec.c b/linphone/mediastreamer/msspeexdec.c new file mode 100644 index 000000000..df6021250 --- /dev/null +++ b/linphone/mediastreamer/msspeexdec.c @@ -0,0 +1,215 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msspeexdec.h" + +#ifdef HAVE_GLIB +#include +#endif + +extern MSFilter * ms_speex_enc_new(); + +MSCodecInfo speex_info= +{ + { + "Speex codec", + 0, + MS_FILTER_AUDIO_CODEC, + ms_speex_dec_new, + "A high quality variable bit-rate codec from Jean Marc Valin and David Rowe." + }, + ms_speex_enc_new, + ms_speex_dec_new, + 0, /*frame size */ + 0, + 8000, /*minimal bitrate */ + -1, /* sampling frequency */ + 110, /* payload type */ + "speex", + 1, + 1 +}; + + + +void ms_speex_codec_init() +{ + + ms_filter_register(MS_FILTER_INFO(&speex_info)); + //ms_filter_register(MS_FILTER_INFO(&speex_lbr_info)); +} + +#ifdef HAVE_GLIB +gchar * g_module_check_init(GModule *module) +{ + ms_speex_codec_init(); + + return NULL; +} +#else +gchar * g_module_check_init() +{ + ms_speex_codec_init(); + + return NULL; +} +#endif + +static MSSpeexDecClass * ms_speex_dec_class=NULL; +//static MSSpeexDecClass * ms_speexnb_dec_class=NULL; + +MSFilter * ms_speex_dec_new() +{ + MSSpeexDec *obj=g_new(MSSpeexDec,1); + + if (ms_speex_dec_class==NULL){ + ms_speex_dec_class=g_new(MSSpeexDecClass,1); + ms_speex_dec_class_init(ms_speex_dec_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_dec_class); + + ms_speex_dec_init(obj); + return MS_FILTER(obj); +} + +void ms_speex_dec_init(MSSpeexDec *obj) +{ + ms_filter_init(MS_FILTER(obj)); + obj->initialized=0; + MS_FILTER(obj)->outfifos=obj->outf; + MS_FILTER(obj)->inqueues=obj->inq; + obj->outf[0]=NULL; + obj->inq[0]=NULL; + obj->frequency=8000; /*default value */ + +} + +void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode) +{ + int pf=1; + + obj->speex_state=speex_decoder_init((SpeexMode*)mode); + speex_bits_init(&obj->bits); + /* enable the perceptual post filter */ + speex_decoder_ctl(obj->speex_state,SPEEX_SET_PF, &pf); + + speex_mode_query((SpeexMode*)mode, SPEEX_MODE_FRAME_SIZE, &obj->frame_size); + + obj->initialized=1; +} + +int ms_speex_dec_set_property(MSSpeexDec *obj, MSFilterProperty prop, int *value) +{ + if (obj->initialized){ + /* we are called when speex is running !! forbid that! */ + ms_warning("ms_speex_dec_set_property: cannot call this function when running!"); + return -1; + } + switch(prop){ + case MS_FILTER_PROPERTY_FREQ: + obj->frequency=value[0]; + break; + default: + break; + } + return 0; +} + +void ms_speex_dec_setup(MSSpeexDec *obj) +{ + const SpeexMode *mode; + g_message("Speex decoder setup: freq=%i",obj->frequency); + if ( obj->frequency< 16000) mode=&speex_nb_mode; + else mode=&speex_wb_mode; + ms_speex_dec_init_core(obj,mode); +} + +void ms_speex_dec_unsetup(MSSpeexDec *obj) +{ + ms_speex_dec_uninit_core(obj); +} + +void ms_speex_dec_class_init(MSSpeexDecClass *klass) +{ + gint frame_size=0; + + ms_filter_class_init(MS_FILTER_CLASS(klass)); + /* use the largest frame size to configure fifos */ + speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size); + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_dec_process; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_dec_setup; + MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_dec_unsetup; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_dec_destroy; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_dec_set_property; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexDecoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info; + MS_FILTER_CLASS(klass)->max_foutputs=1; + MS_FILTER_CLASS(klass)->max_qinputs=1; + MS_FILTER_CLASS(klass)->w_maxgran=frame_size*2; + ms_trace("ms_speex_dec_class_init: w_maxgran is %i.",MS_FILTER_CLASS(klass)->w_maxgran); +} + +void ms_speex_dec_uninit_core(MSSpeexDec *obj) +{ + speex_decoder_destroy(obj->speex_state); + speex_bits_destroy(&obj->bits); + obj->initialized=0; +} + +void ms_speex_dec_uninit(MSSpeexDec *obj) +{ + +} + +void ms_speex_dec_destroy(MSSpeexDec *obj) +{ + ms_speex_dec_uninit(obj); + g_free(obj); +} + +void ms_speex_dec_process(MSSpeexDec *obj) +{ + MSFifo *outf=obj->outf[0]; + MSQueue *inq=obj->inq[0]; + gint16 *output; + gint gran=obj->frame_size*2; + MSMessage *m; + + g_return_if_fail(inq!=NULL); + g_return_if_fail(outf!=NULL); + + m=ms_queue_get(inq); + g_return_if_fail(m!=NULL); + speex_bits_reset(&obj->bits); + ms_fifo_get_write_ptr(outf,gran,(void**)&output); + g_return_if_fail(output!=NULL); + if (m->data!=NULL){ + + speex_bits_read_from(&obj->bits,m->data,m->size); + /* decode */ + speex_decode_int(obj->speex_state,&obj->bits,(short*)output); + }else{ + /* we have a missing packet */ + speex_decode_int(obj->speex_state,NULL,(short*)output); + } + ms_message_destroy(m); + +} diff --git a/linphone/mediastreamer/msspeexdec.h b/linphone/mediastreamer/msspeexdec.h new file mode 100644 index 000000000..de60745b9 --- /dev/null +++ b/linphone/mediastreamer/msspeexdec.h @@ -0,0 +1,69 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSSPEEXDEC_H +#define MSSPEEXDEC_H + +#include "mscodec.h" +#include + +struct _MSSpeexDec +{ + MSFilter parent; + MSQueue *inq[1]; /* speex has an input q because it can be variable bit rate */ + MSFifo *outf[1]; + void *speex_state; + SpeexBits bits; + int frequency; + int frame_size; + int initialized; +}; + +typedef struct _MSSpeexDec MSSpeexDec; + + +struct _MSSpeexDecClass +{ + MSFilterClass parent; +}; + +typedef struct _MSSpeexDecClass MSSpeexDecClass; + + +#define MS_SPEEX_DEC(o) ((MSSpeexDec*)(o)) +#define MS_SPEEX_DEC_CLASS(o) ((MSSpeexDecClass*)(o)) + +/* call this before if don't load the plugin dynamically */ +void ms_speex_codec_init(); + +/* mediastreamer compliant constructor */ +MSFilter * ms_speex_dec_new(); + +void ms_speex_dec_init(MSSpeexDec *obj); +void ms_speex_dec_init_core(MSSpeexDec *obj,const SpeexMode *mode); +void ms_speex_dec_class_init(MSSpeexDecClass *klass); +void ms_speex_dec_uninit(MSSpeexDec *obj); +void ms_speex_dec_uninit_core(MSSpeexDec *obj); + +void ms_speex_dec_process(MSSpeexDec *obj); +void ms_speex_dec_destroy(MSSpeexDec *obj); + +#endif diff --git a/linphone/mediastreamer/msspeexenc.c b/linphone/mediastreamer/msspeexenc.c new file mode 100644 index 000000000..903269ecb --- /dev/null +++ b/linphone/mediastreamer/msspeexenc.c @@ -0,0 +1,187 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + + +#include "msspeexenc.h" +#include "ms.h" +extern MSCodecInfo speex_info; + +static MSSpeexEncClass * ms_speex_enc_class=NULL; + +MSFilter * ms_speex_enc_new() +{ + MSSpeexEnc *obj=g_new(MSSpeexEnc,1); + + if (ms_speex_enc_class==NULL){ + ms_speex_enc_class=g_new(MSSpeexEncClass,1); + ms_speex_enc_class_init(ms_speex_enc_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_speex_enc_class); + ms_speex_enc_init(MS_SPEEX_ENC(obj)); + return MS_FILTER(obj); +} + +void ms_speex_enc_init(MSSpeexEnc *obj) +{ + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->infifos=obj->inf; + MS_FILTER(obj)->outqueues=obj->outq; + obj->inf[0]=NULL; + obj->outq[0]=NULL; + obj->frequency=8000; + obj->bitrate=30000; + obj->initialized=0; +} + +void ms_speex_enc_init_core(MSSpeexEnc *obj,const SpeexMode *mode, gint bitrate) +{ + int proc_type, proc_speed; + gchar *proc_vendor; + int tmp; + int frame_size; + + obj->speex_state=speex_encoder_init((SpeexMode*)mode); + speex_bits_init(&obj->bits); + + if (bitrate>0) { + bitrate++; + speex_encoder_ctl(obj->speex_state, SPEEX_SET_BITRATE, &bitrate); + g_message("Setting speex output bitrate less or equal than %i",bitrate-1); + } + + proc_speed=ms_proc_get_speed(); + proc_vendor=ms_proc_get_param("vendor_id"); + if (proc_speed<0 || proc_vendor==NULL){ + g_warning("Can't guess processor features: setting speex encoder to its lowest complexity."); + tmp=1; + speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp); + }else if ((proc_speed!=-1) && (proc_speed<200)){ + g_warning("A cpu speed less than 200 Mhz is not enough: let's reduce the complexity of the speex codec."); + tmp=1; + speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp); + }else if (proc_vendor!=NULL) { + if (strncmp(proc_vendor,"GenuineIntel",strlen("GenuineIntel"))==0){ + proc_type=ms_proc_get_type(); + if (proc_type==5){ + g_warning("A pentium I is not enough fast for speex codec in normal mode: let's reduce its complexity."); + tmp=1; + speex_encoder_ctl(obj->speex_state,SPEEX_SET_COMPLEXITY,&tmp); + } + } + g_free(proc_vendor); + } + /* guess the used input frame size */ + speex_mode_query((SpeexMode*)mode, SPEEX_MODE_FRAME_SIZE, &frame_size); + MS_FILTER(obj)->r_mingran=frame_size*2; + ms_trace("ms_speex_init: using frame size of %i.",MS_FILTER(obj)->r_mingran); + + obj->initialized=1; +} + +/* must be called before the encoder is running*/ +int ms_speex_enc_set_property(MSSpeexEnc *obj,int property,int *value) +{ + if (obj->initialized){ + /* we are called when speex is running !! forbid that! */ + ms_warning("ms_speex_enc_set_property: cannot call this function when running!"); + return -1; + } + switch(property){ + case MS_FILTER_PROPERTY_FREQ: + obj->frequency=value[0]; + break; + case MS_FILTER_PROPERTY_BITRATE: /* to specify max bitrate */ + obj->bitrate=value[0]; + break; + } + return 0; +} + +void ms_speex_enc_setup(MSSpeexEnc *obj) +{ + const SpeexMode *mode; + g_message("Speex encoder setup: freq=%i",obj->frequency); + if ( obj->frequency< 16000) mode=&speex_nb_mode; + else mode=&speex_wb_mode; + ms_speex_enc_init_core(obj,mode,obj->bitrate); + +} + +void ms_speex_enc_unsetup(MSSpeexEnc *obj) +{ + ms_speex_enc_uninit_core(obj); +} + +void ms_speex_enc_class_init(MSSpeexEncClass *klass) +{ + gint frame_size=0; + + ms_filter_class_init(MS_FILTER_CLASS(klass)); + /* we take the larger (wb) frame size */ + speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size); + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_enc_process; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_enc_destroy; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_enc_setup; + MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_enc_unsetup; + MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_enc_set_property; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexEncoder"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info; + MS_FILTER_CLASS(klass)->max_finputs=1; + MS_FILTER_CLASS(klass)->max_qoutputs=1; + MS_FILTER_CLASS(klass)->r_maxgran=frame_size*2; + ms_trace("ms_speex_enc_class_init: r_maxgran is %i.",MS_FILTER_CLASS(klass)->r_maxgran); +} + +void ms_speex_enc_uninit_core(MSSpeexEnc *obj) +{ + if (obj->initialized){ + speex_encoder_destroy(obj->speex_state); + speex_bits_destroy(&obj->bits); + obj->initialized=0; + } +} + +void ms_speex_enc_destroy(MSSpeexEnc *obj) +{ + ms_speex_enc_uninit_core(obj); + g_free(obj); +} + +void ms_speex_enc_process(MSSpeexEnc *obj) +{ + MSFifo *inf=obj->inf[0]; + MSQueue *outq=obj->outq[0]; + gint16 *input; + gint gran=MS_FILTER(obj)->r_mingran; + MSMessage *m; + + g_return_if_fail(inf!=NULL); + g_return_if_fail(outq!=NULL); + + ms_fifo_get_read_ptr(inf,gran,(void**)&input); + g_return_if_fail(input!=NULL); + /* encode */ + speex_bits_reset(&obj->bits); + speex_encode_int(obj->speex_state,(short*)input,&obj->bits); + m=ms_message_new(speex_bits_nbytes(&obj->bits)); + m->size=speex_bits_write(&obj->bits,m->data,m->size); + ms_queue_put(outq,m); +} diff --git a/linphone/mediastreamer/msspeexenc.h b/linphone/mediastreamer/msspeexenc.h new file mode 100644 index 000000000..e7f145c82 --- /dev/null +++ b/linphone/mediastreamer/msspeexenc.h @@ -0,0 +1,66 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSSPEEXENC_H +#define MSSPEEXENC_H + +#include "mscodec.h" +#include + +struct _MSSpeexEnc +{ + MSFilter parent; + MSFifo *inf[1]; + MSQueue *outq[1]; /* speex has an output q because it can be variable bit rate */ + void *speex_state; + SpeexBits bits; + int frequency; + int bitrate; + int initialized; +}; + +typedef struct _MSSpeexEnc MSSpeexEnc; + + +struct _MSSpeexEncClass +{ + MSFilterClass parent; +}; + +typedef struct _MSSpeexEncClass MSSpeexEncClass; + + +#define MS_SPEEX_ENC(o) ((MSSpeexEnc*)(o)) +#define MS_SPEEX_ENC_CLASS(o) ((MSSpeexEncClass*)(o)) + +/* generic constructor */ +MSFilter * ms_speex_enc_new(); + +void ms_speex_enc_init_core(MSSpeexEnc *obj,const SpeexMode *mode, gint quality); +void ms_speex_enc_uninit_core(MSSpeexEnc *obj); +void ms_speex_enc_init(MSSpeexEnc *obj); +void ms_speex_enc_class_init(MSSpeexEncClass *klass); + + +void ms_speex_enc_process(MSSpeexEnc *obj); +void ms_speex_enc_destroy(MSSpeexEnc *obj); + +#endif diff --git a/linphone/mediastreamer/mssync.c b/linphone/mediastreamer/mssync.c new file mode 100644 index 000000000..c0d078138 --- /dev/null +++ b/linphone/mediastreamer/mssync.c @@ -0,0 +1,194 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mssync.h" +#include + +/* TODO: + -define an uninit function that free the mutex +*/ + +/** + * function_name:ms_sync_get_bytes_per_tick + * @sync: A #MSSync object. + * + * Returns the number of bytes per tick. This is a usefull information for sources, so + * that they can know how much data they must deliver each time they are called. + * + */ + +/* private */ +void ms_sync_init(MSSync *sync) +{ + sync->klass=NULL; + sync->lock=g_mutex_new(); + sync->thread_cond=g_cond_new(); + sync->stop_cond=g_cond_new(); + sync->attached_filters=NULL; + sync->execution_list=NULL; + sync->filters=0; + sync->run=0; + sync->flags=0; + sync->samples_per_tick=0; + sync->ticks=0; + sync->time=0; + sync->thread=NULL; +} + +void ms_sync_class_init(MSSyncClass *klass) +{ + klass->max_filters=0; + klass->synchronize=NULL; + klass->attach=ms_sync_attach_generic; + klass->detach=ms_sync_detach_generic; + klass->destroy=NULL; +} + +/* public*/ + + +/** + * ms_sync_attach: + * @sync: A #MSSync object. + * @f: A #MSFilter object. + * + * Attach a chain of filters to a synchronisation source @sync. Filter @f must be the first filter of the processing chain. + * In order to be run, each chain of filter must be attached to a synchronisation source, that will be responsible for scheduling + * the processing. Multiple chains can be attached to a single synchronisation. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_sync_attach(MSSync *sync,MSFilter *f) +{ + gint err; + ms_sync_lock(sync); + err=sync->klass->attach(sync,f); + ms_sync_update(sync); + ms_sync_unlock(sync); + return(err); +} + +int ms_sync_attach_generic(MSSync *sync,MSFilter *f) +{ + int i; + //printf("attr: %i\n",f->klass->attributes); + g_return_val_if_fail(f->klass->attributes & FILTER_IS_SOURCE,-EINVAL); + g_return_val_if_fail(sync->attached_filters!=NULL,-EFAULT); + + + /* find a free place to attach*/ + for (i=0;iklass->max_filters;i++) + { + if (sync->attached_filters[i]==NULL) + { + sync->attached_filters[i]=f; + sync->filters++; + ms_trace("Filter succesfully attached to sync."); + return 0; + } + } + g_warning("No more link on sync !"); + return(-EMLINK); +} + +/** + * ms_sync_detach: + * @sync: A #MSSync object. + * @f: A #MSFilter object. + * + * Dettach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain. + * The processing chain will no more be executed. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_sync_detach(MSSync *sync,MSFilter *f) +{ + gint err; + ms_sync_lock(sync); + err=sync->klass->detach(sync,f); + ms_sync_update(sync); + ms_sync_unlock(sync); + return(err); +} + +int ms_sync_detach_generic(MSSync *sync,MSFilter *f) +{ + int i; + g_return_val_if_fail(f->klass->attributes & FILTER_IS_SOURCE,-EINVAL); + g_return_val_if_fail(sync->attached_filters!=NULL,-EFAULT); + for (i=0;ifilters;i++) + { + if (sync->attached_filters[i]==f) + { + sync->attached_filters[i]=NULL; + sync->filters--; + return 0; + } + } + return(-EMLINK); +} + +void ms_sync_set_samples_per_tick(MSSync *sync,gint size) +{ + if (sync->samples_per_tick==0) + { + sync->samples_per_tick=size; + g_cond_signal(sync->thread_cond); + } + else sync->samples_per_tick=size; +} + +/* call the setup func of each filter attached to the graph */ +void ms_sync_setup(MSSync *sync) +{ + GList *elem=sync->execution_list; + MSFilter *f; + while(elem!=NULL){ + f=(MSFilter*)elem->data; + if (f->klass->setup!=NULL){ + f->klass->setup(f,sync); + } + elem=g_list_next(elem); + } +} + +/* call the unsetup func of each filter attached to the graph */ +void ms_sync_unsetup(MSSync *sync) +{ + GList *elem=sync->execution_list; + MSFilter *f; + while(elem!=NULL){ + f=(MSFilter*)elem->data; + if (f->klass->unsetup!=NULL){ + f->klass->unsetup(f,sync); + } + elem=g_list_next(elem); + } +} + + +int ms_sync_uninit(MSSync *sync) +{ + g_mutex_free(sync->lock); + g_cond_free(sync->thread_cond); + g_cond_free(sync->stop_cond); + return 0; +} + diff --git a/linphone/mediastreamer/mssync.h b/linphone/mediastreamer/mssync.h new file mode 100644 index 000000000..012c068f7 --- /dev/null +++ b/linphone/mediastreamer/mssync.h @@ -0,0 +1,136 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MS_SYNC_H +#define MS_SYNC_H + + +#include "msfilter.h" + +struct _MSSync +{ + struct _MSSyncClass *klass; + GMutex *lock; + MSFilter **attached_filters; /* pointer to a table of pointer of filters*/ + GList *execution_list; /* the list of filters to be executed. This is filled with compilation */ + gint filters; /*number of filters attached to the sync */ + gint run; /* flag to indicate whether the sync must be run or not */ + GThread * thread; /* the thread ressource if this sync is run by a thread*/ + GCond *thread_cond; + GCond *stop_cond; + guint32 flags; + gint interval; /* in miliseconds*/ +#define MS_SYNC_NEED_UPDATE (0x0001) /* a modification has occured in the processing chains + attached to this sync; so the execution list has to be updated */ + guint samples_per_tick; /* number of bytes produced by sources of the processing chains*/ + guint32 ticks; + guint32 time; /* a time since the start of the sync expressed in milisec*/ +}; + +typedef struct _MSSync MSSync; + +typedef void (*MSSyncDestroyFunc)(MSSync*); +typedef void (*MSSyncSyncFunc)(MSSync*); +typedef int (*MSSyncAttachFunc)(MSSync*,MSFilter*); +typedef int (*MSSyncDetachFunc)(MSSync*,MSFilter*); + +typedef struct _MSSyncClass +{ + gint max_filters; /* the maximum number of filters that can be attached to this sync*/ + MSSyncSyncFunc synchronize; + MSSyncDestroyFunc destroy; + MSSyncAttachFunc attach; + MSSyncDetachFunc detach; +} MSSyncClass; + +/* private */ +void ms_sync_init(MSSync *sync); +void ms_sync_class_init(MSSyncClass *klass); + +int ms_sync_attach_generic(MSSync *sync,MSFilter *f); +int ms_sync_detach_generic(MSSync *sync,MSFilter *f); + +/* public*/ + +#define MS_SYNC(sync) ((MSSync*)(sync)) +#define MS_SYNC_CLASS(klass) ((MSSyncClass*)(klass)) + +#define ms_sync_synchronize(_sync) \ +do \ +{ \ + MSSync *__sync=_sync; \ + __sync->ticks++; \ + ((__sync)->klass->synchronize((__sync))); \ +}while(0) + +void ms_sync_setup(MSSync *sync); + +void ms_sync_unsetup(MSSync *sync); + +#define ms_sync_update(sync) (sync)->flags|=MS_SYNC_NEED_UPDATE + +#define ms_sync_get_samples_per_tick(sync) ((sync)->samples_per_tick) + +void ms_sync_set_samples_per_tick(MSSync *sync,gint size); + +#define ms_sync_get_tick_count(sync) ((sync)->ticks) + +#define ms_sync_suspend(sync) g_cond_wait((sync)->thread_cond,(sync)->lock) + +#define ms_sync_lock(sync) g_mutex_lock((sync)->lock) + +#define ms_sync_unlock(sync) g_mutex_unlock((sync)->lock) + +#define ms_sync_trylock(sync) g_mutex_trylock((sync)->lock) + +/** + * function_name:ms_sync_attach + * @sync: A #MSSync object. + * @f: A #MSFilter object. + * + * Attach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_sync_attach(MSSync *sync,MSFilter *f); + +/** + * ms_sync_detach: + * @sync: A #MSSync object. + * @f: A #MSFilter object. + * + * Dettach a chain of filters to a synchronisation source. Filter @f must be the first filter of the processing chain. + * The processing chain will no more be executed. + * + * Returns: 0 if successfull, a negative value reprensenting the errno.h error. + */ +int ms_sync_detach(MSSync *sync,MSFilter *f); + +int ms_sync_uninit(MSSync *sync); + +#define ms_sync_start(sync) ms_start((sync)) +#define ms_sync_stop(sync) ms_stop((sync)) + + +/*destroy*/ +#define ms_sync_destroy(sync) (sync)->klass->destroy((sync)) + + +#endif diff --git a/linphone/mediastreamer/mstcpclient.c b/linphone/mediastreamer/mstcpclient.c new file mode 100644 index 000000000..abeb5f8ad --- /dev/null +++ b/linphone/mediastreamer/mstcpclient.c @@ -0,0 +1,137 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mstcpclient.h" +#include +#include +#include +#include + + +void ms_tcp_client_process(MSTcpClient *r); +void ms_tcp_client_init(MSTcpClient *r); +void ms_tcp_client_destroy(MSTcpClient *r); +void ms_tcp_client_class_init(MSTcpClientClass *klass); + +static MSTcpClientClass *ms_tcp_client_class=NULL; + +MSFilter * ms_tcp_client_new(void) +{ + MSTcpClient *r; + + r=g_new(MSTcpClient,1); + + if (ms_tcp_client_class==NULL) + { + ms_tcp_client_class=g_new(MSTcpClientClass,1); + ms_tcp_client_class_init(ms_tcp_client_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_tcp_client_class); + ms_tcp_client_init(r); + return(MS_FILTER(r)); +} + + +void ms_tcp_client_init(MSTcpClient *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->outqueues=r->q_outputs; + memset(r->q_outputs,0,sizeof(MSQueue*)); + r->sock=-1; + r->msg=NULL; +} + + +int ms_tcp_client_connect(MSTcpClient *obj, const char *addr, int port){ + struct addrinfo hints; + struct addrinfo *res; + char service[40]; + int err; + sprintf(service,"%i",port); + memset(&hints,0,sizeof(hints)); + hints.ai_family=PF_UNSPEC; + hints.ai_socktype=SOCK_STREAM; + err=getaddrinfo(addr,service,&hints,&res); + if (err!=0){ + g_warning("getaddrinfo error: %s",gai_strerror(err)); + return -1; + } + obj->sock=socket(res->ai_family,res->ai_socktype,0); + if (obj->sock<0){ + g_warning("fail to create socket: %s",strerror(errno)); + return -1; + } + err=connect(obj->sock,res->ai_addr,res->ai_addrlen); + if (err<0){ + g_warning("Could not connect to %s:%i : %s",addr,port,strerror(errno)); + close(obj->sock); + obj->sock=-1; + return -1; + } + return 0; +} + +void ms_tcp_client_class_init(MSTcpClientClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"TcpClient"); + MS_FILTER_CLASS(klass)->max_qoutputs=1; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_tcp_client_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_tcp_client_process; + ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE); +} + + + +void ms_tcp_client_process(MSTcpClient *r) +{ + static const int rcvsz=5000; + int err; + if (r->sock>0){ + if (r->msg==NULL){ + r->msg=ms_message_new(rcvsz); + memset(r->msg->data,0,rcvsz); + } + err=recv(r->sock,r->msg->data,rcvsz,MSG_DONTWAIT); + if (err<0 && errno!=EWOULDBLOCK && errno!=EAGAIN){ + g_warning("recv error: %s",strerror(errno)); + }else if (err>0){ + r->msg->size=err; + ms_queue_put(r->q_outputs[0],r->msg); + printf("output new message %p,%i\n",r->msg->data,r->msg->size); + r->msg=NULL; + + } + } +} + +void ms_tcp_client_uninit( MSTcpClient *obj){ + if (obj->sock>0) close(obj->sock); + if (obj->msg!=NULL) ms_message_destroy(obj->msg); +} + +void ms_tcp_client_destroy( MSTcpClient *obj) +{ + ms_tcp_client_uninit(obj); + g_free(obj); +} + + + diff --git a/linphone/mediastreamer/mstcpclient.h b/linphone/mediastreamer/mstcpclient.h new file mode 100644 index 000000000..639593cd6 --- /dev/null +++ b/linphone/mediastreamer/mstcpclient.h @@ -0,0 +1,50 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef mstcpclient_h +#define mstcpclient_h + +#include "msfilter.h" + +/* According to earlier standards */ +#include +#include +#include + + +struct _MSTcpClient{ + MSFilter parent; + MSQueue *q_outputs[1]; + int sock; + MSMessage *msg; +}; + +typedef struct _MSTcpClient MSTcpClient; + +struct _MSTcpClientClass{ + MSFilterClass parent; +}; + +typedef struct _MSTcpClientClass MSTcpClientClass; + +MSFilter *ms_tcp_client_new(); +int ms_tcp_client_connect(MSTcpClient *obj, const char *addr, int port); +#define MS_TCP_CLIENT(o) ((MSTcpClient*)(o)) +#endif diff --git a/linphone/mediastreamer/mstcpserv.c b/linphone/mediastreamer/mstcpserv.c new file mode 100644 index 000000000..9bbd61db7 --- /dev/null +++ b/linphone/mediastreamer/mstcpserv.c @@ -0,0 +1,174 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mstcpserv.h" +#include +#include +#include +#include + +#include +#include + + +void ms_tcp_serv_process(MSTcpServ *r); +void ms_tcp_serv_init(MSTcpServ *r, int port); +void ms_tcp_serv_destroy(MSTcpServ *r); +void ms_tcp_serv_class_init(MSTcpServClass *klass); + +static MSTcpServClass *ms_tcp_serv_class=NULL; + +MSFilter * ms_tcp_serv_new(void) +{ + MSTcpServ *r; + + r=g_new(MSTcpServ,1); + + if (ms_tcp_serv_class==NULL) + { + ms_tcp_serv_class=g_new(MSTcpServClass,1); + ms_tcp_serv_class_init(ms_tcp_serv_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_tcp_serv_class); + ms_tcp_serv_init(r,5800); + return(MS_FILTER(r)); +} + + +void ms_tcp_serv_init(MSTcpServ *r, int port) +{ + struct addrinfo *res; + struct addrinfo hints; + char service[20]; + int err; + int val=1; + + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->inqueues=r->q_inputs; + memset(r->q_inputs,0,sizeof(MSQueue*)); + memset(&r->set,0,sizeof(fd_set)); + r->maxfd=0; + r->asock=socket(PF_INET,SOCK_STREAM,0); + if (r->asock<0){ + g_warning("Could not create socket: %s",strerror(errno)); + return; + } + err=fcntl(r->asock,F_SETFL,O_NONBLOCK); + if (err<0){ + g_warning("Could not non blocking flag on socket: %s",strerror(errno)); + return; + } + err=setsockopt(r->asock,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(int)); + if (err<0){ + g_warning("Could not set socket reusable: %s",strerror(errno)); + return; + } + sprintf(service,"%i",port); + memset(&hints,0,sizeof(hints)); + hints.ai_family=PF_UNSPEC; + hints.ai_socktype=SOCK_STREAM; + if (err=getaddrinfo("0.0.0.0",service,&hints,&res)!=0){ + g_warning("Could not getaddrinfo: %s",gai_strerror(err)); + return; + } + err=bind(r->asock,(struct sockaddr *)res->ai_addr,res->ai_addrlen); + freeaddrinfo(res); + if (err<0){ + g_warning("Could not bind socket: %s",strerror(errno)); + return; + } + err=listen(r->asock,10); + if (err<0){ + g_warning("Could not listen: %s",strerror(errno)); + return; + } +} + +void ms_tcp_serv_class_init(MSTcpServClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"TcpServ"); + MS_FILTER_CLASS(klass)->max_qinputs=1; + MS_FILTER_CLASS(klass)->max_finputs=0; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_tcp_serv_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_tcp_serv_process; +} + +static void accept_new_clients(MSTcpServ *r){ + int sock; + struct sockaddr_storage ss; + socklen_t len=sizeof(ss); + int val=1; + int err; + + sock=accept(r->asock,(struct sockaddr*)&ss,&len); + if (sock<0){ + if (errno!=EWOULDBLOCK && errno!=EAGAIN) g_warning("Could not accept connection: %s",strerror(errno)); + return; + } + FD_SET(sock,&r->set); + err=setsockopt(sock,SOL_TCP,TCP_NODELAY,&val,sizeof(int)); + if (err<0){ + g_warning("Could not set tcp nodelay option: %s",strerror(errno)); + } + if (r->maxfdmaxfd=sock; + printf("New client accepted.\n"); +} + + +void ms_tcp_serv_process(MSTcpServ *r) +{ + MSMessage *msg; + int err; + g_return_if_fail(r->asock>0); + /*printf("ms_tcp_serv_process\n");*/ + /* first accept incoming connections */ + accept_new_clients(r); + /* send data to all clients */ + msg=ms_queue_get(r->q_inputs[0]); + if (msg!=NULL){ + int i; + for (i=0;imaxfd+1;i++){ + if (FD_ISSET(i,&r->set)){ + err=send(i,msg->data,msg->size,0); + if (err<0){ + FD_CLR(i,&r->set); + close(i); + g_message("Client disconnected."); + } + } + } + ms_message_destroy(msg); + } + +} + +void ms_tcp_serv_uninit( MSTcpServ *obj){ + if (obj->asock>0) close(obj->asock); +} + +void ms_tcp_serv_destroy( MSTcpServ *obj) +{ + ms_tcp_serv_uninit(obj); + g_free(obj); +} + + + diff --git a/linphone/mediastreamer/mstcpserv.h b/linphone/mediastreamer/mstcpserv.h new file mode 100644 index 000000000..1ed6eb3b8 --- /dev/null +++ b/linphone/mediastreamer/mstcpserv.h @@ -0,0 +1,33 @@ +#ifndef mstcpserver_h +#define mstcpserver_h + +#include "msfilter.h" + +/* According to earlier standards */ +#include +#include +#include + + +struct _MSTcpServ{ + MSFilter parent; + MSQueue *q_inputs[1]; + fd_set set; + int maxfd; + int asock; +}; + +typedef struct _MSTcpServ MSTcpServ; + +struct _MSTcpServClass{ + MSFilterClass parent; +}; + +typedef struct _MSTcpServClass MSTcpServClass; + +MSFilter *ms_tcp_serv_new(); +#define MS_TCP_SERV(o) ((MSTcpServ*)(o)) + + +#endif + diff --git a/linphone/mediastreamer/mstimer.c b/linphone/mediastreamer/mstimer.c new file mode 100644 index 000000000..25200a913 --- /dev/null +++ b/linphone/mediastreamer/mstimer.c @@ -0,0 +1,114 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mstimer.h" +#include +#include +#include +#include + +static MSTimerClass *ms_timer_class=NULL; + + +void ms_timer_init(MSTimer *sync) +{ + ms_sync_init(MS_SYNC(sync)); + MS_SYNC(sync)->attached_filters=sync->filters; + memset(sync->filters,0,MSTIMER_MAX_FILTERS*sizeof(MSFilter*)); + MS_SYNC(sync)->samples_per_tick=80; + ms_timer_set_interval(sync,10); + sync->state=MS_TIMER_STOPPED; +} + +void ms_timer_class_init(MSTimerClass *klass) +{ + ms_sync_class_init(MS_SYNC_CLASS(klass)); + MS_SYNC_CLASS(klass)->max_filters=MSTIMER_MAX_FILTERS; + MS_SYNC_CLASS(klass)->synchronize=(MSSyncSyncFunc)ms_timer_synchronize; + MS_SYNC_CLASS(klass)->destroy=(MSSyncDestroyFunc)ms_timer_destroy; + /* no need to overload these function*/ + MS_SYNC_CLASS(klass)->attach=ms_sync_attach_generic; + MS_SYNC_CLASS(klass)->detach=ms_sync_detach_generic; +} + +void ms_timer_destroy(MSTimer *timer) +{ + g_free(timer); +} + + +void ms_timer_synchronize(MSTimer *timer) +{ + //printf("ticks=%i \n",MS_SYNC(timer)->ticks); + if (timer->state==MS_TIMER_STOPPED){ + timer->state=MS_TIMER_RUNNING; + gettimeofday(&timer->orig,NULL); + timer->sync.time=0; + } + else { + gint32 diff,time; + struct timeval tv,cur; + + timer->sync.time+=timer->milisec; + + gettimeofday(&cur,NULL); + time=((cur.tv_usec-timer->orig.tv_usec)/1000 ) + ((cur.tv_sec-timer->orig.tv_sec)*1000 ); + while((diff = timer->sync.time-time) > 0) + { + tv.tv_sec = timer->milisec/1000; + tv.tv_usec = (timer->milisec%1000)*1000; + select(0,NULL,NULL,NULL,&tv); + gettimeofday(&cur,NULL); + time=((cur.tv_usec-timer->orig.tv_usec)/1000 ) + ((cur.tv_sec-timer->orig.tv_sec)*1000 ); + } + if (diff<-50) g_warning("Must catchup %i miliseconds.",-diff); + } + + return; +} + + +MSSync *ms_timer_new() +{ + MSTimer *timer; + + timer=g_malloc(sizeof(MSTimer)); + ms_timer_init(timer); + if (ms_timer_class==NULL) + { + ms_timer_class=g_new(MSTimerClass,1); + ms_timer_class_init(ms_timer_class); + } + MS_SYNC(timer)->klass=MS_SYNC_CLASS(ms_timer_class); + return(MS_SYNC(timer)); +} + +void ms_timer_set_interval(MSTimer *timer, int milisec) +{ + + MS_SYNC(timer)->ticks=0; + MS_SYNC(timer)->interval=milisec; + timer->interval.tv_sec=milisec/1000; + timer->interval.tv_usec=(milisec % 1000)*1000; + timer->milisec=milisec; + + +} diff --git a/linphone/mediastreamer/mstimer.h b/linphone/mediastreamer/mstimer.h new file mode 100644 index 000000000..5c7e8edee --- /dev/null +++ b/linphone/mediastreamer/mstimer.h @@ -0,0 +1,68 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSTIMER_H +#define MSTIMER_H + +#include "mssync.h" +#include + +#define MSTIMER_MAX_FILTERS 10 + +/* MSTimer derivates from MSSync base class*/ + +typedef struct _MSTimer +{ + /* the MSSync must be the first field of the object in order to the object mechanism to work*/ + MSSync sync; + MSFilter *filters[MSTIMER_MAX_FILTERS]; + gint milisec; /* the interval */ + struct timeval interval; + struct timeval orig; + gint state; +} MSTimer; + + +typedef struct _MSTimerClass +{ + /* the MSSyncClass must be the first field of the class in order to the class mechanism to work*/ + MSSyncClass parent_class; +} MSTimerClass; + + +/*private*/ +#define MS_TIMER_RUNNING 1 +#define MS_TIMER_STOPPED 0 +void ms_timer_init(MSTimer *sync); +void ms_timer_class_init(MSTimerClass *sync); + +void ms_timer_destroy(MSTimer *timer); +void ms_timer_synchronize(MSTimer *timer); + +/*public*/ +void ms_timer_set_interval(MSTimer *timer, gint milisec); + +/* casts a MSSync object into a MSTimer */ +#define MS_TIMER(sync) ((MSTimer*)(sync)) +/* casts a MSSync class into a MSTimer class */ +#define MS_TIMER_CLASS(klass) ((MSTimerClass*)(klass)) + +MSSync *ms_timer_new(); + +#endif diff --git a/linphone/mediastreamer/mstruespeechdecoder.c b/linphone/mediastreamer/mstruespeechdecoder.c new file mode 100644 index 000000000..aba6e0645 --- /dev/null +++ b/linphone/mediastreamer/mstruespeechdecoder.c @@ -0,0 +1,152 @@ +/* + Copyright 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mstruespeechdecoder.h" +#include "mscodec.h" + +MSCodecInfo TrueSpeechinfo = +{ + { + "TrueSpeech codec", + 0, + MS_FILTER_AUDIO_CODEC, + ms_truespeechencoder_new, + "This is a proprietary codec by the DSP Group that is used in some " + "Windows applications. It has a good quality and bitrate. " + "It requires the Windows DLLs tssoft32.acm and " + "tsd32.dll to be available." + }, + ms_truespeechencoder_new, + ms_truespeechdecoder_new, + 480, + 32, + 8536, + 8000, + 116, + "TSP0", + 1, + 1, +}; + + +static MSTrueSpeechDecoderClass *ms_truespeechdecoder_class = 0; + +/* FOR INTERNAL USE*/ +void ms_truespeechdecoder_init(MSTrueSpeechDecoder *r); +void ms_truespeechdecoder_class_init(MSTrueSpeechDecoderClass *klass); +void ms_truespeechdecoder_destroy(MSTrueSpeechDecoder *obj); +void ms_truespeechdecoder_process(MSTrueSpeechDecoder *r); + +MSFilter * ms_truespeechdecoder_new(void) +{ + MSTrueSpeechDecoder *r = 0; + + if (!ms_truespeechdecoder_class) + { + ms_truespeechdecoder_class = g_new(MSTrueSpeechDecoderClass, 1); + ms_truespeechdecoder_class_init(ms_truespeechdecoder_class); + } + + r = g_new(MSTrueSpeechDecoder, 1); + MS_FILTER(r)->klass = MS_FILTER_CLASS(ms_truespeechdecoder_class); + ms_truespeechdecoder_init(r); + return MS_FILTER(r); +} + + +/* FOR INTERNAL USE*/ +void ms_truespeechdecoder_init(MSTrueSpeechDecoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos = r->f_inputs; + MS_FILTER(r)->outfifos = r->f_outputs; + + WAVEFORMATEX* wf = ms_truespeechencoder_wf_create(); + + r->codec = win32codec_create(wf, 0); + free(wf); + + MS_FILTER(r)->r_mingran = r->codec->min_insize; + + MS_FILTER_CLASS(ms_truespeechdecoder_class)->r_maxgran = + r->codec->min_insize; + MS_FILTER_CLASS(ms_truespeechdecoder_class)->w_maxgran = + r->codec->min_outsize; + + memset(r->f_inputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT); + memset(r->f_outputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT); +} + +void ms_truespeechdecoder_class_init(MSTrueSpeechDecoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass), "TrueSpeechDecoder"); + MS_FILTER_CLASS(klass)->max_finputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT; + MS_FILTER_CLASS(klass)->max_foutputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT; + MS_FILTER_CLASS(klass)->r_maxgran = 0; /* filled in by first instance */ + MS_FILTER_CLASS(klass)->w_maxgran = 0; /* filled in by first instance */ + MS_FILTER_CLASS(klass)->destroy = (MSFilterDestroyFunc)ms_truespeechdecoder_destroy; + MS_FILTER_CLASS(klass)->process = (MSFilterProcessFunc)ms_truespeechdecoder_process; + MS_FILTER_CLASS(klass)->info = MS_FILTER_INFO(&TrueSpeechinfo); + klass->driver = win32codec_create_driver(TRUESPEECH_DLL, + TRUESPEECH_FORMAT_TAG, 0); +} + +void ms_truespeechdecoder_process(MSTrueSpeechDecoder *r) +{ + MSFifo *fi,*fo; + gint err1; + void *s,*d; + + /* process output fifos, but there is only one for this class of filter*/ + + fi = r->f_inputs[0]; + fo = r->f_outputs[0]; + if (fi) + { + err1 = ms_fifo_get_read_ptr(fi, r->codec->min_insize, &s); + if (err1 > 0) + { + err1 = ms_fifo_get_write_ptr(fo, r->codec->min_outsize, &d); + if (d) + { + signed long n; + n = win32codec_convert(r->codec, + s, r->codec->min_insize, + d, r->codec->min_outsize); + } + } + + } +} + + + +void ms_truespeechdecoder_uninit(MSTrueSpeechDecoder *obj) +{ + win32codec_destroy(obj->codec); +} + +void ms_truespeechdecoder_destroy(MSTrueSpeechDecoder *obj) +{ + ms_truespeechdecoder_uninit(obj); + g_free(obj); +} + + diff --git a/linphone/mediastreamer/mstruespeechdecoder.h b/linphone/mediastreamer/mstruespeechdecoder.h new file mode 100644 index 000000000..624774365 --- /dev/null +++ b/linphone/mediastreamer/mstruespeechdecoder.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSTRUESPEECHDECODER_H +#define MSTRUESPEECHDECODER_H + +#include "msfilter.h" +#include "mstruespeechencoder.h" + + + +typedef struct _MSTrueSpeechDecoder +{ + /* the MSTrueSpeechDecoder derives from MSFilter, so the MSFilter + object MUST be the first of the MSTrueSpeechDecoder object + in order for the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT]; + MSFifo *f_outputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT]; + Win32Codec* codec; +} MSTrueSpeechDecoder; + +typedef struct _MSTrueSpeechDecoderClass +{ + /* the MSTrueSpeechDecoder derives from MSFilter, + so the MSFilter class MUST be the first of the MSTrueSpechDecoder + class + in order for the class mechanism to work*/ + MSFilterClass parent_class; + Win32CodecDriver* driver; +} MSTrueSpeechDecoderClass; + +/* PUBLIC */ +#define MS_TRUESPEECHDECODER(filter) ((MSTrueSpechMDecoder*)(filter)) +#define MS_TRUESPEECHDECODER_CLASS(klass) ((MSTrueSpeechDecoderClass*)(klass)) +MSFilter * ms_truespeechdecoder_new(void); + + +#endif diff --git a/linphone/mediastreamer/mstruespeechencoder.c b/linphone/mediastreamer/mstruespeechencoder.c new file mode 100644 index 000000000..0b00c0c35 --- /dev/null +++ b/linphone/mediastreamer/mstruespeechencoder.c @@ -0,0 +1,161 @@ +/* + Copyright 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mstruespeechencoder.h" +#include "mscodec.h" + +#define TRUESPEECH_CBSIZE 32 + +extern MSCodecInfo TrueSpeechinfo; + +static MSTrueSpeechEncoderClass *ms_truespeechencoder_class = 0; + +/* FOR INTERNAL USE*/ +void ms_truespeechencoder_init(MSTrueSpeechEncoder *r); +void ms_truespeechencoder_class_init(MSTrueSpeechEncoderClass *klass); +void ms_truespeechencoder_destroy(MSTrueSpeechEncoder *obj); +void ms_truespeechencoder_process(MSTrueSpeechEncoder *r); + +MSFilter * ms_truespeechencoder_new(void) +{ + MSTrueSpeechEncoder *r = 0; + + if (!ms_truespeechencoder_class) + { + ms_truespeechencoder_class = g_new(MSTrueSpeechEncoderClass, 1); + ms_truespeechencoder_class_init(ms_truespeechencoder_class); + } + + r = g_new(MSTrueSpeechEncoder, 1); + MS_FILTER(r)->klass = MS_FILTER_CLASS(ms_truespeechencoder_class); + ms_truespeechencoder_init(r); + return MS_FILTER(r); +} + + +/* FOR INTERNAL USE*/ +void ms_truespeechencoder_init(MSTrueSpeechEncoder *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos = r->f_inputs; + MS_FILTER(r)->outfifos = r->f_outputs; + + WAVEFORMATEX* wf = ms_truespeechencoder_wf_create(); + + r->codec = win32codec_create(wf, 1); + free(wf); + + MS_FILTER(r)->r_mingran = r->codec->min_insize; + + MS_FILTER_CLASS(ms_truespeechencoder_class)->r_maxgran = + r->codec->min_insize; + MS_FILTER_CLASS(ms_truespeechencoder_class)->w_maxgran = + r->codec->min_outsize; + + memset(r->f_inputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT); + memset(r->f_outputs, 0, sizeof(MSFifo*) * MS_TRUESPEECH_CODEC_MAX_IN_OUT); +} + +void ms_truespeechencoder_class_init(MSTrueSpeechEncoderClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass), "TrueSpeechEncoder"); + MS_FILTER_CLASS(klass)->max_finputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT; + MS_FILTER_CLASS(klass)->max_foutputs = MS_TRUESPEECH_CODEC_MAX_IN_OUT; + MS_FILTER_CLASS(klass)->r_maxgran = 0; /* filled in by first instance */ + MS_FILTER_CLASS(klass)->w_maxgran = 0; /* filled in by first instance */ + MS_FILTER_CLASS(klass)->destroy = (MSFilterDestroyFunc)ms_truespeechencoder_destroy; + MS_FILTER_CLASS(klass)->process = (MSFilterProcessFunc)ms_truespeechencoder_process; + MS_FILTER_CLASS(klass)->info = MS_FILTER_INFO(&TrueSpeechinfo); + klass->driver = win32codec_create_driver(TRUESPEECH_DLL, + TRUESPEECH_FORMAT_TAG, 1); +} + +void ms_truespeechencoder_process(MSTrueSpeechEncoder *r) +{ + MSFifo *fi,*fo; + int err1; + void *s,*d; + + /* process output fifos, but there is only one for this class of filter*/ + + fi = r->f_inputs[0]; + fo = r->f_outputs[0]; + if (fi) + { + err1 = ms_fifo_get_read_ptr(fi, r->codec->min_insize, &s); + if (err1 > 0) + { + err1 = ms_fifo_get_write_ptr(fo, r->codec->min_outsize, &d); + if (d) + { + signed long n; + + n = win32codec_convert(r->codec, + s, r->codec->min_insize, + d, r->codec->min_outsize); + } + } + + } +} + + + +void ms_truespeechencoder_uninit(MSTrueSpeechEncoder *obj) +{ + win32codec_destroy(obj->codec); +} + +void ms_truespeechencoder_destroy(MSTrueSpeechEncoder *obj) +{ + ms_truespeechencoder_uninit(obj); + g_free(obj); +} + + +WAVEFORMATEX* ms_truespeechencoder_wf_create() +{ + WAVEFORMATEX* ts_wf = 0; + long* iptr = 0; + + ts_wf = malloc(sizeof(WAVEFORMATEX) + TRUESPEECH_CBSIZE); + if (!ts_wf) + { + return 0; + } + + memset(ts_wf, 0, sizeof(*ts_wf) + TRUESPEECH_CBSIZE); + + ts_wf->wFormatTag = TRUESPEECH_FORMAT_TAG; + ts_wf->nChannels = 1; + ts_wf->nSamplesPerSec = 8000; + ts_wf->wBitsPerSample = 1; + ts_wf->nBlockAlign = 32; + ts_wf->nAvgBytesPerSec = 1067; + ts_wf->cbSize = TRUESPEECH_CBSIZE; + + /* write extra data needed by TrueSpeech codec found + from examining a TrueSpeech .wav file header + */ + iptr = (long*)(ts_wf + 1); + *iptr = 0x00f00001; + + return ts_wf; +} diff --git a/linphone/mediastreamer/mstruespeechencoder.h b/linphone/mediastreamer/mstruespeechencoder.h new file mode 100644 index 000000000..04e40bb8b --- /dev/null +++ b/linphone/mediastreamer/mstruespeechencoder.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSTRUESPEECHENCODER_H +#define MSTRUESPEECHENCODER_H + +#include "msfilter.h" +#include + + +#define MS_TRUESPEECH_CODEC_MAX_IN_OUT 1 /* max inputs/outputs per filter*/ + +#define TRUESPEECH_FORMAT_TAG 0x22 +#define TRUESPEECH_DLL "tssoft32.acm" + +typedef struct _MSTrueSpeechEncoder +{ + /* the MSTrueSpeechEncoder derives from MSFilter, so the MSFilter + object MUST be the first of the MSTrueSpeechEncoder object + in order for the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT]; + MSFifo *f_outputs[MS_TRUESPEECH_CODEC_MAX_IN_OUT]; + Win32Codec* codec; +} MSTrueSpeechEncoder; + +typedef struct _MSTrueSpeechEncoderClass +{ + /* the MSTrueSpeechEncoder derives from MSFilter, + so the MSFilter class MUST be the first of the MSTrueSpechEncoder + class + in order for the class mechanism to work*/ + MSFilterClass parent_class; + Win32CodecDriver* driver; +} MSTrueSpeechEncoderClass; + +/* PUBLIC */ +#define MS_TRUESPEECHENCODER(filter) ((MSTrueSpechMEncoder*)(filter)) +#define MS_TRUESPEECHENCODER_CLASS(klass) ((MSTrueSpeechEncoderClass*)(klass)) +MSFilter * ms_truespeechencoder_new(void); + +/* for internal use only */ +WAVEFORMATEX* ms_truespeechencoder_wf_create(); + + +#endif diff --git a/linphone/mediastreamer/msutils.h b/linphone/mediastreamer/msutils.h new file mode 100644 index 000000000..012b87d81 --- /dev/null +++ b/linphone/mediastreamer/msutils.h @@ -0,0 +1,61 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef MSUTILS_H +#define MSUTILS_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_GLIB +#include +#else +#include +#endif +#include + +#ifndef ENODATA +/* this is for freeBSD .*/ +#define ENODATA EWOULDBLOCK +#endif + +#ifdef MS_DEBUG + +#define ms_trace g_message + +#else + +#define ms_trace(...) +#endif + +#define ms_warning g_warning +#define ms_error g_error + +#define VIDEO_SIZE_CIF_W 352 +#define VIDEO_SIZE_CIF_H 288 +#define VIDEO_SIZE_QCIF_W 176 +#define VIDEO_SIZE_QCIF_H 144 +#define VIDEO_SIZE_4CIF_W 704 +#define VIDEO_SIZE_4CIF_H 576 +#define VIDEO_SIZE_MAX_W VIDEO_SIZE_4CIF_W +#define VIDEO_SIZE_MAX_H VIDEO_SIZE_4CIF_H + + +#endif diff --git a/linphone/mediastreamer/msv4l.c b/linphone/mediastreamer/msv4l.c new file mode 100644 index 000000000..b661a25af --- /dev/null +++ b/linphone/mediastreamer/msv4l.c @@ -0,0 +1,522 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msv4l.h" +#include +#include +#include +#include +#include +#include +#include +#include + +char *v4l_palette_string[17]={ + "none", + "GREY", /* Linear greyscale */ + "HI240", /* High 240 cube (BT848) */ + "RGB565", /* 565 16 bit RGB */ + "RGB24", /* 24bit RGB */ + "RGB32", /* 32bit RGB */ + "RGB555", /* 555 15bit RGB */ + "YUV422", /* YUV422 capture */ + "YUYV", + "UYVY", /* The great thing about standards is ... */ + "YUV420", + "YUV411", /* YUV411 capture */ + "RAW", /* RAW capture (BT848) */ + "YUV422P", /* YUV 4:2:2 Planar */ + "YUV411P", /* YUV 4:1:1 Planar */ + "YUV420P", /* YUV 4:2:0 Planar */ + "YUV410P", /* YUV 4:1:0 Planar */ +}; + +#define V4L_PALETTE_TO_STRING(pal) v4l_palette_string[(pal)] + +static int v4l_string_to_enum(const char *format){ + if (strcmp(format,"RGB24")==0) return VIDEO_PALETTE_RGB24; + if (strcmp(format,"YUV420P")==0) return VIDEO_PALETTE_YUV420P; + g_error("unsupported format, fixme"); + return -1; +} + +MSFilterInfo v4l_info= +{ + "Video4Linux", + 0, + MS_FILTER_VIDEO_IO, + ms_v4l_new, + NULL +}; + + +static MSV4lClass *ms_v4l_class=NULL; + +MSFilter * ms_v4l_new() +{ + MSV4l *obj; + obj=g_malloc0(sizeof(MSV4l)); + if (ms_v4l_class==NULL) + { + ms_v4l_class=g_malloc0(sizeof(MSV4lClass)); + ms_v4l_class_init(ms_v4l_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_v4l_class); + ms_v4l_init(obj); + return MS_FILTER(obj); +} + +void ms_v4l_init(MSV4l *obj) +{ + ms_video_source_init(MS_VIDEO_SOURCE(obj)); + /* initialize the static buffer */ + obj->use_mmap=0; + obj->fd=-1; + obj->device = g_strdup("/dev/video0"); + obj->count=0; + obj->allocdbuf=NULL; + obj->grab_image=FALSE; + obj->image_grabbed=NULL; + obj->cond=g_cond_new(); + obj->stopcond=g_cond_new(); + obj->v4lthread=NULL; + obj->thread_exited=FALSE; + obj->frame=0; + MS_VIDEO_SOURCE(obj)->format="YUV420P"; /*default value */ + MS_VIDEO_SOURCE(obj)->width = VIDEO_SIZE_CIF_W; /*default value */ + MS_VIDEO_SOURCE(obj)->height = VIDEO_SIZE_CIF_H; /*default value */ +} + +void ms_v4l_class_init(MSV4lClass *klass) +{ + ms_video_source_class_init(MS_VIDEO_SOURCE_CLASS(klass)); + MS_VIDEO_SOURCE_CLASS(klass)->start=(void (*)(MSVideoSource *))ms_v4l_start; + MS_VIDEO_SOURCE_CLASS(klass)->stop=(void (*)(MSVideoSource *))ms_v4l_stop; + MS_VIDEO_SOURCE_CLASS(klass)->set_device=(int (*)(MSVideoSource*,const gchar*))ms_v4l_set_device; + MS_FILTER_CLASS(klass)->process=(void (*)(MSFilter *))v4l_process; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_v4l_destroy; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"msv4l"); + MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&v4l_info; +} + +void *v4l_thread(MSV4l *obj); + +void ms_v4l_start(MSV4l *obj) +{ + int err; + ms_filter_lock(MS_FILTER(obj)); + obj->fd=open(obj->device,O_RDONLY); + if (obj->fd<0) + { + g_warning("MSV4l: cannot open video device: %s.",strerror(errno)); + MS_VIDEO_SOURCE(obj)->format="RGB24"; + }else{ + err=v4l_configure(obj); + if (err<0) + { + g_warning("MSV4l: could not get configuration of video device"); + } + } + obj->thread_exited=FALSE; + obj->v4lthread=g_thread_create((GThreadFunc)v4l_thread,(gpointer)obj,FALSE,NULL); + while(!obj->thread_run) g_cond_wait(obj->cond,MS_FILTER(obj)->lock); + ms_filter_unlock(MS_FILTER(obj)); +} + +void ms_v4l_stop(MSV4l *obj) +{ + ms_filter_lock(MS_FILTER(obj)); + obj->thread_run=FALSE; + obj->grab_image=FALSE; + g_cond_signal(obj->cond); + while(!obj->thread_exited) g_cond_wait(obj->stopcond,MS_FILTER(obj)->lock); + if (obj->fd>0) + { + close(obj->fd); + obj->fd=-1; + if (!obj->use_mmap){ + if (obj->allocdbuf!=NULL) ms_buffer_destroy(obj->allocdbuf); + obj->allocdbuf=NULL; + }else + { + munmap(obj->mmapdbuf,obj->vmbuf.size); + obj->mmapdbuf=NULL; + } + obj->image_grabbed=NULL; + } + + obj->v4lthread=NULL; + ms_filter_unlock(MS_FILTER(obj)); +} + +int ms_v4l_set_device(MSV4l *obj, const gchar *device) +{ + if (obj->device!=NULL) g_free(obj->device); + obj->device=g_strdup(device); + return 0; +} + +void ms_v4l_set_size(MSV4l *obj, gint width, gint height) +{ + gint err; + gboolean restart = FALSE; + + if (obj->fd == -1) + { + obj->fd = open(obj->device, O_RDONLY); + if (obj->fd < 0) + { + g_warning("MSV4l: cannot open video device: %s.",strerror(errno)); + return; + } + } else + restart = TRUE; + + ms_filter_lock(MS_FILTER(obj)); + err = ioctl(obj->fd, VIDIOCGCAP, &obj->cap); + if (err != 0) + { + g_warning("MSV4l: cannot get device capabilities: %s.",strerror(errno)); + return; + } + if (width <= obj->cap.maxwidth && width >= obj->cap.minwidth && + height <= obj->cap.maxheight && height >= obj->cap.minheight) + { + MS_VIDEO_SOURCE(obj)->width = width; + MS_VIDEO_SOURCE(obj)->height = height; + } + ms_filter_unlock(MS_FILTER(obj)); + + if (restart) + { + ms_v4l_stop(obj); + ms_v4l_start(obj); + } + +} + +static gboolean try_format(MSV4l *obj, struct video_picture *pict, int palette, int depth){ + int err; + pict->palette=palette; + pict->depth=depth; + pict->contrast=25000; + err=ioctl(obj->fd,VIDIOCSPICT,pict); + if (err<0){ + g_warning("Could not set picture properties: %s",strerror(errno)); + return FALSE; + } + return TRUE; +} + +int v4l_configure(MSV4l *f) +{ + gint err; + gint i; + struct video_channel *chan=&f->channel; + struct video_picture *pict=&f->pict; + struct video_mmap *vmap=&f->vmap; + struct video_mbuf *vmbuf=&f->vmbuf; +// struct video_capture *vcap=&f->vcap; + int found=0; + + err=ioctl(f->fd,VIDIOCGCAP,&f->cap); + if (err!=0) + { + g_warning("MSV4l: cannot get device capabilities: %s.",strerror(errno)); + return -1; + } + MS_VIDEO_SOURCE(f)->dev_name=f->cap.name; + + for (i=0;icap.channels;i++) + { + chan->channel=i; + err=ioctl(f->fd,VIDIOCGCHAN,chan); + if (err==0) + { + g_message("Getting video channel %s",chan->name); + switch(chan->type){ + case VIDEO_TYPE_TV: + g_message("Channel is a TV."); + break; + case VIDEO_TYPE_CAMERA: + g_message("Channel is a camera"); + break; + default: + g_warning("unknown video channel type."); + } + found=1; + break; /* find the first channel */ + } + } + if (found) g_message("A valid video channel was found."); + /* select this channel */ + ioctl(f->fd,VIDIOCSCHAN,chan); + + /* set/get the resolution */ + err = -1; + + /* + if (f->cap.type & VID_TYPE_SUBCAPTURE) { + struct video_capture vcap; + vcap.x = vcap.y = 0; + vcap.width = MS_VIDEO_SOURCE(f)->width; + vcap.height = MS_VIDEO_SOURCE(f)->height; + err = ioctl(f->fd, VIDIOCSCAPTURE, &vcap); + + } + */ + + /* get picture properties */ + err=ioctl(f->fd,VIDIOCGPICT,pict); + if (err<0){ + g_warning("Could not get picture properties: %s",strerror(errno)); + return -1; + } + g_message("Default picture properties: brightness=%i,hue=%i,colour=%i,contrast=%i,depth=%i, palette=%i.", + pict->brightness,pict->hue,pict->colour, pict->contrast,pict->depth, pict->palette); + /* trying YUV420P format:*/ + if (try_format(f,pict,VIDEO_PALETTE_YUV420P,16)){ + g_message("Driver supports YUV420P, using that format."); + MS_VIDEO_SOURCE(f)->format="YUV420P"; + }else{ + g_message("Driver does not support YUV420P, trying RGB24..."); + if (try_format(f, pict,VIDEO_PALETTE_RGB24,24)){ + g_message("Driver supports RGB24, using that format."); + MS_VIDEO_SOURCE(f)->format="RGB24"; + }else{ + g_error("Unsupported video formats."); + } + } + + f->bsize=(pict->depth/8) * MS_VIDEO_SOURCE(f)->width* MS_VIDEO_SOURCE(f)->height; + + /* try to get mmap properties */ + err=ioctl(f->fd,VIDIOCGMBUF,vmbuf); + if (err<0){ + g_warning("Could not get mmap properties: %s",strerror(errno)); + f->use_mmap=0; + }else + { + if (vmbuf->size>0){ + f->use_mmap=1; + /* do the mmap */ + f->mmapdbuf=mmap((void*)f,vmbuf->size,PROT_READ,MAP_SHARED,f->fd,0); + if (f->mmapdbuf==(void*)-1) { + g_warning("Could not mmap. Using read instead: %s",strerror(errno)); + f->use_mmap=0; + f->mmapdbuf=NULL; + }else { + /* initialize the mediastreamer buffers */ + gint i; + g_message("Using %i-frames mmap'd buffer.",vmbuf->frames); + for(i=0;iframes;i++){ + f->img[i].buffer=f->mmapdbuf+vmbuf->offsets[i]; + f->img[i].size=vmbuf->offsets[1]; + f->img[i].ref_count=1; + } + f->frame=0; + } + } else g_warning("This device cannot support mmap."); + } + + /* initialize the video map structure */ + vmap->width=MS_VIDEO_SOURCE(f)->width; + vmap->height=MS_VIDEO_SOURCE(f)->height; + vmap->format=v4l_string_to_enum(MS_VIDEO_SOURCE(f)->format); + vmap->frame=0; + return 0; +} + +#define BPP 3 +static inline +void crop( guchar *src, gint s_width, gint s_height, guchar *dest, gint d_width, gint d_height) +{ + register int i; + register int stride = d_width*BPP; + register guchar *s = src, *d = dest; + s += ((s_height - d_height)/2 * s_width * BPP) + ((s_width - d_width)/2 * BPP); + for (i = 0; i < d_height; i++, d += stride, s += s_width * BPP) + memcpy( d, s, stride); +} + +MSBuffer * v4l_grab_image_mmap(MSV4l *obj){ + struct video_mmap *vmap=&obj->vmap; + struct video_mbuf *vmbuf=&obj->vmbuf; + int err; + int syncframe; + int jitter=vmbuf->frames-1; + obj->query_frame=(obj->frame) % vmbuf->frames; + /*g_message("v4l_mmap_process: query_frame=%i", + obj->query_frame);*/ + vmap->frame=obj->query_frame; + err=ioctl(obj->fd,VIDIOCMCAPTURE,vmap); + if (err<0) { + g_warning("v4l_mmap_process: error in VIDIOCMCAPTURE: %s.",strerror(errno)); + return NULL; + } + /*g_message("v4l_mmap_process: query_frame=%i done", + obj->query_frame);*/ + syncframe=(obj->frame-jitter); + obj->frame++; + if (syncframe>=0){ + syncframe=syncframe%vmbuf->frames; + g_message("Syncing on frame %i",syncframe); + err=ioctl(obj->fd,VIDIOCSYNC,&syncframe); + if (err<0) { + g_warning("v4l_mmap_process: error in VIDIOCSYNC: %s.",strerror(errno)); + return NULL; + } + /*g_message("got frame %i",syncframe);*/ + }else { + return NULL; + } + /* not particularly efficient - hope for a capture source that + provides subcapture or setting window */ + /* + if (obj->width != MS_VIDEO_SOURCE(obj)->width || obj->height != MS_VIDEO_SOURCE(obj)->height){ + guchar tmp[obj->bsize]; + crop((guchar*) obj->img[syncframe].buffer, obj->width, obj->height, tmp, + MS_VIDEO_SOURCE(obj)->width, MS_VIDEO_SOURCE(obj)->height); + memcpy(obj->img[syncframe].buffer, tmp, MS_VIDEO_SOURCE(obj)->width * + MS_VIDEO_SOURCE(obj)->height * obj->pict.depth/8); + } + */ + return &obj->img[syncframe]; +} + +MSBuffer *v4l_grab_image_read(MSV4l *obj){ + int err; + if (obj->allocdbuf==NULL){ + obj->allocdbuf=ms_buffer_new(obj->bsize); + obj->allocdbuf->ref_count++; + } + { + err=read(obj->fd,obj->allocdbuf->buffer,obj->bsize); + if (err<0){ + g_warning("MSV4l: Fail to read(): %s",strerror(errno)); + return NULL; + } + } + return obj->allocdbuf; +} + + +MSBuffer * v4l_make_mire(MSV4l *obj){ + gchar *data; + int i,j,line,pos; + int patternw=obj->parent.width/6; + int patternh=obj->parent.height/6; + int red,green=0,blue=0; + if (obj->allocdbuf==NULL){ + obj->allocdbuf=ms_buffer_new(obj->parent.width*obj->parent.height*3); + obj->allocdbuf->ref_count++; + } + data=obj->allocdbuf->buffer; + for (i=0;iparent.height;++i){ + line=i*obj->parent.width*3; + if ( ((i+obj->count)/patternh) & 0x1) red=255; + else red= 0; + for (j=0;jparent.width;++j){ + pos=line+(j*3); + + if ( ((j+obj->count)/patternw) & 0x1) blue=255; + else blue= 0; + + data[pos]=red; + data[pos+1]=green; + data[pos+2]=blue; + } + } + obj->count++; + usleep(60000); + return obj->allocdbuf; +} + + +void *v4l_thread(MSV4l *obj){ + GMutex *mutex=MS_FILTER(obj)->lock; + g_mutex_lock(mutex); + obj->thread_run=TRUE; + g_cond_signal(obj->cond); + while(obj->thread_run){ + g_cond_wait(obj->cond,mutex); + if (obj->grab_image){ + MSBuffer *grabbed; + g_mutex_unlock(mutex); + if (obj->fd>0){ + if (obj->use_mmap){ + grabbed=v4l_grab_image_mmap(obj); + }else{ + grabbed=v4l_grab_image_read(obj); + } + }else grabbed=v4l_make_mire(obj); + g_mutex_lock(mutex); + if (grabbed){ + obj->image_grabbed=grabbed; + obj->grab_image=FALSE; + } + } + } + g_cond_signal(obj->stopcond); + obj->thread_exited=TRUE; + g_mutex_unlock(mutex); + return NULL; +} + + + + +void v4l_process(MSV4l * obj) +{ + GMutex *mutex=MS_FILTER(obj)->lock; + g_mutex_lock(mutex); + if (obj->image_grabbed!=NULL){ + MSMessage *m=ms_message_alloc(); + ms_message_set_buf(m,obj->image_grabbed); + ms_queue_put(MS_FILTER(obj)->outqueues[0],m); + obj->image_grabbed=NULL; + }else{ + obj->grab_image=TRUE; + g_cond_signal(obj->cond); + } + g_mutex_unlock(mutex); +} + +void ms_v4l_uninit(MSV4l *obj) +{ + if (obj->device!=NULL) { + g_free(obj->device); + obj->device=NULL; + } + if (obj->v4lthread!=NULL) ms_v4l_stop(obj); + if (obj->allocdbuf!=NULL) { + ms_buffer_destroy(obj->allocdbuf); + obj->allocdbuf=NULL; + } + g_cond_free(obj->cond); + g_cond_free(obj->stopcond); + ms_filter_uninit(MS_FILTER(obj)); +} + +void ms_v4l_destroy(MSV4l *obj) +{ + ms_v4l_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msv4l.h b/linphone/mediastreamer/msv4l.h new file mode 100644 index 000000000..b0262b3a9 --- /dev/null +++ b/linphone/mediastreamer/msv4l.h @@ -0,0 +1,92 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSV4L_H +#define MSV4L_H + +#include "msvideosource.h" +#include +#include + +struct _MSV4l +{ + MSVideoSource parent; + int fd; + char *device; + struct video_capability cap; + struct video_channel channel; + struct video_window win; + struct video_picture pict; + struct video_mmap vmap; + struct video_mbuf vmbuf; + struct video_capture vcap; + gint bsize; + gint use_mmap; + gint frame; + guint query_frame; + gchar *mmapdbuf; /* the mmap'd buffer */ + MSBuffer img[VIDEO_MAX_FRAME]; /* the buffer wrappers used for mmaps */ + MSBuffer *allocdbuf; /* the buffer allocated for read() and mire */ + gint count; + MSBuffer *image_grabbed; + GCond *cond; + GCond *stopcond; + GThread *v4lthread; + gboolean grab_image; + gboolean thread_run; + gboolean thread_exited; +}; + +typedef struct _MSV4l MSV4l; + + +struct _MSV4lClass +{ + MSVideoSourceClass parent_class; + +}; + +typedef struct _MSV4lClass MSV4lClass; + + +/* PUBLIC API */ +#define MS_V4L(v) ((MSV4l*)(v)) +#define MS_V4L_CLASS(k) ((MSV4lClass*)(k)) +MSFilter * ms_v4l_new(); + +void ms_v4l_start(MSV4l *obj); +void ms_v4l_stop(MSV4l *obj); +int ms_v4l_set_device(MSV4l *f, const gchar *device); +void ms_v4l_set_size(MSV4l *v4l, gint w, gint h); + +/* PRIVATE API */ +void ms_v4l_init(MSV4l *obj); +void ms_v4l_class_init(MSV4lClass *klass); +int v4l_configure(MSV4l *f); + +void v4l_process(MSV4l *obj); + +void ms_v4l_uninit(MSV4l *obj); + +void ms_v4l_destroy(MSV4l *obj); + +extern MSFilterInfo v4l_info; + +#endif diff --git a/linphone/mediastreamer/msvideooutput.c b/linphone/mediastreamer/msvideooutput.c new file mode 100644 index 000000000..c09c33aea --- /dev/null +++ b/linphone/mediastreamer/msvideooutput.c @@ -0,0 +1,495 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msvideooutput.h" +#include "msvideosource.h" +#include "affine.h" +#include "msavdecoder.h" +#include "msutils.h" +#include + +#ifndef XV_YV12 +#define XV_YV12 0x32315659 +#endif + +#ifndef XV_YUY2 +#define XV_YUY2 0x32595559 +#endif + +#ifndef XV_UYVY +#define XV_UYVY 0x59565955 +#endif + +#ifndef XV_I420 +#define XV_I420 0x30323449 +#endif + +static MSVideoOutputClass *ms_video_output_class=NULL; + + +gboolean xv_init (MSVideoOutput *obj) +{ + gboolean got_port = FALSE; + unsigned int count; + XvAdaptorInfo *adaptor; + + obj->xv_shminfo.shmaddr = NULL; + obj->xv_window = gdk_x11_drawable_get_xid(obj->window); + obj->xv_display = (Display*) gdk_x11_drawable_get_xdisplay(obj->window); + + if ( XvQueryAdaptors(obj->xv_display, obj->xv_window, &count, &adaptor) == Success ) + { + unsigned int n, i; + + for (n = 0; !got_port && n < count; ++n) + { + for ( obj->xv_port = adaptor[n].base_id; + obj->xv_port < adaptor[n].base_id + adaptor[n].num_ports; + obj->xv_port++ ) + { + if (XvGrabPort(obj->xv_display, obj->xv_port, CurrentTime) == 0) + { + int formats; + XvImageFormatValues *list; + + list = XvListImageFormats( obj->xv_display, obj->xv_port, &formats); + for ( i = 0; i < formats; i ++ ) { + if ( list[i].id == XV_I420 && !got_port ) + got_port = TRUE; + } + if ( got_port ) + break; + else + XvUngrabPort( obj->xv_display, obj->xv_port, CurrentTime ); + } + } + } + if ( got_port ) + { + obj->xv_gc = XCreateGC(obj->xv_display, obj->xv_window, 0, &obj->xv_values); + + obj->xv_image = (XvImage *) XvShmCreateImage( obj->xv_display, obj->xv_port, XV_I420, 0, obj->width, obj->height, &obj->xv_shminfo); + if (obj->xv_image == NULL) { + g_message("Unable to allocate XvImage, falling back to GDK output"); + XvUngrabPort( obj->xv_display, obj->xv_port, CurrentTime ); + obj->xv_port = 0; + return FALSE; + } + else { + g_message("allocated XvImage with size %i", obj->xv_image->data_size); + } + + obj->xv_shminfo.shmid = shmget( IPC_PRIVATE, obj->xv_image->data_size, IPC_CREAT | 0777); + obj->xv_shminfo.shmaddr = (char *) shmat( obj->xv_shminfo.shmid, 0, 0); + obj->xv_image->data = obj->xv_shminfo.shmaddr; + obj->xv_shminfo.readOnly = 0; + if (!XShmAttach( (Display*) gdk_x11_get_default_xdisplay(), &obj->xv_shminfo)) { + got_port = FALSE; + } + shmctl(obj->xv_shminfo.shmid, IPC_RMID, 0); + } + else obj->xv_port = 0; + } + else { + got_port = FALSE; + obj->xv_port = 0; + } + return got_port; +} + + +void xv_uninit(MSVideoOutput *obj) +{ + if ( obj->xv_port ) { + XvUngrabPort( obj->xv_display, obj->xv_port, CurrentTime ); + } + + if (obj->xv_image != NULL) + XvStopVideo(obj->xv_display, obj->xv_port, obj->xv_window); + + if (obj->xv_shminfo.shmaddr != NULL) { + XShmDetach(obj->xv_display, &obj->xv_shminfo); + shmctl(obj->xv_shminfo.shmid, IPC_RMID, 0); + shmdt(obj->xv_shminfo.shmaddr); + } + if (obj->xv_image != NULL) + XFree(obj->xv_image); +} + +void ms_video_output_init(MSVideoOutput *obj) +{ + gint error; + GdkWindowAttr attr; + MSVideoOutputClass *klass=MS_VIDEO_OUTPUT_CLASS(MS_FILTER(obj)->klass); + memset(&attr,0,sizeof(attr)); + attr.title="linphone video"; + attr.window_type=GDK_WINDOW_CHILD; + attr.wclass=GDK_INPUT_OUTPUT; + attr.x=0; + attr.y=0; + attr.width = VIDEO_SIZE_CIF_W; + attr.height = VIDEO_SIZE_CIF_H; + attr.visual=klass->visual; + attr.colormap=klass->colormap; + attr.override_redirect = TRUE; + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->inqueues=obj->input; + obj->window=gdk_window_new(NULL,&attr,GDK_WA_TITLE|GDK_WA_X|GDK_WA_Y|GDK_WA_COLORMAP|GDK_WA_VISUAL); + if (obj->window==NULL) + { + g_error("Could not create gdk video window"); + } + obj->gc=gdk_gc_new(obj->window); + gdk_window_show(obj->window); + gdk_flush(); + //gdk_window_withdraw(obj->window); + obj->width = VIDEO_SIZE_CIF_W; + obj->height = VIDEO_SIZE_CIF_H; + obj->prev_h=0; + obj->prev_w=0; + + obj->bpp = 3/2; + obj->bufsize=obj->width*obj->height*obj->bpp; + obj->palette = "YUV420P"; + obj->active=TRUE; +} + +void ms_video_output_setup(MSVideoOutput *vo, MSSync *sync) +{ +#if 0 + /* tries to find the video source of the stream */ + MSFilter *vs; + vs=ms_filter_search_upstream_by_type(MS_FILTER(vo),MS_FILTER_VIDEO_IO); + if (vs != NULL) { + /* get video source properties */ + vo->width=MS_VIDEO_SOURCE(vs)->width; + vo->height=MS_VIDEO_SOURCE(vs)->height; + vo->palette=MS_VIDEO_SOURCE(vs)->format; + ms_video_output_set_size(vo,vo->width,vo->height); + } else + g_warning("ms_video_output_setup: could not find the video source."); + + if (xv_init(vo) == FALSE && vo->palette!=NULL && strcmp(vo->palette, "RGB24") != 0) { + /* tell our upstream codec to use RGB too! */ + vs=ms_filter_search_upstream_by_type(MS_FILTER(vo),MS_FILTER_VIDEO_CODEC); + if (vs != NULL) { + ms_trace("found upstream codec"); + vo->palette = "RGB24"; + vo->bpp = 3; + vo->bufsize = vo->width*vo->height*vo->bpp; + ms_AVdecoder_set_format(MS_AVDECODER(vs), "RGB24"); + }else{ + g_warning("ms_video_output_setup: could not find the video codec."); + } + } +#endif +} + + +void ms_video_output_class_init(MSVideoOutputClass *klass) +{ + gint status; + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_qinputs=2; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_video_output_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_video_output_process; + MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_video_output_setup; + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"MSVideoOutput"); + status=gdk_init_check(0,NULL); + if (status==0){ + g_error("Failed to initialize gdk."); + } + gdk_rgb_init(); + gdk_rgb_set_verbose(1); + klass->visual=gdk_rgb_get_visual(); + klass->colormap=gdk_rgb_get_cmap(); +} + +void ms_video_output_uninit(MSVideoOutput *obj) +{ + xv_uninit(obj); + gdk_gc_destroy(obj->gc); + gdk_window_destroy(obj->window); + gdk_flush(); +} + +MSFilter * ms_video_output_new() +{ + MSVideoOutput *obj=g_malloc0(sizeof(MSVideoOutput)); + + if (ms_video_output_class==NULL) + { + ms_video_output_class=g_malloc0(sizeof(MSVideoOutputClass)); + ms_video_output_class_init(ms_video_output_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_video_output_class); + ms_video_output_init(obj); + return MS_FILTER(obj); +} + +void ms_video_output_start(MSVideoOutput *obj) +{ + ms_filter_lock(MS_FILTER(obj)); + obj->active=TRUE; + ms_filter_unlock(MS_FILTER(obj)); +} + +void ms_video_output_stop(MSVideoOutput *obj) +{ + ms_filter_lock(MS_FILTER(obj)); + obj->active=FALSE; + ms_filter_unlock(MS_FILTER(obj)); +} + +void ms_video_output_set_title(MSVideoOutput *obj,gchar *title) +{ + g_return_if_fail(obj->window); + gdk_threads_enter(); + gdk_window_set_title(obj->window,title); + gdk_flush(); + gdk_threads_leave(); +} + +void ms_video_output_set_size(MSVideoOutput *obj,gint width, gint height) +{ + gdk_threads_enter(); + obj->width=width; + obj->height=height; + obj->bufsize=width*height*obj->bpp; + gdk_window_resize(obj->window,width,height); + gdk_flush(); + gdk_threads_leave(); +} + +void ms_video_output_set_format(MSVideoOutput *obj, const char *fmt){ + obj->palette=fmt; +} + +static inline +void composite( guchar *dest, gint d_width, gint d_height, gint d_x, gint d_y, guchar *src, gint s_width, gint s_height, gint bpp) +{ + register gint i; + register gint s_stride = s_width*bpp; + register gint d_stride = d_width*bpp; + register guchar *s = src, *d = dest; + d += (d_y * d_stride) + (d_x * bpp); + for (i = 0; i < s_height; i++, s += s_stride, d += d_stride) + memcpy( d, s, s_stride); +} + +static inline void ntohl_block(guint32 *buf, int len) +{ + register int i; + for (i=0; i>10);\ + g = y - ((u*352 + v*731) >> 10);\ + b = y + ((u*1814) >> 10);\ + r = r < 0 ? 0 : r;\ + g = g < 0 ? 0 : g;\ + b = b < 0 ? 0 : b;\ + r = r > 255 ? 255 : r;\ + g = g > 255 ? 255 : g;\ + b = b > 255 ? 255 : b + + +static inline +void yv12_to_rgb24 (unsigned char *src, unsigned char *dest, int width, int height) +{ + register int i,j; + register int y0, y1, u, v; + register int r, g, b; + register unsigned char *s[3]; + s[0] = src; + s[1] = s[0] + width*height; + s[2] = s[1] + width*height/4; + + for (i = 0; i < height; i++) { + for (j = 0; j < width/2; j++) { + y0 = *(s[0])++; + y1 = *(s[0])++; + if (i % 2 == 0 ) { + u = *(s[1])++ - 128; + v = *(s[2])++ - 128; + } + YUV2RGB (y0, u, v, r, g, b); + *dest++ = r; + *dest++ = g; + *dest++ = b; + YUV2RGB (y1, u, v, r, g, b); + *dest++ = r; + *dest++ = g; + *dest++ = b; + } + } +} + + +#define PIP_FACTOR 5.0 + +void ms_video_output_process(MSVideoOutput *obj) +{ + MSQueue *q=obj->input[0]; + MSMessage *m; + GdkPixbuf *pb_pip = NULL; + guchar buf[VIDEO_SIZE_MAX_W*VIDEO_SIZE_MAX_H*3], buf2[VIDEO_SIZE_MAX_W*VIDEO_SIZE_MAX_H*3]; + + ms_filter_lock(MS_FILTER(obj)); + if (obj->active==FALSE){ + ms_filter_unlock(MS_FILTER(obj)); + while((m=ms_queue_get(q))!=NULL) ms_message_destroy(m); + return; + } + + while((m=ms_queue_get(q))!=NULL) + { + ms_trace("Getting new buffer"); + if (m->size >= obj->bufsize) + { + gint w=VIDEO_SIZE_CIF_W, h=VIDEO_SIZE_CIF_H; + + gdk_threads_enter(); + gdk_window_get_geometry(obj->window, NULL, NULL, &w, &h, NULL); + if (w != obj->prev_w || h != obj->prev_h) { + gdk_window_resize(obj->window,w,h); + gdk_window_clear(obj->window); + obj->prev_w = w; + obj->prev_h = h; + } + gdk_flush(); + if (obj->xv_port != 0 && strcmp(obj->palette, "YUV420P") == 0) { + int imageWidth = obj->width * obj->width / VIDEO_SIZE_MAX_W; + int imageHeight = obj->height * obj->height / VIDEO_SIZE_MAX_H; + double ratioWidth = (double)w / (double)imageWidth; + double ratioHeight = (double)h / (double)imageHeight; + int width, height, x, y; + if (ratioHeight < ratioWidth) { + width = (int)( imageWidth * ratioHeight ); + height = (int)( imageHeight * ratioHeight ); + } else { + width = (int)( imageWidth * ratioWidth ); + height = (int)( imageHeight * ratioWidth ); + } + x = ( w - width ) / 2; + y = ( h - height ) / 2; + + memcpy( obj->xv_image->data, m->data, obj->xv_image->data_size ); + if (obj->input[1] != NULL) { + MSMessage *m = ms_queue_get(obj->input[1]); + + if (m != NULL) { + /* CAUTION: this is very tricky planar scaling and compositing! */ + affine_scale((const unsigned char *)m->data, buf, + obj->width, obj->height, obj->width/PIP_FACTOR, obj->height/PIP_FACTOR, 1); + + affine_scale( (const unsigned char *) m->data + obj->width * obj->height, + buf + (int)(obj->width/PIP_FACTOR * obj->height/PIP_FACTOR), + obj->width/2, obj->height/2, obj->width/PIP_FACTOR/2, obj->height/PIP_FACTOR/2, 1); + + affine_scale( (const unsigned char *) m->data + (int)(obj->width * obj->height * 5/4), + buf + (int)(obj->width/PIP_FACTOR * obj->height/PIP_FACTOR * 5/4), + obj->width/2, obj->height/2, obj->width/PIP_FACTOR/2, obj->height/PIP_FACTOR/2, 1); + + ms_message_destroy(m); + + composite( obj->xv_image->data, obj->width, obj->height, obj->width-obj->width/PIP_FACTOR-6, 6, + buf, obj->width/PIP_FACTOR, obj->height/PIP_FACTOR, 1); + + composite( obj->xv_image->data + (int)(obj->width * obj->height), + obj->width/2, obj->height/2, obj->width/2 - obj->width/PIP_FACTOR/2 - 3, 3, + buf + (int)(obj->width/PIP_FACTOR * obj->height/PIP_FACTOR), + obj->width/PIP_FACTOR/2, obj->height/PIP_FACTOR/2, 1); + + composite( obj->xv_image->data + (int)(obj->width * obj->height * 5/4), + obj->width/2, obj->height/2, obj->width/2 - obj->width/PIP_FACTOR/2 - 3, 3, + buf + (int)(obj->width/PIP_FACTOR * obj->height/PIP_FACTOR * 5/4), + obj->width/PIP_FACTOR/2, obj->height/PIP_FACTOR/2, 1); + } + } + XvShmPutImage(obj->xv_display, obj->xv_port, obj->xv_window, obj->xv_gc, obj->xv_image, + 0, 0, obj->width, obj->height, + x, y, width, height, FALSE ); + XFlush(obj->xv_display); + } + else + { + GdkPixbuf *pb, *pb_scaled; + + if (strcmp(obj->palette, "RGB24") == 0) { + pb = gdk_pixbuf_new_from_data( m->data, GDK_COLORSPACE_RGB, + FALSE, 8, obj->width, obj->height, obj->width*3, NULL, NULL); + } else { + /* convert the YUV420P image to RGB24 ourselves */ + yv12_to_rgb24(m->data, buf2, obj->width, obj->height); + pb = gdk_pixbuf_new_from_data(buf2, GDK_COLORSPACE_RGB, + FALSE, 8, obj->width, obj->height, obj->width*3, NULL, NULL); + } + + pb_scaled = gdk_pixbuf_scale_simple(pb, w, h, GDK_INTERP_BILINEAR); + if (obj->input[1] != NULL) { + MSMessage *m = ms_queue_get(obj->input[1]); + + if (m != NULL) { + GdkPixbuf *pb; + /* XXX: assumes the pip video source is always YV12 */ + yv12_to_rgb24(m->data, buf, obj->width, obj->height); + + pb = gdk_pixbuf_new_from_data( buf, GDK_COLORSPACE_RGB, + FALSE, 8, obj->width, obj->height, obj->width*3, NULL, NULL); + if (pb_pip != NULL) + gdk_pixbuf_unref(pb_pip); + pb_pip = gdk_pixbuf_scale_simple(pb, w/PIP_FACTOR, h/PIP_FACTOR, GDK_INTERP_BILINEAR); + ms_message_destroy(m); + gdk_pixbuf_unref(pb); + } + if (pb_pip != NULL) { + gdk_pixbuf_composite(pb_pip, pb_scaled, + w-w/PIP_FACTOR-5, 5, w/PIP_FACTOR, h/PIP_FACTOR, + w-w/PIP_FACTOR-5, 5, 1.0, 1.0, + GDK_INTERP_BILINEAR, 255); + } + } + gdk_pixbuf_render_to_drawable(pb_scaled, obj->window, obj->gc, 0, 0, 0, 0, + w, h, GDK_RGB_DITHER_NONE, 0, 0); + + gdk_flush(); + gdk_pixbuf_unref(pb); + gdk_pixbuf_unref(pb_scaled); + } + gdk_threads_leave(); + } + else g_warning("Image is too small for current window"); + ms_message_destroy(m); + } + ms_filter_unlock(MS_FILTER(obj)); +} + +void ms_video_output_destroy(MSVideoOutput *obj) +{ + ms_video_output_uninit(obj); + g_free(obj); +} diff --git a/linphone/mediastreamer/msvideooutput.h b/linphone/mediastreamer/msvideooutput.h new file mode 100644 index 000000000..6f7835791 --- /dev/null +++ b/linphone/mediastreamer/msvideooutput.h @@ -0,0 +1,86 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef MSVIDEOOUTPUT_H +#define MSVIDEOOUTPUT_H + + +#include "ms.h" +#include "msfilter.h" +#include +#include +#include +#include +#include +#include + +struct _MSVideoOutput +{ + MSFilter parent; + MSQueue *input[2]; + GdkWindow *window; + GdkGC *gc; + GdkImage *image; + gint width,height; + gint bufsize; + const gchar *palette; + gdouble bpp; + gint prev_w, prev_h; + Display *xv_display; + Window xv_window; + GC xv_gc; + XGCValues xv_values; + XvImage *xv_image; + unsigned int xv_port; + XShmSegmentInfo xv_shminfo; + gboolean active; +}; + + +typedef struct _MSVideoOutput MSVideoOutput; + +struct _MSVideoOutputClass +{ + MSFilterClass parent_class; + GdkVisual *visual; + GdkColormap *colormap; +}; + +typedef struct _MSVideoOutputClass MSVideoOutputClass; + + +#define MS_VIDEO_OUTPUT(obj) ((MSVideoOutput*)(obj)) +#define MS_VIDEO_OUTPUT_CLASS(klass) ((MSVideoOutputClass*)(klass)) + +void ms_video_output_init(MSVideoOutput *obj); +void ms_video_output_class_init(MSVideoOutputClass *klass); +void ms_video_output_uninit(MSVideoOutput *obj); + +MSFilter * ms_video_output_new(); +void ms_video_output_set_format(MSVideoOutput *obj, const char *fmt); +void ms_video_output_set_size(MSVideoOutput *obj,gint width, gint height); +void ms_video_output_start(MSVideoOutput *obj); +void ms_video_output_stop(MSVideoOutput *obj); +void ms_video_output_set_title(MSVideoOutput *obj,gchar *title); + +void ms_video_output_destroy(MSVideoOutput *obj); +void ms_video_output_process(MSVideoOutput *obj); +#endif diff --git a/linphone/mediastreamer/msvideosource.c b/linphone/mediastreamer/msvideosource.c new file mode 100644 index 000000000..fad63d12c --- /dev/null +++ b/linphone/mediastreamer/msvideosource.c @@ -0,0 +1,99 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "msvideosource.h" +#include "mediastream.h" + +#ifdef __linux +#include "msv4l.h" +#endif +#ifdef HAVE_LIBDC1394 +#include "msdc1394.h" +#endif + +/* register all statically linked codecs */ +void ms_video_source_register_all() +{ +#ifdef __linux + ms_filter_register(&v4l_info); +#endif +#ifdef HAVE_LIBDC1394 + ms_filter_register(MS_FILTER_INFO(&dc1394_info)); +#endif +} + +void ms_video_source_class_init(MSVideoSourceClass *klass) +{ + /* init base class first*/ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + /* then init videosource specific things*/ + MS_FILTER_CLASS(klass)->max_qoutputs=MSVIDEOSOURCE_MAX_OUTPUTS; + ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE|FILTER_HAS_QUEUES); +} + +void ms_video_source_init(MSVideoSource *obj) +{ + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->outqueues=obj->outputs; + obj->width = VIDEO_SIZE_CIF_W; + obj->height = VIDEO_SIZE_CIF_H; +} + +void ms_video_source_start(MSVideoSource *f) +{ + MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->start(f); +} + +void ms_video_source_stop(MSVideoSource *f) +{ + MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->stop(f); +} + +int ms_video_source_set_device(MSVideoSource *f, const gchar *device) +{ + return MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->set_device(f,device); +} + +gchar* ms_video_source_get_device_name(MSVideoSource *f) +{ + return f->dev_name; +} + +void ms_video_source_set_size(MSVideoSource *f, gint width, gint height) +{ + if (MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->set_size) + MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->set_size(f, width, height); +} + +void ms_video_source_set_frame_rate(MSVideoSource *f, gint frame_rate, gint frame_rate_base) +{ + if (MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->set_frame_rate) + MS_VIDEO_SOURCE_CLASS(MS_FILTER(f)->klass)->set_frame_rate(f, frame_rate, frame_rate_base); + else{ + f->frame_rate=frame_rate; + f->frame_rate_base=frame_rate_base; + } +} + +gchar* ms_video_source_get_format(MSVideoSource *f) +{ + return f->format; +} diff --git a/linphone/mediastreamer/msvideosource.h b/linphone/mediastreamer/msvideosource.h new file mode 100644 index 000000000..9a27f836c --- /dev/null +++ b/linphone/mediastreamer/msvideosource.h @@ -0,0 +1,74 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSVIDEOSOURCE_H +#define MSVIDEOSOURCE_H + + +#include "msfilter.h" + +/* this is the video input abstract class */ + +#define MSVIDEOSOURCE_MAX_OUTPUTS 1 /* max output per filter*/ + +typedef struct _MSVideoSource +{ + /* the MSVideoSource derivates from MSFilter, so the MSFilter object MUST be the first of the MSVideoSource object + in order to the object mechanism to work*/ + MSFilter filter; + MSQueue *outputs[MSVIDEOSOURCE_MAX_OUTPUTS]; + gchar *dev_name; + gint width, height; + gchar *format; + gint frame_rate; + gint frame_rate_base; +} MSVideoSource; + +typedef struct _MSVideoSourceClass +{ + /* the MSVideoSource derivates from MSFilter, so the MSFilter class MUST be the first of the MSVideoSource class + in order to the class mechanism to work*/ + MSFilterClass parent_class; + gint (*set_device)(MSVideoSource *s, const gchar *name); + void (*start)(MSVideoSource *s); + void (*stop)(MSVideoSource *s); + void (*set_size)(MSVideoSource *s, gint width, gint height); + void (*set_frame_rate)(MSVideoSource *s, gint frame_rate, gint frame_rate_base); +} MSVideoSourceClass; + +/* PUBLIC */ +void ms_video_source_register_all(); +int ms_video_source_set_device(MSVideoSource *f, const gchar *device); +gchar* ms_video_source_get_device_name(MSVideoSource *f); +void ms_video_source_start(MSVideoSource *f); +void ms_video_source_stop(MSVideoSource *f); +void ms_video_source_set_size(MSVideoSource *f, gint width, gint height); +void ms_video_source_set_frame_rate(MSVideoSource *f, gint frame_rate, gint frame_rate_base); +gchar* ms_video_source_get_format(MSVideoSource *f); + +#define MS_VIDEO_SOURCE(obj) ((MSVideoSource*)(obj)) +#define MS_VIDEO_SOURCE_CLASS(klass) ((MSVideoSourceClass*)(klass)) + + +/* FOR INTERNAL USE*/ +void ms_video_source_init(MSVideoSource *f); +void ms_video_source_class_init(MSVideoSourceClass *klass); + +#endif diff --git a/linphone/mediastreamer/mswrite.c b/linphone/mediastreamer/mswrite.c new file mode 100644 index 000000000..d548736fc --- /dev/null +++ b/linphone/mediastreamer/mswrite.c @@ -0,0 +1,129 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mswrite.h" +#include +#include +#include +#include +#include +#include +#include + +static MSWriteClass *ms_write_class=NULL; + +#ifdef _WIN32 +# define FILEPERMS (S_IRUSR|S_IWUSR) +#else +# define FILEPERMS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) +#endif + +MSFilter * ms_write_new(char *name) +{ + MSWrite *r; + int fd=-1; + + r=g_new(MSWrite,1); + ms_write_init(r); + if (ms_write_class==NULL) + { + ms_write_class=g_new(MSWriteClass,1); + ms_write_class_init(ms_write_class); + } + MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_write_class); + if ((name!=NULL) && (strlen(name)!=0)) + { + fd=open(name,O_WRONLY | O_CREAT | O_TRUNC,FILEPERMS); + if (fd<0) g_error("ms_write_new: failed to open %s.\n",name); + } + r->fd=fd; + return(MS_FILTER(r)); +} + + +/* FOR INTERNAL USE*/ +void ms_write_init(MSWrite *r) +{ + ms_filter_init(MS_FILTER(r)); + MS_FILTER(r)->infifos=r->f_inputs; + MS_FILTER(r)->inqueues=r->q_inputs; + MS_FILTER(r)->r_mingran=MSWRITE_MIN_GRAN; + memset(r->f_inputs,0,sizeof(MSFifo*)*MSWRITE_MAX_INPUTS); + memset(r->q_inputs,0,sizeof(MSQueue*)*MSWRITE_MAX_INPUTS); + r->fd=-1; +} + +void ms_write_class_init(MSWriteClass *klass) +{ + ms_filter_class_init(MS_FILTER_CLASS(klass)); + ms_filter_class_set_name(MS_FILTER_CLASS(klass),"dskwriter"); + MS_FILTER_CLASS(klass)->max_finputs=MSWRITE_MAX_INPUTS; + MS_FILTER_CLASS(klass)->max_qinputs=MSWRITE_MAX_INPUTS; + MS_FILTER_CLASS(klass)->r_maxgran=MSWRITE_DEF_GRAN; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_write_destroy; + MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_write_process; +} + +void ms_write_process(MSWrite *r) +{ + MSFifo *f; + MSQueue *q; + MSMessage *buf=NULL; + int i,j,err1,err2; + gint gran=ms_filter_get_mingran(MS_FILTER(r)); + void *p; + + /* process output fifos*/ + for (i=0,j=0;(iklass->max_finputs)&&(jfinputs);i++) + { + f=r->f_inputs[i]; + if (f!=NULL) + { + if ( (err1=ms_fifo_get_read_ptr(f,gran,&p))>0 ) + { + + err2=write(r->fd,p,gran); + if (err2<0) g_warning("ms_write_process: failed to write: %s.\n",strerror(errno)); + } + j++; + } + } + /* process output queues*/ + for (i=0,j=0;(iklass->max_qinputs)&&(jqinputs);i++) + { + q=r->q_inputs[i]; + if (q!=NULL) + { + while ( (buf=ms_queue_get(q))!=NULL ){ + int ret = write(r->fd,buf->data,buf->size); + assert( ret == buf->size ); + j++; + ms_message_destroy(buf); + } + } + } +} + +void ms_write_destroy( MSWrite *obj) +{ + if (obj->fd!=0) close(obj->fd); + g_free(obj); +} + diff --git a/linphone/mediastreamer/mswrite.h b/linphone/mediastreamer/mswrite.h new file mode 100644 index 000000000..cd766d10f --- /dev/null +++ b/linphone/mediastreamer/mswrite.h @@ -0,0 +1,63 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSWRITE_H +#define MSWRITE_H + +#include "msfilter.h" + + +/*this is the class that implements writing reading sink filter*/ + +#define MSWRITE_MAX_INPUTS 1 /* max output per filter*/ + +#define MSWRITE_DEF_GRAN 512 /* the default granularity*/ +#define MSWRITE_MIN_GRAN 64 + +typedef struct _MSWrite +{ + /* the MSWrite derivates from MSFilter, so the MSFilter object MUST be the first of the MSWrite object + in order to the object mechanism to work*/ + MSFilter filter; + MSFifo *f_inputs[MSWRITE_MAX_INPUTS]; + MSQueue *q_inputs[MSWRITE_MAX_INPUTS]; + gint fd; /* the file descriptor of the file being written*/ +} MSWrite; + +typedef struct _MSWriteClass +{ + /* the MSWrite derivates from MSFilter, so the MSFilter class MUST be the first of the MSWrite class + in order to the class mechanism to work*/ + MSFilterClass parent_class; +} MSWriteClass; + +/* PUBLIC */ +#define MS_WRITE(filter) ((MSWrite*)(filter)) +#define MS_WRITE_CLASS(klass) ((MSWriteClass*)(klass)) +MSFilter * ms_write_new(char *name); + +/* FOR INTERNAL USE*/ +void ms_write_init(MSWrite *r); +void ms_write_class_init(MSWriteClass *klass); +void ms_write_destroy( MSWrite *obj); +void ms_write_process(MSWrite *r); + +#endif + diff --git a/linphone/mediastreamer/msxine.c b/linphone/mediastreamer/msxine.c new file mode 100644 index 000000000..f5f407c2e --- /dev/null +++ b/linphone/mediastreamer/msxine.c @@ -0,0 +1,189 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msxine.h" +#include "stdlib.h" + + +static MSXineClass *ms_xine_class=NULL; + +static void change_window_size(void *user_data, + int video_width, int video_height, + int *dest_x, int *dest_y, + int *dest_height, int *dest_width) +{ + MSXine *obj=(MSXine*)user_data; + XLockDisplay(obj->vis.display); + g_message("entering change window size!!!!"); + g_message("video_width=%i, video_height=%i",video_width,video_height); + sleep(1); + fflush(NULL); + XUnlockDisplay(obj->vis.display); + +} + +void calc_dest_size (void *this, + int video_width, int video_height, + int *dest_width, int *dest_height) { + g_message("entering video_window_calc_dest_size() !"); + *dest_width=video_width; + *dest_height=video_height; +} +void ms_xine_init(MSXine *obj) +{ + MSXineClass *klass=MS_XINE_CLASS(MS_FILTER(obj)->klass); + double res_h,res_v; + XSetWindowAttributes att; + ao_driver_t *ao_driver; + XGCValues xgcv; + + + ms_filter_init(MS_FILTER(obj)); + MS_FILTER(obj)->inqueues=obj->input; + memset(&obj->vis,0,sizeof(x11_visual_t)); + /* create an X11 window */ + obj->vis.display=XOpenDisplay(NULL); + obj->vis.screen=DefaultScreen(obj->vis.display); + + res_h = (DisplayWidth (obj->vis.display, obj->vis.screen)*1000 + / DisplayWidthMM (obj->vis.display, obj->vis.screen)); + res_v = (DisplayHeight (obj->vis.display, obj->vis.screen)*1000 + / DisplayHeightMM (obj->vis.display, obj->vis.screen)); + obj->vis.display_ratio = res_h / res_v; + if (fabs(obj->vis.display_ratio - 1.0) < 0.01) { + /* + * we have a display with *almost* square pixels (<1% error), + * to avoid time consuming software scaling in video_out_xshm, + * correct this to the exact value of 1.0 and pretend we have + * perfect square pixels. + */ + obj->vis.display_ratio = 1.0; + } + + att.colormap=DefaultColormap(obj->vis.display,obj->vis.screen); + att.background_pixel = BlackPixel(obj->vis.display,obj->vis.screen); + att.border_pixel = BlackPixel(obj->vis.display,obj->vis.screen); + obj->vis.d=XCreateWindow(obj->vis.display,RootWindow(obj->vis.display,obj->vis.screen),0,0,1000,800,0, + DefaultDepth(obj->vis.display,obj->vis.screen),CopyFromParent, + DefaultVisual(obj->vis.display,obj->vis.screen), + CWColormap | CWBackPixel | CWBorderPixel, + &att); + XMapWindow(obj->vis.display,obj->vis.d); + XSync(obj->vis.display,False); + XSetStandardProperties(obj->vis.display, obj->vis.d, + "Linphone video display", "Linphone video display", None, NULL, 0, 0); + XCreateGC(obj->vis.display, obj->vis.d, 0L, &xgcv); + + //XMapRaised(obj->vis.display,obj->vis.d); + //sleep(1); + //XFlush(obj->vis.display); + + /* select the first available output plugin type*/ + obj->vo_driver=xine_load_video_output_plugin(klass->config, + klass->video_plugins[0], + VISUAL_TYPE_X11, + &obj->vis); + if (obj->vo_driver==NULL){ + g_error("Could not load a xine output plugin."); + } + else g_message("New vo driver %x created.",obj->vo_driver); + ao_driver=xine_load_audio_output_plugin(klass->config,"esd"); + if (ao_driver==NULL) g_message("Could not load audio output plugin"); + + /* set some callbacks */ + obj->vis.user_data=(void*)obj; + obj->vis.request_dest_size=change_window_size; + obj->vis.calc_dest_size=calc_dest_size; + + /* initializing a xine engine*/ + obj->engine=xine_init(obj->vo_driver,ao_driver,klass->config); + if (obj->engine==NULL){ + g_error("Could not create a new xine engine"); + } + + obj->vo_driver->gui_data_exchange (obj->vo_driver, + GUI_DATA_EX_DRAWABLE_CHANGED, + (void*)obj->vis.d); +} + +void ms_xine_class_init(MSXineClass *klass) +{ + int i; + + ms_filter_class_init(MS_FILTER_CLASS(klass)); + MS_FILTER_CLASS(klass)->max_qinputs=1; + MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_xine_destroy; + /* read xine config file */ + klass->config=config_file_init(NULL); + if (klass->config==NULL){ + g_error("Could not read xine config file"); + } + /* list available video output plugins */ + klass->video_plugins=xine_list_video_output_plugins(VISUAL_TYPE_X11); + g_message("Xine video plugins for X11 are:"); + i=0; + while (klass->video_plugins[i]!=NULL) + { + g_message("\t- %s",klass->video_plugins[i]); + i++; + } + +} + +MSFilter * ms_xine_new() +{ + MSXine *obj=g_malloc(sizeof(MSXine)); + + if (ms_xine_class==NULL) + { + ms_xine_class=g_malloc(sizeof(MSXineClass)); + ms_xine_class_init(ms_xine_class); + } + MS_FILTER(obj)->klass=MS_FILTER_CLASS(ms_xine_class); + ms_xine_init(obj); + return MS_FILTER(obj); +} + +void ms_xine_start(MSXine *obj) +{ + xine_play(obj->engine, + "file://cdrom/Videos/(smr)shrek-ts(1of2).avi", + 0,0); +} + +void ms_xine_uninit(MSXine *obj) +{ + xine_exit(obj->engine); + free(obj->vo_driver); + XDestroyWindow(obj->vis.display,obj->vis.d); +} + +void ms_xine_stop(MSXine *obj) +{ + xine_stop(obj->engine); +} + + +void ms_xine_destroy(MSXine *obj) +{ + ms_xine_uninit(obj); + g_free(obj); +} + diff --git a/linphone/mediastreamer/msxine.h b/linphone/mediastreamer/msxine.h new file mode 100644 index 000000000..dd897bb57 --- /dev/null +++ b/linphone/mediastreamer/msxine.h @@ -0,0 +1,69 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MSXINE_H +#define MSXINE_H + + +#include "ms.h" +#include "msfilter.h" + +#include +#include +#include + +struct _MSXine +{ + MSFilter parent; + MSQueue *input[1]; + x11_visual_t vis; + vo_driver_t *vo_driver; + xine_t *engine; +}; + + +typedef struct _MSXine MSXine; + +struct _MSXineClass +{ + MSFilterClass parent_class; + config_values_t *config; + char **video_plugins; + +}; + +typedef struct _MSXineClass MSXineClass; + + +#define MS_XINE(obj) ((MSXine*)(obj)) +#define MS_XINE_CLASS(klass) ((MSXineClass*)(klass)) + +void ms_xine_init(MSXine *obj); +void ms_xine_class_init(MSXineClass *klass); +void ms_xine_uninit(MSXine *obj); + +MSFilter * ms_xine_new(); +void ms_xine_start(MSXine *obj); +void ms_xine_stop(MSXine *obj); + + +void ms_xine_destroy(MSXine *obj); + +#endif \ No newline at end of file diff --git a/linphone/mediastreamer/osscard.c b/linphone/mediastreamer/osscard.c new file mode 100644 index 000000000..c0cb7a53b --- /dev/null +++ b/linphone/mediastreamer/osscard.c @@ -0,0 +1,498 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "osscard.h" + +#include "msossread.h" +#include "msosswrite.h" + +#ifdef HAVE_SYS_SOUNDCARD_H +#include + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#if 0 +void * oss_thread(OssCard *obj) +{ + gint i; + gint err; + g_message("oss_thread: starting **********"); + while(1){ + for(i=0;ilock); + if (obj->ref==0){ + g_cond_signal(obj->cond); + g_mutex_unlock(obj->lock); + g_thread_exit(NULL); + } + g_mutex_unlock(obj->lock); + obj->readindex=i; + + err=read(obj->fd,obj->readbuf[i],SND_CARD(obj)->bsize); + if (err<0) g_warning("oss_thread: read() error:%s.",strerror(errno)); + obj->writeindex=i; + write(obj->fd,obj->writebuf[i],SND_CARD(obj)->bsize); + memset(obj->writebuf[i],0,SND_CARD(obj)->bsize); + } + } +} +#endif +int oss_open(OssCard *obj, int bits,int stereo, int rate) +{ + int fd; + int p=0,cond=0; + int i=0; + int min_size=0,blocksize=512; + int err; + + //g_message("opening sound device"); + fd=open(obj->dev_name,O_RDWR|O_NONBLOCK); + if (fd<0) return -EWOULDBLOCK; + /* unset nonblocking mode */ + /* We wanted non blocking open but now put it back to normal ; thanks Xine !*/ + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK); + + /* reset is maybe not needed but takes time*/ + /*ioctl(fd, SNDCTL_DSP_RESET, 0); */ + + +#ifdef WORDS_BIGENDIAN + p=AFMT_U16_BE; +#else + p=AFMT_U16_LE; +#endif + + err=ioctl(fd,SNDCTL_DSP_SETFMT,&p); + if (err<0){ + g_warning("oss_open: can't set sample format:%s.",strerror(errno)); + } + + + p = bits; /* 16 bits */ + err=ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &p); + if (err<0){ + g_warning("oss_open: can't set sample size to %i:%s.",bits,strerror(errno)); + } + + p = rate; /* rate in khz*/ + err=ioctl(fd, SNDCTL_DSP_SPEED, &p); + if (err<0){ + g_warning("oss_open: can't set sample rate to %i:%s.",rate,strerror(errno)); + } + + p = stereo; /* stereo or not */ + err=ioctl(fd, SNDCTL_DSP_STEREO, &p); + if (err<0){ + g_warning("oss_open: can't set mono/stereo mode:%s.",strerror(errno)); + } + + if (rate==16000) blocksize=4096; /* oss emulation is not very good at 16khz */ + else blocksize=blocksize*(rate/8000); + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + + /* try to subdivide BLKSIZE to reach blocksize if necessary */ + if (min_size>blocksize) + { + cond=1; + p=min_size/blocksize; + while(cond) + { + i=ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &p); + //printf("SUB_DIVIDE said error=%i,errno=%i\n",i,errno); + if ((i==0) || (p==1)) cond=0; + else p=p/2; + } + } + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + if (min_size>blocksize) + { + g_warning("dsp block size set to %i.",min_size); + }else{ + /* no need to access the card with less latency than needed*/ + min_size=blocksize; + } + + g_message("dsp blocksize is %i.",min_size); + + /* start recording !!! Alex */ + { + int fl,res; + + fl=PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT; + res=ioctl(fd, SNDCTL_DSP_SETTRIGGER, &fl); + if (res<0) g_warning("OSS_TRIGGER: %s",strerror(errno)); + } + + obj->fd=fd; + obj->readpos=0; + obj->writepos=0; + SND_CARD(obj)->bits=bits; + SND_CARD(obj)->stereo=stereo; + SND_CARD(obj)->rate=rate; + SND_CARD(obj)->bsize=min_size; + return fd; +} + +int oss_card_probe(OssCard *obj,int bits,int stereo,int rate) +{ + + int fd; + int p=0,cond=0; + int i=0; + int min_size=0,blocksize=512; + + if (obj->fd>0) return SND_CARD(obj)->bsize; + fd=open(obj->dev_name,O_RDWR|O_NONBLOCK); + if (fd<0) { + g_warning("oss_card_probe: can't open %s: %s.",obj->dev_name,strerror(errno)); + return -1; + } + ioctl(fd, SNDCTL_DSP_RESET, 0); + + p = bits; /* 16 bits */ + ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &p); + + p = stereo; /* number of channels */ + ioctl(fd, SNDCTL_DSP_CHANNELS, &p); + + p = rate; /* rate in khz*/ + ioctl(fd, SNDCTL_DSP_SPEED, &p); + + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + + /* try to subdivide BLKSIZE to reach blocksize if necessary */ + if (min_size>blocksize) + { + cond=1; + p=min_size/blocksize; + while(cond) + { + i=ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &p); + //printf("SUB_DIVIDE said error=%i,errno=%i\n",i,errno); + if ((i==0) || (p==1)) cond=0; + else p=p/2; + } + } + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + if (min_size>blocksize) + { + g_warning("dsp block size set to %i.",min_size); + }else{ + /* no need to access the card with less latency than needed*/ + min_size=blocksize; + } + close(fd); + return min_size; +} + + +int oss_card_open(OssCard *obj,int bits,int stereo,int rate) +{ + int fd; + obj->ref++; + if (obj->fd==0){ + fd=oss_open(obj,bits,stereo,rate); + if (fd<0) { + obj->fd=0; + obj->ref--; + return -1; + } + } + + obj->readbuf=g_malloc0(SND_CARD(obj)->bsize); + obj->writebuf=g_malloc0(SND_CARD(obj)->bsize); + + SND_CARD(obj)->flags|=SND_CARD_FLAGS_OPENED; + return 0; +} + +void oss_card_close(OssCard *obj) +{ + obj->ref--; + if (obj->ref==0) { + close(obj->fd); + obj->fd=0; + SND_CARD(obj)->flags&=~SND_CARD_FLAGS_OPENED; + g_free(obj->readbuf); + obj->readbuf=NULL; + g_free(obj->writebuf); + obj->writebuf=NULL; + + } +} + +void oss_card_destroy(OssCard *obj) +{ + snd_card_uninit(SND_CARD(obj)); + g_free(obj->dev_name); + g_free(obj->mixdev_name); + if (obj->readbuf!=NULL) g_free(obj->readbuf); + if (obj->writebuf!=NULL) g_free(obj->writebuf); +} + +gboolean oss_card_can_read(OssCard *obj) +{ + struct timeval tout={0,0}; + int err; + fd_set fdset; + if (obj->readpos!=0) return TRUE; + FD_ZERO(&fdset); + FD_SET(obj->fd,&fdset); + err=select(obj->fd+1,&fdset,NULL,NULL,&tout); + if (err>0) return TRUE; + else return FALSE; +} + +int oss_card_read(OssCard *obj,char *buf,int size) +{ + int err; + gint bsize=SND_CARD(obj)->bsize; + if (sizereadpos,size); + if (obj->readpos==0){ + err=read(obj->fd,obj->readbuf,bsize); + if (err<0) { + g_warning("oss_card_read: read() failed:%s.",strerror(errno)); + return -1; + } + } + + memcpy(buf,&obj->readbuf[obj->readpos],canread); + obj->readpos+=canread; + if (obj->readpos>=bsize) obj->readpos=0; + return canread; + }else{ + err=read(obj->fd,buf,size); + if (err<0) { + g_warning("oss_card_read: read-2() failed:%s.",strerror(errno)); + } + return err; + } + +} + +int oss_card_write(OssCard *obj,char *buf,int size) +{ + int err; + gint bsize=SND_CARD(obj)->bsize; + + if (sizewritepos,size); + memcpy(&obj->writebuf[obj->writepos],buf,canwrite); + obj->writepos+=canwrite; + if (obj->writepos>=bsize){ + err=write(obj->fd,obj->writebuf,bsize); + obj->writepos=0; + } + return canwrite; + }else{ + return write(obj->fd,buf,bsize); + } +} + +void oss_card_set_level(OssCard *obj,gint way,gint a) +{ + int p,mix_fd; + int osscmd; + g_return_if_fail(obj->mixdev_name!=NULL); +#ifdef HAVE_SYS_SOUNDCARD_H + switch(way){ + case SND_CARD_LEVEL_GENERAL: + osscmd=SOUND_MIXER_VOLUME; + break; + case SND_CARD_LEVEL_INPUT: + osscmd=SOUND_MIXER_IGAIN; + break; + case SND_CARD_LEVEL_OUTPUT: + osscmd=SOUND_MIXER_PCM; + break; + default: + g_warning("oss_card_set_level: unsupported command."); + return; + } + p=(((int)a)<<8 | (int)a); + mix_fd = open(obj->mixdev_name, O_WRONLY); + ioctl(mix_fd,MIXER_WRITE(osscmd), &p); + close(mix_fd); +#endif +} + +gint oss_card_get_level(OssCard *obj,gint way) +{ + int p=0,mix_fd; + int osscmd; + g_return_val_if_fail(obj->mixdev_name!=NULL,-1); +#ifdef HAVE_SYS_SOUNDCARD_H + switch(way){ + case SND_CARD_LEVEL_GENERAL: + osscmd=SOUND_MIXER_VOLUME; + break; + case SND_CARD_LEVEL_INPUT: + osscmd=SOUND_MIXER_IGAIN; + break; + case SND_CARD_LEVEL_OUTPUT: + osscmd=SOUND_MIXER_PCM; + break; + default: + g_warning("oss_card_get_level: unsupported command."); + return -1; + } + mix_fd = open(obj->mixdev_name, O_RDONLY); + ioctl(mix_fd,MIXER_READ(SOUND_MIXER_VOLUME), &p); + close(mix_fd); +#endif + return p>>8; +} + +void oss_card_set_source(OssCard *obj,int source) +{ + gint p=0; + gint mix_fd; + g_return_if_fail(obj->mixdev_name!=NULL); +#ifdef HAVE_SYS_SOUNDCARD_H + if (source == 'c') + p = 1 << SOUND_MIXER_CD; + if (source == 'l') + p = 1 << SOUND_MIXER_LINE; + if (source == 'm') + p = 1 << SOUND_MIXER_MIC; + + + mix_fd = open(obj->mixdev_name, O_WRONLY); + ioctl(mix_fd, SOUND_MIXER_WRITE_RECSRC, &p); + close(mix_fd); +#endif +} + +MSFilter *oss_card_create_read_filter(OssCard *card) +{ + MSFilter *f=ms_oss_read_new(); + ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index); + return f; +} + +MSFilter *oss_card_create_write_filter(OssCard *card) +{ + MSFilter *f=ms_oss_write_new(); + ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index); + return f; +} + + +SndCard * oss_card_new(char *devname, char *mixdev_name) +{ + OssCard * obj= g_new0(OssCard,1); + SndCard *base= SND_CARD(obj); + snd_card_init(base); + obj->dev_name=g_strdup(devname); + obj->mixdev_name=g_strdup( mixdev_name); +#ifdef HAVE_GLIB + base->card_name=g_strdup_printf("%s (Open Sound System)",devname); +#else + base->card_name=malloc(100); + snprintf(base->card_name, 100, "%s (Open Sound System)",devname); +#endif + base->_probe=(SndCardOpenFunc)oss_card_probe; + base->_open_r=(SndCardOpenFunc)oss_card_open; + base->_open_w=(SndCardOpenFunc)oss_card_open; + base->_can_read=(SndCardPollFunc)oss_card_can_read; + base->_read=(SndCardIOFunc)oss_card_read; + base->_write=(SndCardIOFunc)oss_card_write; + base->_close_r=(SndCardCloseFunc)oss_card_close; + base->_close_w=(SndCardCloseFunc)oss_card_close; + base->_set_rec_source=(SndCardMixerSetRecSourceFunc)oss_card_set_source; + base->_set_level=(SndCardMixerSetLevelFunc)oss_card_set_level; + base->_get_level=(SndCardMixerGetLevelFunc)oss_card_get_level; + base->_destroy=(SndCardDestroyFunc)oss_card_destroy; + base->_create_read_filter=(SndCardCreateFilterFunc)oss_card_create_read_filter; + base->_create_write_filter=(SndCardCreateFilterFunc)oss_card_create_write_filter; + return base; +} + +#define DSP_NAME "/dev/dsp" +#define MIXER_NAME "/dev/mixer" + +gint oss_card_manager_init(SndCardManager *manager, gint tabindex) +{ + gchar *devname; + gchar *mixername; + gint devindex=0; + gint found=0; + + /* search for /dev/dsp and /dev/mixer */ +#ifdef HAVE_GLIB + if (g_file_test(DSP_NAME,G_FILE_TEST_EXISTS)){ + tabindex++; + devindex++; + manager->cards[0]=oss_card_new(DSP_NAME,MIXER_NAME); + manager->cards[0]->index=0; + found++; + g_message("Found /dev/dsp."); + } + for (;tabindexcards[tabindex]=oss_card_new(devname,mixername); + manager->cards[tabindex]->index=tabindex; + tabindex++; + found++; + } + g_free(devname); + g_free(mixername); + } +#else + if (access(DSP_NAME,F_OK)==0){ + tabindex++; + devindex++; + manager->cards[0]=oss_card_new(DSP_NAME,MIXER_NAME); + manager->cards[0]->index=0; + found++; + g_message("Found /dev/dsp."); + } + for (;tabindexcards[tabindex]=oss_card_new(devname,mixername); + manager->cards[tabindex]->index=tabindex; + tabindex++; + found++; + } + g_free(devname); + g_free(mixername); + } +#endif + if (tabindex==0) g_warning("No sound cards found !"); + return found; +} + + +#endif diff --git a/linphone/mediastreamer/osscard.h b/linphone/mediastreamer/osscard.h new file mode 100644 index 000000000..30b96c23c --- /dev/null +++ b/linphone/mediastreamer/osscard.h @@ -0,0 +1,47 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* An implementation of SndCard : the OssCard */ + +#ifndef OSS_CARD_H +#define OSS_CARD_H + +#include "sndcard.h" + +#define OSS_CARD_BUFFERS 3 +struct _OssCard +{ + SndCard parent; + gchar *dev_name; /* /dev/dsp0 for example */ + gchar *mixdev_name; /* /dev/mixer0 for example */ + gint fd; /* the file descriptor of the open soundcard, 0 if not open*/ + gint ref; + gchar *readbuf; + gint readpos; + gchar *writebuf; + gint writepos; +}; + +typedef struct _OssCard OssCard; + +SndCard * oss_card_new(char *devname, char *mixdev_name); + +typedef OssCard HpuxSndCard; + +#endif diff --git a/linphone/mediastreamer/rfc2429.h b/linphone/mediastreamer/rfc2429.h new file mode 100644 index 000000000..1dee9c43e --- /dev/null +++ b/linphone/mediastreamer/rfc2429.h @@ -0,0 +1,46 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef rfc2429_h +#define rfc2429_h + +#define MAKE_MASK(bits) ( (1<<(bits)) -1 ) + +static inline unsigned int rfc2429_get_P(const char *header){ + return (header[0]>>2) & 0x1; +} + +static inline unsigned int rfc2429_get_V(const char *header){ + return (header[0]>>1) & 0x1; +} + +static inline unsigned int rfc2429_get_PLEN(const char *header){ + unsigned short *p=(unsigned short*)header; + return (ntohs(p[0])>>3) & MAKE_MASK(6); +} + +static inline unsigned int rfc2429_get_PEBIT(const char *header){ + unsigned short *p=(unsigned short*)header; + return ntohs(p[0]) & MAKE_MASK(3); +} + + +#endif diff --git a/linphone/mediastreamer/ring_test.c b/linphone/mediastreamer/ring_test.c new file mode 100644 index 000000000..3d8293e11 --- /dev/null +++ b/linphone/mediastreamer/ring_test.c @@ -0,0 +1,63 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msringplayer.h" +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include + + +#define READFILE "../share/rings/orig.wav" +#define WRITEFILE "/tmp/mediaout" + +int main() +{ + MSFilter *play,*copy,*rec; + MSSync *timer; + int i=0; + SndCard *card; + ms_init(); + + card=snd_card_manager_get_card(snd_card_manager,2); + play=ms_ring_player_new(READFILE,2); + //play=ms_oss_read_new(0); + rec=snd_card_create_write_filter(card); + copy=ms_copy_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,copy); + ms_filter_add_link(copy,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + + while(1) + { + ms_sound_write_set_level(MS_SOUND_WRITE(rec),i); + i+=10; + sleep(1); + if (i>100) i=0; + } + return 0; +} diff --git a/linphone/mediastreamer/sndcard.c b/linphone/mediastreamer/sndcard.c new file mode 100644 index 000000000..f438d1510 --- /dev/null +++ b/linphone/mediastreamer/sndcard.c @@ -0,0 +1,209 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "sndcard.h" +#include "msfilter.h" + +void snd_card_init(SndCard *obj) +{ + memset(obj,0,sizeof(SndCard)); +} + +void snd_card_uninit(SndCard *obj) +{ + if (obj->card_name!=NULL) g_free(obj->card_name); +} + +const gchar *snd_card_get_identifier(SndCard *obj) +{ + return obj->card_name; +} + +int snd_card_open_r(SndCard *obj, int bits, int stereo, int rate) +{ + g_return_val_if_fail(obj->_open_r!=NULL,-1); + g_message("Opening sound card [%s] in capture mode with stereo=%i,rate=%i,bits=%i",obj->card_name,stereo,rate,bits); + return obj->_open_r(obj,bits,stereo,rate); +} +int snd_card_open_w(SndCard *obj, int bits, int stereo, int rate) +{ + g_return_val_if_fail(obj->_open_w!=NULL,-1); + g_message("Opening sound card [%s] in playback mode with stereo=%i,rate=%i,bits=%i",obj->card_name,stereo,rate,bits); + return obj->_open_w(obj,bits,stereo,rate); +} + +gboolean snd_card_can_read(SndCard *obj){ + g_return_val_if_fail(obj->_can_read!=NULL,-1); + return obj->_can_read(obj); +} + +void snd_card_set_blocking_mode(SndCard *obj,gboolean yesno){ + g_return_if_fail(obj->_set_blocking_mode!=NULL); + obj->_set_blocking_mode(obj,yesno); +} + +int snd_card_read(SndCard *obj,char *buffer,int size) +{ + g_return_val_if_fail(obj->_read!=NULL,-1); + return obj->_read(obj,buffer,size); +} +int snd_card_write(SndCard *obj,char *buffer,int size) +{ + g_return_val_if_fail(obj->_write!=NULL,-1); + return obj->_write(obj,buffer,size); +} + +int snd_card_get_bsize(SndCard *obj) +{ + if (obj->flags & SND_CARD_FLAGS_OPENED){ + return obj->bsize; + } + return -1; +} + +void snd_card_close_r(SndCard *obj) +{ + g_return_if_fail(obj->_close_r!=NULL); + g_message("Closing reading channel of soundcard."); + obj->_close_r(obj); +} + +void snd_card_close_w(SndCard *obj) +{ + g_return_if_fail(obj->_close_w!=NULL); + g_message("Closing writing channel of soundcard."); + obj->_close_w(obj); +} + +gint snd_card_probe(SndCard *obj,int bits, int stereo, int rate) +{ + g_return_val_if_fail(obj->_probe!=NULL,-1); + return obj->_probe(obj,bits,stereo,rate); +} + +void snd_card_set_rec_source(SndCard *obj, int source) +{ + g_return_if_fail(obj->_set_rec_source!=NULL); + obj->_set_rec_source(obj,source); +} + +void snd_card_set_level(SndCard *obj, int way, int level) +{ + g_return_if_fail(obj->_set_level!=NULL); + obj->_set_level(obj,way,level); +} + +gint snd_card_get_level(SndCard *obj,int way) +{ + g_return_val_if_fail(obj->_get_level!=NULL,-1); + return obj->_get_level(obj,way); +} + + +MSFilter * snd_card_create_read_filter(SndCard *obj) +{ + g_return_val_if_fail(obj->_create_read_filter!=NULL,NULL); + return obj->_create_read_filter(obj); +} +MSFilter * snd_card_create_write_filter(SndCard *obj) +{ + g_return_val_if_fail(obj->_create_write_filter!=NULL,NULL); + return obj->_create_write_filter(obj); +} + + +#ifdef HAVE_SYS_AUDIO_H +gint sys_audio_manager_init(SndCardManager *manager, gint index) +{ + /* this is a quick shortcut, as multiple soundcards on HPUX does not happen + very often... */ + manager->cards[index]=hpux_snd_card_new("/dev/audio","/dev/audio"); + return 1; +} + +#endif + +#include "osscard.h" +#include "alsacard.h" +#include "jackcard.h" + +#ifdef HAVE_SYS_SOUNDCARD_H +/* in osscard.c */ +gint oss_card_manager_init(SndCardManager *manager, gint tabindex); +#endif + +void snd_card_manager_init(SndCardManager *manager) +{ + gint index=0; + gint tmp=0; + memset(manager,0,sizeof(SndCardManager)); + #ifdef HAVE_SYS_SOUNDCARD_H + tmp=oss_card_manager_init(manager,index); + index+=tmp; + if (index>=MAX_SND_CARDS) return; + #endif + #ifdef __ALSA_ENABLED__ + tmp=alsa_card_manager_init(manager,index); + index+=tmp; + if (index>=MAX_SND_CARDS) return; + #endif + #ifdef __JACK_ENABLED__ + tmp=jack_card_manager_init(manager,index); + index+=tmp; + if (index>=MAX_SND_CARDS) return; + #endif + #ifdef HAVE_SYS_AUDIO_H + tmp=sys_audio_manager_init(manager,index); + index+=tmp; + #endif +} + + + + + +SndCard * snd_card_manager_get_card(SndCardManager *manager,int index) +{ + g_return_val_if_fail(index>=0,NULL); + g_return_val_if_fail(indexMAX_SND_CARDS) return NULL; + return manager->cards[index]; +} + +SndCard * snd_card_manager_get_card_with_string(SndCardManager *manager,const char *cardname,int *index) +{ + int i; + for (i=0;icards[i]==NULL) continue; + card_name=manager->cards[i]->card_name; + if (card_name==NULL) continue; + if (strcmp(card_name,cardname)==0){ + *index=i; + return manager->cards[i]; + } + } + g_warning("No card %s found.",cardname); + return NULL; +} + +SndCardManager _snd_card_manager; +SndCardManager *snd_card_manager=&_snd_card_manager; diff --git a/linphone/mediastreamer/sndcard.h b/linphone/mediastreamer/sndcard.h new file mode 100644 index 000000000..7441b5707 --- /dev/null +++ b/linphone/mediastreamer/sndcard.h @@ -0,0 +1,145 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + + +#ifndef SNDCARD_H +#define SNDCARD_H + +#undef PACKAGE +#undef VERSION +#ifdef HAVE_CONFIG_H +# include +#endif +#undef PACKAGE +#undef VERSION + +#ifdef HAVE_GLIB +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* the base class for all soundcards: SndCard */ +struct _SndCard; + +typedef int (*SndCardOpenFunc)(struct _SndCard*,int, int, int); +typedef void (*SndCardSetBlockingModeFunc)(struct _SndCard*, gboolean ); +typedef void (*SndCardCloseFunc)(struct _SndCard*); +typedef gint (*SndCardIOFunc)(struct _SndCard*,char *,int); +typedef void (*SndCardDestroyFunc)(struct _SndCard*); +typedef gboolean (*SndCardPollFunc)(struct _SndCard*); +typedef gint (*SndCardMixerGetLevelFunc)(struct _SndCard*,gint); +typedef void (*SndCardMixerSetRecSourceFunc)(struct _SndCard*,gint); +typedef void (*SndCardMixerSetLevelFunc)(struct _SndCard*,gint ,gint); +typedef struct _MSFilter * (*SndCardCreateFilterFunc)(struct _SndCard *); + +struct _SndCard +{ + gchar *card_name; /* SB16 PCI for example */ + gint index; + gint bsize; + gint rate; + gint stereo; + gint bits; + gint flags; +#define SND_CARD_FLAGS_OPENED 1 + SndCardOpenFunc _probe; + SndCardOpenFunc _open_r; + SndCardOpenFunc _open_w; + SndCardSetBlockingModeFunc _set_blocking_mode; + SndCardPollFunc _can_read; + SndCardIOFunc _read; + SndCardIOFunc _write; + SndCardCloseFunc _close_r; + SndCardCloseFunc _close_w; + SndCardMixerGetLevelFunc _get_level; + SndCardMixerSetLevelFunc _set_level; + SndCardMixerSetRecSourceFunc _set_rec_source; + SndCardCreateFilterFunc _create_read_filter; + SndCardCreateFilterFunc _create_write_filter; + SndCardDestroyFunc _destroy; +}; + + +typedef struct _SndCard SndCard; + +void snd_card_init(SndCard *obj); +void snd_card_uninit(SndCard *obj); +gint snd_card_probe(SndCard *obj, int bits, int stereo, int rate); +int snd_card_open_r(SndCard *obj, int bits, int stereo, int rate); +int snd_card_open_w(SndCard *obj, int bits, int stereo, int rate); +int snd_card_get_bsize(SndCard *obj); +gboolean snd_card_can_read(SndCard *obj); +int snd_card_read(SndCard *obj,char *buffer,int size); +int snd_card_write(SndCard *obj,char *buffer,int size); +void snd_card_set_blocking_mode(SndCard *obj,gboolean yesno); +void snd_card_close_r(SndCard *obj); +void snd_card_close_w(SndCard *obj); + +void snd_card_set_rec_source(SndCard *obj, int source); /* source='l' or 'm'*/ +void snd_card_set_level(SndCard *obj, int way, int level); +gint snd_card_get_level(SndCard *obj,int way); + +const gchar *snd_card_get_identifier(SndCard *obj); + +struct _MSFilter * snd_card_create_read_filter(SndCard *sndcard); +struct _MSFilter * snd_card_create_write_filter(SndCard *sndcard); + + +#define SND_CARD_LEVEL_GENERAL 1 +#define SND_CARD_LEVEL_INPUT 2 +#define SND_CARD_LEVEL_OUTPUT 3 + + +int snd_card_destroy(SndCard *obj); + +#define SND_CARD(obj) ((SndCard*)(obj)) + + + + +/* SndCardManager */ + +#define MAX_SND_CARDS 20 + + +struct _SndCardManager +{ + SndCard *cards[MAX_SND_CARDS]; +}; + +typedef struct _SndCardManager SndCardManager; + +void snd_card_manager_init(SndCardManager *manager); +SndCard * snd_card_manager_get_card(SndCardManager *manager,int index); +SndCard * snd_card_manager_get_card_with_string(SndCardManager *manager,const char *cardname,int *index); + +extern SndCardManager *snd_card_manager; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/mediastreamer/test.c b/linphone/mediastreamer/test.c new file mode 100644 index 000000000..a24c3f4dd --- /dev/null +++ b/linphone/mediastreamer/test.c @@ -0,0 +1,91 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msringplayer.h" +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include +#include + +#define READFILE "../share/rings/orig.wav" +#define WRITEFILE "/tmp/mediaout" + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + + +int main(int argc, char *argv[]) +{ + MSFilter *play,*copy,*rec; + MSSync *timer; + int i=0; + int tmp; + char *ring; + + ms_init(); + + if (argc>1){ + ring=argv[1]; + }else ring= READFILE; + + play=ms_ring_player_new(ring,2); + //play=ms_oss_read_new(0); + rec=snd_card_create_write_filter(snd_card_manager_get_card(snd_card_manager,1)); + copy=ms_copy_new(); + + ms_filter_get_property(play,MS_FILTER_PROPERTY_FREQ,&tmp); + g_message("Playing at rate %i.",tmp); + ms_filter_set_property(rec,MS_FILTER_PROPERTY_FREQ,&tmp); + ms_filter_get_property(play,MS_FILTER_PROPERTY_CHANNELS,&tmp); + g_message("Playing with %i channels",tmp); + ms_filter_set_property(rec,MS_FILTER_PROPERTY_CHANNELS,&tmp); + + timer=ms_timer_new(); + ms_sync_start(timer); + + ms_filter_add_link(play,copy); + ms_filter_add_link(copy,rec); + ms_sync_attach(timer,play); + + + while(cond) + { + sleep(1); + } + ms_sync_detach(timer,play); + ms_sync_stop(timer); + ms_sync_destroy(timer); + + ms_filter_remove_links(play,copy); + ms_filter_remove_links(copy,rec); + ms_filter_destroy(play); + ms_filter_destroy(copy); + ms_filter_destroy(rec); + + return 0; +} diff --git a/linphone/mediastreamer/test_alaw.c b/linphone/mediastreamer/test_alaw.c new file mode 100644 index 000000000..243ceca8c --- /dev/null +++ b/linphone/mediastreamer/test_alaw.c @@ -0,0 +1,90 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include "msAlawdec.h" +#include "msAlawenc.h" + +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_oss_read_new(); + rec=ms_oss_write_new(); + + ms_sound_read_set_device(MS_SOUND_READ(play),0); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + + enc=ms_ALAWencoder_new(); + dec=ms_ALAWdecoder_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + + ms_sound_read_start(MS_SOUND_READ(play)); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + while(cond) + { + sleep(1); + } + + ms_sound_read_stop(MS_SOUND_READ(play)); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(enc); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_gsm.c b/linphone/mediastreamer/test_gsm.c new file mode 100644 index 000000000..1e2350b15 --- /dev/null +++ b/linphone/mediastreamer/test_gsm.c @@ -0,0 +1,85 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include "msGSMdecoder.h" +#include "msGSMencoder.h" + +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_oss_read_new(); + rec=ms_oss_write_new(); + ms_sound_read_set_device(MS_SOUND_READ(play),0); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + + enc=ms_GSMencoder_new(); + dec=ms_GSMdecoder_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + ms_sound_read_start(MS_SOUND_READ(play)); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + while(cond) + { + sleep(1); + } + ms_sound_read_stop(MS_SOUND_READ(play)); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(enc); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_lpc10.c b/linphone/mediastreamer/test_lpc10.c new file mode 100644 index 000000000..bb39f9df3 --- /dev/null +++ b/linphone/mediastreamer/test_lpc10.c @@ -0,0 +1,89 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include "msLPC10decoder.h" +#include "msLPC10encoder.h" + +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_oss_read_new(); + rec=ms_oss_write_new(); + + ms_sound_read_set_device(MS_SOUND_READ(play),0); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + + enc=ms_LPC10encoder_new(); + dec=ms_LPC10decoder_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + ms_sound_read_start(MS_SOUND_READ(play)); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + + while(cond) + { + sleep(1); + } + ms_sound_read_stop(MS_SOUND_READ(play)); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(enc); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_mulaw.c b/linphone/mediastreamer/test_mulaw.c new file mode 100644 index 000000000..9962e8601 --- /dev/null +++ b/linphone/mediastreamer/test_mulaw.c @@ -0,0 +1,87 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "msnosync.h" +#include "mstimer.h" +#include "msMUlawdec.h" +#include "msMUlawenc.h" + +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_oss_read_new(); + rec=ms_oss_write_new(); + ms_sound_read_set_device(MS_SOUND_READ(play),0); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + + enc=ms_MULAWencoder_new(); + dec=ms_MULAWdecoder_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + ms_sound_read_start(MS_SOUND_READ(play)); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + while(cond) + { + sleep(1); + } + ms_sound_read_stop(MS_SOUND_READ(play)); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(enc); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_rtprecv.c b/linphone/mediastreamer/test_rtprecv.c new file mode 100644 index 000000000..d6ba66513 --- /dev/null +++ b/linphone/mediastreamer/test_rtprecv.c @@ -0,0 +1,99 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "msrtprecv.h" +#include "ms.h" +#include "mswrite.h" +#include "msosswrite.h" +#include "msMUlawdec.h" +#include "mstimer.h" +#include "msfdispatcher.h" + +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*dec,*rec,*filerec,*dis; + MSSync *timer; + RtpSession *rtps; + + /*create the rtp session */ + ortp_init(); + rtps=rtp_session_new(RTP_SESSION_RECVONLY); + rtp_session_set_local_addr(rtps,"0.0.0.0",8000); + rtp_session_set_scheduling_mode(rtps,0); + rtp_session_set_blocking_mode(rtps,0); + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_rtp_recv_new(); + rec=ms_oss_write_new(); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + dec=ms_MULAWdecoder_new(); + filerec=ms_write_new("/tmp/rtpstream"); + dis=ms_fdispatcher_new(); + timer=ms_timer_new(); + + ms_rtp_recv_set_session(MS_RTP_RECV(play),rtps); + + ms_filter_add_link(play,dec); + ms_filter_add_link(dec,dis); + ms_filter_add_link(dis,rec); + ms_filter_add_link(dis,filerec); + ms_sync_attach(timer,play); + printf("gran=%i\n",MS_SYNC(timer)->samples_per_tick); + + ms_start(timer); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + while(cond) + { + sleep(1); + } + + printf("stoping sync...\n"); + ms_stop(timer); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_filter_destroy(dis); + ms_filter_destroy(filerec); + + rtp_session_destroy(rtps); + ms_sync_destroy(timer); + ortp_global_stats_display(); + + return 0; +} diff --git a/linphone/mediastreamer/test_smpeg.c b/linphone/mediastreamer/test_smpeg.c new file mode 100644 index 000000000..a1e2c436e --- /dev/null +++ b/linphone/mediastreamer/test_smpeg.c @@ -0,0 +1,70 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "ms.h" +#include "msfilter.h" +#include "mssmpeg.h" +#include +#include +#include +#include "mstimer.h" +#include "msread.h" + +int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *source; + MSFilter *smpeg_filter; + MSSync *timer; + + timer=ms_timer_new(); + ms_timer_set_interval(MS_TIMER(timer),100); + + smpeg_filter=ms_smpeg_new(); + source=ms_read_new("/cdrom/Videos/Queen - Bohemian Rhapsody.mpg"); + ms_filter_add_link(source,smpeg_filter); + ms_sync_attach(timer,source); + signal(SIGINT,stop_handler); + + ms_start(timer); + ms_smpeg_start(MS_SMPEG(smpeg_filter)); + while (cond){ + sleep (1); + } + g_message("Exiting..."); + ms_smpeg_stop(MS_SMPEG(smpeg_filter)); + ms_stop(timer); + ms_sync_detach(timer,source); + ms_filter_remove_links(source,smpeg_filter); + ms_sync_destroy(timer); + ms_filter_destroy(smpeg_filter); + ms_filter_destroy(source); + g_message("End of test program."); + return 0; +} + + diff --git a/linphone/mediastreamer/test_speex.c b/linphone/mediastreamer/test_speex.c new file mode 100644 index 000000000..06726104c --- /dev/null +++ b/linphone/mediastreamer/test_speex.c @@ -0,0 +1,88 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "sndcard.h" +#include "mscopy.h" +#include "mstimer.h" +#include "msspeexdec.h" +#include "msspeexenc.h" + +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + SndCard *card; + int rate=16000; + + ms_init(); + signal(SIGINT,stop_handler); + /* get the first card */ + card=snd_card_manager_get_card(snd_card_manager,0); + if (card==NULL) g_error("No sound card detected."); + + play=snd_card_create_read_filter(card); + rec=snd_card_create_write_filter(card); + + enc=ms_speex_enc_new(); + dec=ms_speex_dec_new(); + + ms_filter_set_property(play,MS_FILTER_PROPERTY_FREQ,&rate); + ms_filter_set_property(rec,MS_FILTER_PROPERTY_FREQ,&rate); + ms_filter_set_property(enc,MS_FILTER_PROPERTY_FREQ,&rate); + ms_filter_set_property(dec,MS_FILTER_PROPERTY_FREQ,&rate); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + while(cond) + { + sleep(1); + } + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(enc); + ms_filter_destroy(dec); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_truespeech.c b/linphone/mediastreamer/test_truespeech.c new file mode 100644 index 000000000..4e734fac4 --- /dev/null +++ b/linphone/mediastreamer/test_truespeech.c @@ -0,0 +1,91 @@ + /* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ms.h" + +#include "msosswrite.h" +#include "msossread.h" +#include "mscopy.h" +#include "mstimer.h" +#include "mstruespeechdecoder.h" +#include "mstruespeechencoder.h" + +#include +#include +#include +#include + +static int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + + +int main() +{ + MSFilter *play,*enc,*dec,*rec; + MSSync *timer; + + ms_init(); + signal(SIGINT,stop_handler); + + play=ms_oss_read_new(); + rec=ms_oss_write_new(); + + ms_sound_read_set_device(MS_SOUND_READ(play),0); + ms_sound_write_set_device(MS_SOUND_WRITE(rec),0); + + enc=ms_truespeechencoder_new(); + dec=ms_truespeechdecoder_new(); + timer=ms_timer_new(); + + ms_filter_add_link(play,enc); + ms_filter_add_link(enc,dec); + ms_filter_add_link(dec,rec); + ms_sync_attach(timer,play); + + ms_start(timer); + + ms_sound_read_start(MS_SOUND_READ(play)); + ms_sound_write_start(MS_SOUND_WRITE(rec)); + while(cond) + { + sleep(1); + } + + ms_sound_read_stop(MS_SOUND_READ(play)); + ms_sound_write_stop(MS_SOUND_WRITE(rec)); + + printf("stoping sync...\n"); + ms_stop(timer); + printf("unlinking filters...\n"); + ms_filter_remove_links(play,enc); + ms_filter_remove_links(enc,dec); + ms_filter_remove_links(dec,rec); + printf("destroying filters...\n"); + ms_filter_destroy(play); + ms_filter_destroy(dec); + ms_filter_destroy(enc); + ms_filter_destroy(rec); + ms_sync_destroy(timer); + return 0; +} diff --git a/linphone/mediastreamer/test_v4l.c b/linphone/mediastreamer/test_v4l.c new file mode 100644 index 000000000..9b51e82fb --- /dev/null +++ b/linphone/mediastreamer/test_v4l.c @@ -0,0 +1,32 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mediastream.h" + + +int main() +{ + VideoStream *v; + ms_init(); + v=video_preview_start("Video4Linux","/dev/video0"); + sleep(15); + video_preview_stop(v); + return 0; +} diff --git a/linphone/mediastreamer/test_videostream.c b/linphone/mediastreamer/test_videostream.c new file mode 100644 index 000000000..1289971ad --- /dev/null +++ b/linphone/mediastreamer/test_videostream.c @@ -0,0 +1,45 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mediastream.h" +#include + +static gboolean cond=TRUE; + +static void stop_handler(int signum){ + cond=FALSE; +} + +int main() +{ + VideoStream *v; + ortp_init(); + rtp_profile_set_payload(&av_profile,98,&payload_type_h263_1998); + ms_init(); + signal(SIGINT,stop_handler); + v=video_stream_start(&av_profile,6000,"127.0.0.1",6000, 98, 60, TRUE, "Video4Linux","/dev/video0"); + while(cond) { + ortp_global_stats_display(); + sleep(1); + } + video_stream_stop(v); + ortp_exit(); + return 0; +} diff --git a/linphone/mediastreamer/test_xine.c b/linphone/mediastreamer/test_xine.c new file mode 100644 index 000000000..1eb7bc3dc --- /dev/null +++ b/linphone/mediastreamer/test_xine.c @@ -0,0 +1,45 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "ms.h" +#include "msfilter.h" +#include "msxine.h" +#include + + + +int main() +{ + MSFilter *xinefilter1,*xinefilter2; + + xinefilter1=ms_xine_new(); + //xinefilter2=ms_xine_new(); + //sleep(10); + ms_xine_start(MS_XINE(xinefilter1)); + sleep(15); + ms_xine_stop(MS_XINE(xinefilter1)); + ms_filter_destroy(xinefilter1); + //ms_filter_destroy(xinefilter2); + g_message("End of test program."); + return 0; +} + + diff --git a/linphone/mediastreamer/videoclient.c b/linphone/mediastreamer/videoclient.c new file mode 100644 index 000000000..3f24b86e2 --- /dev/null +++ b/linphone/mediastreamer/videoclient.c @@ -0,0 +1,60 @@ +#include "ms.h" +#include "msavdecoder.h" +#include "mstcpclient.h" +#include "mssdlout.h" +#include "mstimer.h" +#include + + +static gboolean running=TRUE; + +static void sighandler(int signum){ + running=FALSE; +} + +int main(int argc, char *argv[]){ + MSFilter *source,*decoder,*output; + MSSync *sync; + + if (argc<3){ + fprintf(stderr,"videoclient \n"); + return -1; + } + + signal(SIGINT,sighandler); + + ms_init(); + + source=ms_tcp_client_new(); + ms_tcp_client_connect(MS_TCP_CLIENT(source),argv[1],atoi(argv[2])); + + decoder=ms_h263_decoder_new(); + ms_AVdecoder_set_format(MS_AVDECODER(decoder),"YUV420P"); + + output=ms_sdl_out_new(); + ms_sdl_out_set_format(MS_SDL_OUT(output),"YUV420P"); + + ms_filter_add_link(source,decoder); + ms_filter_add_link(decoder,output); + + sync=ms_timer_new(); + + ms_sync_attach(sync,source); + + ms_start(sync); + + while(running) sleep(1); + + ms_stop(sync); + + ms_sync_detach(sync,source); + + ms_filter_remove_links(source,decoder); + ms_filter_remove_links(decoder,output); + + ms_filter_destroy(source); + ms_filter_destroy(decoder); + ms_filter_destroy(output); + return 0; +} + diff --git a/linphone/mediastreamer/videoserver.c b/linphone/mediastreamer/videoserver.c new file mode 100644 index 000000000..dc2070e9c --- /dev/null +++ b/linphone/mediastreamer/videoserver.c @@ -0,0 +1,56 @@ +#include "ms.h" +#include "msv4l.h" +#include "msavencoder.h" +#include "mstcpserv.h" +#include "mstimer.h" +#include + + +static gboolean running=TRUE; + +static void sighandler(int signum){ + running=FALSE; +} + +int main(int arg, char *argv[]){ + MSFilter *source,*encoder,*sender; + MSSync *sync; + + signal(SIGINT,sighandler); + + ms_init(); + + source=ms_v4l_new(); + ms_v4l_set_device(MS_V4L(source),"/dev/video0"); + ms_v4l_start(MS_V4L(source)); + + encoder=ms_h263_encoder_new(); + + sender=ms_tcp_serv_new(); + + ms_filter_add_link(source,encoder); + ms_filter_add_link(encoder,sender); + + sync=ms_timer_new(); + + ms_sync_attach(sync,source); + + ms_start(sync); + + while(running) sleep(1); + + ms_stop(sync); + + ms_sync_detach(sync,source); + + ms_v4l_stop(MS_V4L(source)); + + ms_filter_remove_links(source,encoder); + ms_filter_remove_links(encoder,sender); + + ms_filter_destroy(source); + ms_filter_destroy(encoder); + ms_filter_destroy(sender); + return 0; +} + diff --git a/linphone/mediastreamer/videostream.c b/linphone/mediastreamer/videostream.c new file mode 100644 index 000000000..d512b849b --- /dev/null +++ b/linphone/mediastreamer/videostream.c @@ -0,0 +1,346 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "mediastream.h" +#include "msvideosource.h" +#include "msavdecoder.h" +#include "msavencoder.h" +#include "msnosync.h" +#include "mssdlout.h" + +#define USE_SDL + +extern void create_duplex_rtpsession(RtpProfile *profile, int locport,char *remip,int remport, + int payload,int jitt_comp, + RtpSession **recvsend); + +#define MAX_RTP_SIZE UDP_MAX_SIZE + +#ifdef VIDEO_ENABLED + +/* this code is not part of the library itself, it is part of the mediastream program */ +void video_stream_free (VideoStream * stream) +{ + RtpSession *recvs, *sends; + if (stream->rtprecv != NULL) + { + recvs = ms_rtp_recv_get_session (MS_RTP_RECV (stream->rtprecv)); + if (recvs != NULL) + { + rtp_session_destroy (recvs); + } + ms_filter_destroy (stream->rtprecv); + } + if (stream->rtpsend != NULL) + { + sends = ms_rtp_send_get_session (MS_RTP_SEND (stream->rtpsend)); + if (sends != NULL && sends!=recvs) + { + rtp_session_destroy (sends); + } + ms_filter_destroy (stream->rtpsend); + } + if (stream->source != NULL) + ms_filter_destroy (stream->source); + if (stream->output != NULL) + ms_filter_destroy (stream->output); + if (stream->decoder != NULL) + ms_filter_destroy (stream->decoder); + if (stream->encoder != NULL) + ms_filter_destroy (stream->encoder); + if (stream->timer != NULL) + ms_sync_destroy (stream->timer); + g_free (stream); +} + + +VideoStream * +video_stream_start (RtpProfile *profile, int locport, char *remip, int remport, + int payload, int jitt_comp, gboolean show_local, + const gchar *source, const gchar *device) +{ + VideoStream *stream = g_new0 (VideoStream, 1); + RtpSession *rtps, *rtpr; + PayloadType *pt; + gchar *format; + gint width = VIDEO_SIZE_CIF_W; + gint height = VIDEO_SIZE_CIF_H; + float fps; + + create_duplex_rtpsession(profile,locport,remip,remport,payload,jitt_comp,&rtpr); + rtp_session_enable_adaptive_jitter_compensation(rtpr,FALSE); + rtps=rtpr; + ms_trace("sending video to %s:%i", remip4, remport); + + /* creates two rtp filters to recv send streams (remote part) */ + rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE); + stream->rtpsend = ms_rtp_send_new (); + if (remport>0) ms_rtp_send_set_session (MS_RTP_SEND (stream->rtpsend), rtps); + + + stream->rtprecv = ms_rtp_recv_new (); + ms_rtp_recv_set_session (MS_RTP_RECV (stream->rtprecv), rtpr); + + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + g_error("videostream.c: undefined payload type."); + return NULL; + } + ms_trace("videostream.c: getting codecs for %s", pt->mime_type); + + /* creates the filters */ + stream->source = ms_filter_new_with_name(source); + if (stream->source == NULL){ + g_error("videostream.c: failed to create video source %s.", source); + return NULL; + } + +#ifdef USE_SDL + stream->output=ms_sdl_out_new(); +#else + stream->output = MS_FILTER(ms_video_output_new ()); +#endif + stream->encoder=ms_encoder_new_with_string_id(pt->mime_type); + g_message("Video encoder created: %x",stream->encoder); + stream->decoder=ms_decoder_new_with_string_id(pt->mime_type); + if ((stream->encoder==NULL) || (stream->decoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + video_stream_free(stream); + g_error("videostream.c: No codecs available for payload %i.",payload); + return NULL; + } + + /* configure the filters */ + ms_video_source_set_device(MS_VIDEO_SOURCE(stream->source), device); + ms_video_source_set_size(MS_VIDEO_SOURCE(stream->source), width, height); + ms_video_source_set_frame_rate(MS_VIDEO_SOURCE(stream->source), 8, 1); + fps = MS_VIDEO_SOURCE(stream->source)->frame_rate / MS_VIDEO_SOURCE(stream->source)->frame_rate_base; + ms_video_source_start(MS_VIDEO_SOURCE(stream->source)); + format = ms_video_source_get_format(MS_VIDEO_SOURCE(stream->source)); + + ms_AVencoder_set_format (MS_AVENCODER (stream->encoder), format); + ms_AVencoder_set_width(MS_AVENCODER(stream->encoder), width); + ms_AVencoder_set_height(MS_AVENCODER(stream->encoder), height); + /* bitrate is based upon 30fps? adjust by our possibly lower framerate REVISIT later */ + /*ms_AVencoder_set_bit_rate(MS_AVENCODER(stream->encoder), pt->normal_bitrate * 30 / fps );*/ + ms_AVdecoder_set_format (MS_AVDECODER (stream->decoder), "YUV420P"); + ms_AVdecoder_set_width(MS_AVDECODER(stream->decoder), width); + ms_AVdecoder_set_height(MS_AVDECODER(stream->decoder), height); +#ifdef USE_SDL + /* we suppose our decoder and pin1 of encoder always outputs YUV420P */ + ms_sdl_out_set_format(MS_SDL_OUT(stream->output),"YUV420P"); +#else + ms_video_output_set_size (MS_VIDEO_OUTPUT (stream->output), width, height); +#endif + + /* and then connect all */ + ms_filter_add_link (stream->source, stream->encoder); + ms_filter_add_link (stream->encoder, stream->rtpsend); + + ms_filter_add_link (stream->rtprecv, stream->decoder); + ms_filter_add_link (stream->decoder, stream->output); + if (show_local) + ms_filter_add_link(stream->encoder,stream->output); + + /* create the synchronisation source */ + stream->timer = ms_timer_new(); + ms_sync_attach (stream->timer, stream->source); + ms_sync_attach (stream->timer, stream->rtprecv); + + /* and start */ + ms_start (stream->timer); + stream->show_local=show_local; + return stream; +} + + + +void +video_stream_stop (VideoStream * stream) +{ + + ms_stop (stream->timer); + ms_video_source_stop (MS_VIDEO_SOURCE(stream->source)); + ms_sync_detach (stream->timer, stream->source); + ms_sync_detach (stream->timer, stream->rtprecv); + + ms_filter_remove_links(stream->source,stream->encoder); + ms_filter_remove_links (stream->encoder, + stream->rtpsend); + + ms_filter_remove_links (stream->rtprecv, + stream->decoder); + ms_filter_remove_links (stream->decoder, + stream->output); + if (stream->show_local) { + ms_filter_remove_links (stream->encoder, + stream->output); + } + video_stream_free (stream); +} + + +void video_stream_set_rtcp_information(VideoStream *st, const char *cname){ + if (st->send_session!=NULL){ + rtp_session_set_source_description(st->send_session,cname,NULL,NULL,NULL,NULL,"linphone-" LINPHONE_VERSION, + "This is free software (GPL) !"); + } +} + + + +VideoStream * video_preview_start(const gchar *source, const gchar *device){ + VideoStream *stream = g_new0 (VideoStream, 1); + gchar *format; + gint width = VIDEO_SIZE_CIF_W; + gint height = VIDEO_SIZE_CIF_H; + + /* creates the filters */ + stream->source = ms_filter_new_with_name(source); + if (stream->source == NULL){ + g_error("videostream.c: failed to create video source %s.", source); + return NULL; + } +#ifdef USE_SDL + stream->output=ms_sdl_out_new(); +#else + stream->output = ms_video_output_new (); +#endif + /* configure the filters */ + ms_video_source_set_device(MS_VIDEO_SOURCE(stream->source), device); + ms_video_source_set_size(MS_VIDEO_SOURCE(stream->source), width, height); + ms_video_source_set_frame_rate(MS_VIDEO_SOURCE(stream->source), 8, 1); + + ms_video_source_start(MS_VIDEO_SOURCE(stream->source)); + format = ms_video_source_get_format(MS_VIDEO_SOURCE(stream->source)); + +#ifdef USE_SDL + ms_sdl_out_set_format(MS_SDL_OUT(stream->output),format); +#else + ms_video_output_set_format(MS_VIDEO_OUTPUT(stream->output),format); + ms_video_output_set_size (MS_VIDEO_OUTPUT (stream->output), width, height); + ms_video_output_set_title(MS_VIDEO_OUTPUT(stream->output),"Linphone Video"); +#endif + /* and then connect all */ + ms_filter_add_link (stream->source, stream->output); + /* create the synchronisation source */ + stream->timer = ms_timer_new(); + ms_sync_attach (stream->timer, stream->source); + + /* and start */ + ms_start (stream->timer); + + return stream; +} + +void video_preview_stop(VideoStream *stream){ + ms_stop (stream->timer); + ms_video_source_stop (MS_VIDEO_SOURCE(stream->source)); + ms_sync_detach (stream->timer, stream->source); + ms_filter_remove_links(stream->source,stream->output); + video_stream_free(stream); +} + + +VideoStream * video_stream_send_only_start(RtpProfile *profile, int locport, char *remip, int remport, + int payload, const gchar *source, const gchar *device) +{ + VideoStream *stream = g_new0 (VideoStream, 1); + RtpSession *rtps, *rtpr; + PayloadType *pt; + gchar *format; + gint width = VIDEO_SIZE_CIF_W; + gint height = VIDEO_SIZE_CIF_H; + float fps; + + create_duplex_rtpsession(profile,locport,remip,remport,payload,40,&rtpr); + rtp_session_enable_adaptive_jitter_compensation(rtpr,FALSE); + rtps=rtpr; + ms_trace("sending video to %s:%i", remip4, remport); + + /* creates two rtp filters to recv send streams (remote part) */ + rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE); + stream->rtpsend = ms_rtp_send_new (); + if (remport>0) ms_rtp_send_set_session (MS_RTP_SEND (stream->rtpsend), rtps); + + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + g_error("videostream.c: undefined payload type."); + return NULL; + } + ms_trace("videostream.c: getting codecs for %s", pt->mime_type); + + /* creates the filters */ + stream->source = ms_filter_new_with_name(source); + if (stream->source == NULL){ + g_error("videostream.c: failed to create video source %s.", source); + return NULL; + } + + stream->encoder=ms_encoder_new_with_string_id(pt->mime_type); + g_message("Video encoder created: %x",stream->encoder); + if ((stream->encoder==NULL) ){ + /* big problem: we have not a registered codec for this payload...*/ + video_stream_free(stream); + g_error("videostream.c: No codecs available for payload %i.",payload); + return NULL; + } + + /* configure the filters */ + ms_video_source_set_device(MS_VIDEO_SOURCE(stream->source), device); + ms_video_source_set_size(MS_VIDEO_SOURCE(stream->source), width, height); + ms_video_source_set_frame_rate(MS_VIDEO_SOURCE(stream->source), 8, 1); + fps = MS_VIDEO_SOURCE(stream->source)->frame_rate / MS_VIDEO_SOURCE(stream->source)->frame_rate_base; + ms_video_source_start(MS_VIDEO_SOURCE(stream->source)); + format = ms_video_source_get_format(MS_VIDEO_SOURCE(stream->source)); + + ms_AVencoder_set_format (MS_AVENCODER (stream->encoder), format); + ms_AVencoder_set_width(MS_AVENCODER(stream->encoder), width); + ms_AVencoder_set_height(MS_AVENCODER(stream->encoder), height); + /* bitrate is based upon 30fps? adjust by our possibly lower framerate */ + /*ms_AVencoder_set_bit_rate(MS_AVENCODER(stream->encoder), pt->normal_bitrate * 30 / fps );*/ + + /* and then connect all */ + ms_filter_add_link (stream->source, stream->encoder); + ms_filter_add_link (stream->encoder, stream->rtpsend); + + /* create the synchronisation source */ + stream->timer = ms_timer_new(); + ms_sync_attach (stream->timer, stream->source); + + /* and start */ + ms_start (stream->timer); + return stream; +} + +void video_stream_send_only_stop(VideoStream *stream){ + ms_stop (stream->timer); + ms_video_source_stop (MS_VIDEO_SOURCE(stream->source)); + ms_sync_detach (stream->timer, stream->source); + + ms_filter_remove_links(stream->source,stream->encoder); + ms_filter_remove_links (stream->encoder, + stream->rtpsend); + + video_stream_free(stream); +} + +#endif diff --git a/linphone/mediastreamer/waveheader.h b/linphone/mediastreamer/waveheader.h new file mode 100644 index 000000000..405948d6f --- /dev/null +++ b/linphone/mediastreamer/waveheader.h @@ -0,0 +1,111 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* the following code was taken from a free software utility that I don't remember the name. */ +/* sorry */ + + + +#include "ms.h" +#ifndef waveheader_h +#define waveheader_h + +typedef struct uint16scheme +{ + unsigned char lo_byte; + unsigned char hi_byte; +} uint16scheme_t; + +typedef struct uint32scheme +{ + guint16 lo_int; + guint16 hi_int; +} uint32scheme_t; + + +/* all integer in wav header must be read in least endian order */ +inline guint16 _readuint16(guint16 a) +{ + guint16 res; + uint16scheme_t *tmp1=(uint16scheme_t*)&a; + + ((uint16scheme_t *)(&res))->lo_byte=tmp1->hi_byte; + ((uint16scheme_t *)(&res))->hi_byte=tmp1->lo_byte; + return res; +} + +inline guint32 _readuint32(guint32 a) +{ + guint32 res; + uint32scheme_t *tmp1=(uint32scheme_t*)&a; + + ((uint32scheme_t *)(&res))->lo_int=_readuint16(tmp1->hi_int); + ((uint32scheme_t *)(&res))->hi_int=_readuint16(tmp1->lo_int); + return res; +} + +#ifdef WORDS_BIGENDIAN +#define le_uint32(a) (_readuint32((a))) +#define le_uint16(a) (_readuint16((a))) +#define le_int16(a) ( (gint16) _readuint16((guint16)((a))) ) +#else +#define le_uint32(a) (a) +#define le_uint16(a) (a) +#define le_int16(a) (a) +#endif + +typedef struct _riff_t { + char riff[4] ; /* "RIFF" (ASCII characters) */ + guint32 len ; /* Length of package (binary, little endian) */ + char wave[4] ; /* "WAVE" (ASCII characters) */ +} riff_t; + +/* The FORMAT chunk */ + +typedef struct _format_t { + char fmt[4] ; /* "fmt_" (ASCII characters) */ + guint32 len ; /* length of FORMAT chunk (always 0x10) */ + guint16 que ; /* Always 0x01 */ + guint16 channel ; /* Channel numbers (0x01 = mono, 0x02 = stereo) */ + guint32 rate ; /* Sample rate (binary, in Hz) */ + guint32 bps ; /* Bytes Per Second */ + guint16 bpsmpl ; /* bytes per sample: 1 = 8 bit Mono, + 2 = 8 bit Stereo/16 bit Mono, + 4 = 16 bit Stereo */ + guint16 bitpspl ; /* bits per sample */ +} format_t; + +/* The DATA chunk */ + +typedef struct _data_t { + char data[4] ; /* "data" (ASCII characters) */ + int len ; /* length of data */ +} data_t; + +typedef struct _wave_header_t +{ + riff_t riff_chunk; + format_t format_chunk; + data_t data_chunk; +} wave_header_t; + +#define wave_header_get_rate(header) le_uint32((header)->format_chunk.rate) +#define wave_header_get_channel(header) le_uint16((header)->format_chunk.channel) + +#endif diff --git a/linphone/mediastreamer2/.cvsignore b/linphone/mediastreamer2/.cvsignore new file mode 100644 index 000000000..6be2672d9 --- /dev/null +++ b/linphone/mediastreamer2/.cvsignore @@ -0,0 +1,30 @@ +*.la +*.lo +.deps +.libs +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +install-sh +intltool-extract +intltool-merge +intltool-update +libtool +ltmain.sh +mediastreamer-config.h +mediastreamer-config.h.in +mediastreamer.pc +mediastreamer2.spec +missing +mkinstalldirs +stamp-h1 diff --git a/linphone/mediastreamer2/.indent.pro b/linphone/mediastreamer2/.indent.pro new file mode 100644 index 000000000..0f9555875 --- /dev/null +++ b/linphone/mediastreamer2/.indent.pro @@ -0,0 +1,4 @@ +-kr +--use-tabs +--tab-size4 + diff --git a/linphone/mediastreamer2/AUTHORS b/linphone/mediastreamer2/AUTHORS new file mode 100644 index 000000000..ff6dbf174 --- /dev/null +++ b/linphone/mediastreamer2/AUTHORS @@ -0,0 +1 @@ +Simon MORLAT \ No newline at end of file diff --git a/linphone/mediastreamer2/COPYING b/linphone/mediastreamer2/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/linphone/mediastreamer2/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/linphone/mediastreamer2/ChangeLog b/linphone/mediastreamer2/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/mediastreamer2/INSTALL b/linphone/mediastreamer2/INSTALL new file mode 100644 index 000000000..23e5f25d0 --- /dev/null +++ b/linphone/mediastreamer2/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/linphone/mediastreamer2/Makefile.am b/linphone/mediastreamer2/Makefile.am new file mode 100644 index 000000000..fb246149b --- /dev/null +++ b/linphone/mediastreamer2/Makefile.am @@ -0,0 +1,54 @@ + +EXTRA_DIST=mediastreamer-config.h.in pkg.list autogen.sh mediastreamer.pc.in mediastreamer2.spec.in mediastreamer2.spec Makefile.macosx + +SUBDIRS=src build include tests help + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = mediastreamer.pc + +## oRTP packaging methods: + +# `make rpm' + +.phony: rpm + +rpm: + $(MAKE) dist +# + TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz + +# `make package' + +if WITH_EPM + +.PHONY: package + +PKG_NAME = $(PACKAGE)-$(VERSION)-$(RELEASE) +BUILDROOT=`pwd`/epm-install + +package: $(srcdir)/pkg.list $(srcdir)/configure + [ -n "$(BUILDROOT)" ] && rm -rf $(BUILDROOT)/* + [ -n "$(PKG_NAME).*" ] && rm -f $(PKG_NAME).* + $(MAKE) install DESTDIR=$(BUILDROOT) + $(MKEPMLIST) -u $(SYS_USER) -g $(SYS_GROUP) --prefix $(prefix) \ + $(BUILDROOT)/$(prefix) > files.list + $(EPM) -v -f native -g -n -a $(ARCH) --keep-files --output-dir pkg \ + srcdir=$(srcdir) \ + top_srcdir=$(top_srcdir) \ + top_builddir=$(top_builddir) \ + PACKAGE=$(PACKAGE) \ + SUMMARY="$(SUMMARY)" \ + VERSION=$(ORTP_PKGCONFIG_VERSION) \ + RELEASE=$(RELEASE) \ + LICENSE="$(LICENSE)" \ + VENDOR="$(VENDOR)" \ + PACKAGER="$(PACKAGER)" \ + $(PACKAGE) $(srcdir)/pkg.list + rm -rf $(BUILDROOT) + mv -f pkg/$(PACKAGE)-$(ORTP_PKGCONFIG_VERSION)-$(RELEASE).$(EPM_PKG_EXT) $(PKG_NAME).$(ARCH).$(EPM_PKG_EXT) + +clean-local: + rm -rf pkg $(BUILDROOT) + rm -f files.list + +endif WITH_EPM diff --git a/linphone/mediastreamer2/Makefile.macosx b/linphone/mediastreamer2/Makefile.macosx new file mode 100644 index 000000000..bff389626 --- /dev/null +++ b/linphone/mediastreamer2/Makefile.macosx @@ -0,0 +1,76 @@ +# MacOS X Temporary make file +# H.M 2007.05.23 + +SPEEXDIR = ../../../speex-1.2beta1 +GSMDIR = ../../../gsm-1.0-pl12 +ORTPDIR = ../../oRTP + +INCPATH = -I../include -I$(ORTPDIR)/include -I$(SPEEXDIR)/include -I$(GSMDIR)/inc/ +LIBPATH = -L. -L../../../gsm-1.0-pl12/lib +FRAMEWORK = -framework CoreAudio -framework AudioToolbox -framework Carbon -framework AudioUnit +CFLUGS = -g $(INCPATH) -DWORDS_BIGENDIAN -DDEBUG +#CFLUGS = $(INCPATH) -DWORDS_BIGENDIAN + + +LIBOBJ = mscommon.o msqueue.o msfilerec.o msfilter.o msspeex.o mssndcard.o alaw.o ulaw.o msconf.o msjoin.o msrtp.o ice.o tee.o gsm.o speexec.o audiostream.o msticker.o macsnd.o msfileplayer.o +DYLIB = libms.dylib + +all: echo + +echo: ../tests/echo.c $(DYLIB) + cc -c $(CFLUGS) ../tests/echo.c + cc -o echo $(FRAMEWORK) $(LIBPATH) echo.o $(DYLIB) -lortp -lspeex -lgsm + +clean: + rm -rf *.o *.dylib + +$(DYLIB): $(LIBOBJ) libortp.dylib libspeex.dylib + cc -o $(DYLIB) $(FRAMEWORK) -dynamiclib -compatibility_version 1 -current_version 1 $(LIBOBJ) $(LIBPATH) -lortp -lspeex -lgsm + +libortp.dylib: + cp $(ORTPDIR)/src/.libs/libortp.dylib . + install_name_tool -id @executable_path/libortp.dylib libortp.dylib + +libspeex.dylib: + cp $(SPEEXDIR)/libspeex/.libs/libspeex.dylib . + install_name_tool -id @executable_path/libspeex.dylib libspeex.dylib + +msfileplayer.o: msfileplayer.c + gcc -c $(CFLUGS) msfileplayer.c +msticker.o: msticker.c + gcc -c $(CFLUGS) msticker.c +audiostream.o: audiostream.c + gcc -c $(CFLUGS) audiostream.c +speexec.o: speexec.c + gcc -c $(CFLUGS) speexec.c +gsm.o: gsm.c + gcc -c $(CFLUGS) gsm.c +tee.o: tee.c + gcc -c $(CFLUGS) tee.c +ice.o: ice.c + gcc -c $(CFLUGS) ice.c +msrtp.o: msrtp.c + gcc -c $(CFLUGS) msrtp.c +msjoin.o: msjoin.c + gcc -c $(CFLUGS) msjoin.c +msconf.o: msconf.c + gcc -c $(CFLUGS) msconf.c +msfilter.o: msfilter.c + gcc -c $(CFLUGS) msfilter.c +alaw.o: alaw.c + gcc -c $(CFLUGS) alaw.c +ulaw.o: ulaw.c + gcc -c $(CFLUGS) ulaw.c +msfilerec.o: msfilerec.c + gcc -c $(CFLUGS) msfilerec.c +msspeex.o: msspeex.c + gcc -c $(CFLUGS) msspeex.c +mssndcard.o: mssndcard.c + gcc -c $(CFLUGS) mssndcard.c +msqueue.o: msqueue.c + gcc -c $(CFLUGS) msqueue.c +macsnd.o: macsnd.c + gcc -c $(CFLUGS) macsnd.c + +mscommon.o: mscommon.c + gcc -c $(CFLUGS) -DPACKAGE_PLUGINS_DIR=\".\" mscommon.c diff --git a/linphone/mediastreamer2/NEWS b/linphone/mediastreamer2/NEWS new file mode 100644 index 000000000..fd52fd517 --- /dev/null +++ b/linphone/mediastreamer2/NEWS @@ -0,0 +1,23 @@ +mediastreamer-2.2.1: 25, january 2008 + * video output resizing + * 4CIF and VGA support + * bugfixes + * added snow codec (experimental) + * enable setting of max rtp payload size for all encoders + +mediastreamer-2.2.0: 19, November 2007 + * new "no webcam" screen + * bandwidth settings improvements + * new REQ_VFU command to request a video encoder to send an I-frame + (implemented for ffmpeg based encoders) + * contributed macosx sound support + * new MSVolume filter to make sound power measurements + * rate control of ffmpeg video codecs + +mediastreamer-2.1.0: 23, January 2007 + * add support for Video4Linux V2 cameras + * support for mpjeg cameras + * webcam support on windows operational + * video window display ok on windows + * fix bug with quickcam driver on linux + * bandwidth setting improvements. diff --git a/linphone/mediastreamer2/README b/linphone/mediastreamer2/README new file mode 100644 index 000000000..f76f4f53d --- /dev/null +++ b/linphone/mediastreamer2/README @@ -0,0 +1,94 @@ +Project : mediastreamer2 - a modular sound and video processing and streaming +Email : simon.morlat_at_linphone.org +License : GPL +Home Page : http://savannah.gnu.org/projects/linphone + +Mediastreamer2 is a GPL licensed library to make audio and +video real-time streaming and processing. Written in pure C, +it is based upon the ortp library. + +Design: +------ + +Using mediastreamer2 will allow you to chain filters in a graph. Each +filter will be responsible for doing some kind of processing and will +deliver data to the next filter. As an example, you could get some +data from network and unpack it in an RTP filter. This RTP filter will +deliver the data to a decoder (speex, G711...) which will deliver it +to a filter that is able to play the PCM data or record it into a .wav +file. + +There is a doxygen documentation for more information. + +Features: +-------- + +mediastreamer2 already provides a large set of filters. +Here is a complete list of built-in filters. + + All supported platforms: + * RTP receiver + * RTP sender + * tee (duplicate data) + + Audio Filters: + * audio capture + * audio playback + * mme API (windows) + * alsa API (linux) + * oss API (linux) + * arts API (linux) + * portaudio API (macosx and other) + * macsnd API (native macosx API -please do more testing...-) + * several audio encoder/decoder: PCMU, PCMA, speex, gsm + * wav file reader. + * wav file recorder. + * resampler. + * conference bridge. + * volume analyser. + * acoustic echo canceller. + * dtmf generation filter. + + Video Filters: + * video capture + * v4w API (windows) + * directshow API (windows) + * video4linux API (linux) + * video display + * v4w API (windows) + * SDL API (linux, macosx...) + * several audio encoder/decoder: H263-1998, MP4V-ES, theora + * image resizer. + * format converter. (RBG24, I420...) + + Plugin Filters: + * iLBC decoder/encoder. + +Note that, you can build your own components/filters to do your +own processing or support other codecs. + +Installation procedure: +----------------------- + +The program is known to run on linux, but might work +on any unix and windows systems. + + $> ./configure + $> make + $> su -c 'make install' + +Contact information: +-------------------- + +For more information on mediastreamer2, any contributions, or any remarks, +you can contact me at . Commercial licensing +is also provided through antisip (http://www.antisip.com or jack_at_atosc.org). + +Use the *linphone* mailing list for question about mediastreamer2. + . + +Subscribe by writing to: + with a subject set to "subscribe". + + + diff --git a/linphone/mediastreamer2/acinclude.m4 b/linphone/mediastreamer2/acinclude.m4 new file mode 100644 index 000000000..a2aa2feaf --- /dev/null +++ b/linphone/mediastreamer2/acinclude.m4 @@ -0,0 +1,121 @@ +dnl -*- autoconf -*- +AC_DEFUN([MS_CHECK_DEP],[ + dnl $1=dependency description + dnl $2=dependency short name, will be suffixed with _CFLAGS and _LIBS + dnl $3=headers's place + dnl $4=lib's place + dnl $5=header to check + dnl $6=lib to check + dnl $7=function to check in library + + dep_name=$2 + dep_headersdir=$3 + dep_libsdir=$4 + dep_header=$5 + dep_lib=$6 + dep_funclib=$7 + other_libs=$8 + + CPPFLAGS_save=$CPPFLAGS + LDFLAGS_save=$LDFLAGS + CPPFLAGS=`echo "-I$dep_headersdir"|sed -e "s:-I/usr/include[\ ]*$::"` + LIBS="-l$dep_lib" + LDFLAGS=`echo "-L$dep_libsdir"|sed -e "s:-L/usr/lib\(64\)*[\ ]*::"` + + $2_CFLAGS="$CPPFLAGS" + $2_LIBS="$LDFLAGS $LIBS" + + AC_CHECK_HEADERS([$dep_header],[AC_CHECK_LIB([$dep_lib],[$dep_funclib],found=yes,found=no, [$other_libs]) + ],found=no) + + if test "$found" = "yes" ; then + eval $2_found=yes + else + eval $2_found=no + eval $2_CFLAGS= + eval $2_LIBS= + fi + AC_SUBST($2_CFLAGS) + AC_SUBST($2_LIBS) + CPPFLAGS=$CPPFLAGS_save + LDFLAGS=$LDFLAGS_save +]) + + +AC_DEFUN([MS_CHECK_VIDEO],[ + + dnl conditionnal build of video support + AC_ARG_ENABLE(video, + [ --enable-video Turn on video support compiling], + [case "${enableval}" in + yes) video=true ;; + no) video=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-video) ;; + esac],[video=true]) + + AC_ARG_WITH( ffmpeg, + [ --with-ffmpeg Sets the installation prefix of ffmpeg, needed for video support. [default=/usr] ], + [ ffmpegdir=${withval}],[ ffmpegdir=/usr ]) + + AC_ARG_WITH( sdl, + [ --with-sdl Sets the installation prefix of libSDL, needed for video support. [default=/usr] ], + [ libsdldir=${withval}],[ libsdldir=/usr ]) + + if test "$video" = "true"; then + + dnl test for ffmpeg presence + PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 50.0.0 ],ffmpeg_found=yes , ffmpeg_found=no) + dnl workaround for debian... + PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 0d.50.0.0 ], ffmpeg_found=yes, ffmpeg_found=no) + if test x$ffmpeg_found = xno ; then + AC_MSG_ERROR([Could not find ffmpeg headers and library. This is mandatory for video support]) + fi + + dnl check for new/old ffmpeg header file layout + CPPFLAGS_save=$CPPFLAGS + CPPFLAGS=$FFMPEG_CFLAGS + AC_CHECK_HEADERS(libavcodec/avcodec.h) + CPPFLAGS=$CPPFLAGS_save + + dnl to workaround a bug on debian and ubuntu, check if libavcodec needs -lvorbisenc to compile + AC_CHECK_LIB(avcodec,avcodec_register_all, novorbis=yes , [ + LIBS="$LIBS -lvorbisenc" + ], $FFMPEG_LIBS ) + + dnl when swscale feature is not provided by + dnl libswscale, its features are swallowed by + dnl libavcodec, but without swscale.h and without any + dnl declaration into avcodec.h (this is to be + dnl considered as an ffmpeg bug). + dnl + dnl #if defined(HAVE_LIBAVCODEC_AVCODEC_H) && !defined(HAVE_LIBSWSCALE_SWSCALE_H) + dnl # include "swscale.h" // private linhone swscale.h + dnl #endif + CPPFLAGS_save=$CPPFLAGS + CPPFLAGS=$FFMPEG_CFLAGS + AC_CHECK_HEADERS(libswscale/swscale.h) + CPPFLAGS=$CPPFLAGS_save + + PKG_CHECK_MODULES(SWSCALE, [libswscale >= 0.5.0 ], [echo "We have libswscale"], + [echo "We don't have libswscale, let's hope its symbols are in libavcodec"] ) + + MS_CHECK_DEP([SDL],[SDL],[${libsdldir}/include],[${libsdldir}/lib],[SDL/SDL.h],[SDL],[SDL_Init]) + if test "$SDL_found" = "no" ; then + AC_MSG_ERROR([Could not find libsdl headers and library. This is mandatory for video support]) + fi + + PKG_CHECK_MODULES(THEORA, [theora >= 1.0alpha7 ], [have_theora=yes], + [have_theora=no]) + AC_CHECK_HEADERS(X11/Xlib.h) + + VIDEO_CFLAGS=" $FFMPEG_CFLAGS $SDL_CFLAGS -DVIDEO_ENABLED " + VIDEO_LIBS=" $FFMPEG_LIBS $SWSCALE_LIBS $SDL_LIBS" + + if test "${ac_cv_header_X11_Xlib_h}" = "yes" ; then + VIDEO_LIBS="$VIDEO_LIBS -lX11" + fi + fi + + AC_SUBST(VIDEO_CFLAGS) + AC_SUBST(VIDEO_LIBS) +]) diff --git a/linphone/mediastreamer2/autogen.sh b/linphone/mediastreamer2/autogen.sh new file mode 100755 index 000000000..d7d269423 --- /dev/null +++ b/linphone/mediastreamer2/autogen.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +AM_VERSION="1.9" +if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then + # automake-1.9 (recommended) is not available on Fedora 8 + AUTOMAKE=automake + ACLOCAL=aclocal +else + ACLOCAL=aclocal-${AM_VERSION} + AUTOMAKE=automake-${AM_VERSION} +fi + +echo "Generating build scripts in mediastreamer..." +set -x +libtoolize --copy --force +autoheader +$ACLOCAL +$AUTOMAKE --force-missing --add-missing --copy +autoconf diff --git a/linphone/mediastreamer2/build/.cvsignore b/linphone/mediastreamer2/build/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/mediastreamer2/build/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/mediastreamer2/build/Makefile.am b/linphone/mediastreamer2/build/Makefile.am new file mode 100755 index 000000000..4718144ae --- /dev/null +++ b/linphone/mediastreamer2/build/Makefile.am @@ -0,0 +1 @@ +SUBDIRS= win32native win32-novideo wince diff --git a/linphone/mediastreamer2/build/win32-novideo/.cvsignore b/linphone/mediastreamer2/build/win32-novideo/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/mediastreamer2/build/win32-novideo/Makefile.am b/linphone/mediastreamer2/build/win32-novideo/Makefile.am new file mode 100755 index 000000000..b8a8dc25a --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=alldescs.h mediastreamer2.vcproj mediastream.vcproj mediastreamer2.def + diff --git a/linphone/mediastreamer2/build/win32-novideo/alldescs.h b/linphone/mediastreamer2/build/win32-novideo/alldescs.h new file mode 100755 index 000000000..9f7534ac3 --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/alldescs.h @@ -0,0 +1,66 @@ +#include "mediastreamer2/msfilter.h" + +extern MSFilterDesc ms_alaw_dec_desc; +extern MSFilterDesc ms_alaw_enc_desc; +extern MSFilterDesc ms_ulaw_dec_desc; +extern MSFilterDesc ms_ulaw_enc_desc; +extern MSFilterDesc ms_file_player_desc; +extern MSFilterDesc ms_rtp_send_desc; +extern MSFilterDesc ms_rtp_recv_desc; +extern MSFilterDesc ms_dtmf_gen_desc; +extern MSFilterDesc ms_file_rec_desc; +extern MSFilterDesc ms_speex_dec_desc; +extern MSFilterDesc ms_speex_enc_desc; +extern MSFilterDesc ms_gsm_dec_desc; +extern MSFilterDesc ms_gsm_enc_desc; +extern MSFilterDesc ms_speex_ec_desc; +extern MSFilterDesc ms_tee_desc; +extern MSFilterDesc ms_conf_desc; +//extern MSFilterDesc alsa_write_desc; +//extern MSFilterDesc alsa_read_desc; +//extern MSFilterDesc oss_read_desc; +//extern MSFilterDesc oss_write_desc; +//extern MSFilterDesc ms_arts_read_desc; +//extern MSFilterDesc ms_arts_write_desc; +//extern MSFilterDesc ms_v4l_desc; +//extern MSFilterDesc ms_sdl_out_desc; +//extern MSFilterDesc ms_h263_enc_desc; +//extern MSFilterDesc ms_h263_dec_desc; +extern MSFilterDesc ms_join_desc; +extern MSFilterDesc ms_resample_desc; +extern MSFilterDesc ms_volume_desc; +MSFilterDesc * ms_filter_descs[]={ +&ms_alaw_dec_desc, +&ms_alaw_enc_desc, +&ms_ulaw_dec_desc, +&ms_ulaw_enc_desc, +&ms_file_player_desc, +&ms_rtp_send_desc, +&ms_rtp_recv_desc, +&ms_dtmf_gen_desc, +&ms_file_rec_desc, +&ms_speex_dec_desc, +&ms_speex_enc_desc, +&ms_gsm_dec_desc, +&ms_gsm_enc_desc, +&ms_speex_ec_desc, +&ms_tee_desc, +&ms_conf_desc, +//&alsa_write_desc, +//&alsa_read_desc, +//&oss_read_desc, +//&oss_write_desc, +//&ms_arts_read_desc, +//&ms_arts_write_desc, +//&ms_v4l_desc, +//&ms_sdl_out_desc, +//&ms_h263_enc_desc, +//&ms_h263_dec_desc, +&ms_join_desc, +#ifndef DISABLE_RESAMPLE +&ms_resample_desc, +#endif +&ms_volume_desc, +NULL +}; + diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastream.dev b/linphone/mediastreamer2/build/win32-novideo/mediastream.dev new file mode 100755 index 000000000..111434f53 --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/mediastream.dev @@ -0,0 +1,59 @@ +[Project] +FileName=mediastream.dev +Name=mediastream +UnitCount=1 +Type=1 +Ver=1 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DINET6 _@@_-DORTP_INET6 _@@_-DORTP_STATIC_@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DDISABLE_RESAMPLE_@@_-Wall -Werror_@@_-g_@@_ +CppCompiler= +Linker=mediastreamer2.lib_@@_-lortp_@@_-lgsm_@@_-lspeex_@@_-lws2_32_@@_-liphlpapi_@@_-lwinmm_@@_ +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=mediastream.exe +HostApplication= +Folders= +CommandLine=--local 8000 --remote 127.0.0.1:8000 --payload 0 +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 + +[Unit1] +FileName=..\..\tests\mediastream.c +CompileCpp=0 +Folder=mediastream +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastream.vcproj b/linphone/mediastreamer2/build/win32-novideo/mediastream.vcproj new file mode 100755 index 000000000..b44c28431 --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/mediastream.vcproj @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def new file mode 100755 index 000000000..72fb5c03c --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.def @@ -0,0 +1,70 @@ +LIBRARY mediastreamer2 + +EXPORTS + + ms_init + ms_exit + ms_reload_snd_card + + ms_filter_new + ms_filter_new_from_desc + ms_filter_destroy + ms_filter_create_encoder + ms_filter_create_decoder + ms_filter_call_method + ms_filter_call_method_noarg + ms_filter_link + ms_filter_unlink + ms_filter_preprocess + ms_filter_postprocess + ms_filter_register + ms_filter_codec_supported + + ms_snd_card_create_reader + ms_snd_card_create_writer + ms_snd_card_get_name + ms_snd_card_get_string_id + ms_snd_card_manager_get + ms_snd_card_manager_get_default_card + ms_snd_card_manager_get_card + ms_snd_card_manager_get_list + ms_snd_card_dup + ms_snd_card_destroy + + ms_ticker_new + ms_ticker_destroy + ms_ticker_attach + ms_ticker_detach + ms_ticker_set_time_func + ms_ticker_print_graphs + + ms_bufferizer_init + ms_bufferizer_uninit + ms_bufferizer_read + ms_bufferizer_put + ms_bufferizer_put_from_queue + + audio_stream_start + audio_stream_stop + audio_stream_free + create_duplex_rtpsession + + ms_load_plugins + ms_filter_set_notify_callback + + ms_sleep + ms_filter_new_from_name + + ms_queue_init + + ms_list_free + ms_list_for_each + ms_list_append + ms_list_remove + ms_filter_set_notify_callback + + ice_sound_send_stun_request + ice_process_stun_message + ms_discover_mtu + ms_set_mtu + \ No newline at end of file diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.dev b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.dev new file mode 100755 index 000000000..5163f16b7 --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.dev @@ -0,0 +1,419 @@ +[Project] +FileName=mediastreamer2.dev +Name=mediastreamer2 +UnitCount=36 +Type=2 +Ver=1 +ObjFiles= +Includes=../../../oRTP/include;../../include;c:/Dev-Cpp/include/gsm;. +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DINET6 _@@_-DORTP_INET6 _@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DWINSND_BUFLEN=512_@@_-DMAX_WAVEHDR=12_@@_-DDISABLE_RESAMPLE_@@_-Wall -Werror -g_@@_ +CppCompiler= +Linker=-lortp_@@_ +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=mediastreamer2.lib +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 + +[Unit1] +FileName=..\..\include\mediastreamer2\waveheader.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\mediastreamer2\allfilters.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\mediastreamer2\dtmfgen.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\mediastreamer2\ice.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\mediastreamer2\mediastream.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\mediastreamer2\mscommon.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\include\mediastreamer2\msfileplayer.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\mediastreamer2\msfilerec.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\mediastreamer2\msfilter.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\mediastreamer2\msqueue.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\include\mediastreamer2\msrtp.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\include\mediastreamer2\mssndcard.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\include\mediastreamer2\msticker.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\include\mediastreamer2\msv4l.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\include\mediastreamer2\msvideo.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\src\alaw.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\src\audiostream.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\src\dtmfgen.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\src\gsm.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\src\ice.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\src\mscommon.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\src\msconf.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\src\msfileplayer_win.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\src\msfilerec_win.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\src\msfilter.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\src\msqueue.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\src\msrtp.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\src\mssndcard.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\src\msspeex.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\src\msticker.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\src\speexec.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\src\tee.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\src\ulaw.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\src\msjoin.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\src\winsnd2.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\src\winsnd2.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit34] +FileName=alldescs.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.vcproj b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.vcproj new file mode 100755 index 000000000..68a99b15f --- /dev/null +++ b/linphone/mediastreamer2/build/win32-novideo/mediastreamer2.vcproj @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/build/win32native/.cvsignore b/linphone/mediastreamer2/build/win32native/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/mediastreamer2/build/win32native/Makefile.am b/linphone/mediastreamer2/build/win32native/Makefile.am new file mode 100755 index 000000000..9aed018f4 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=alldescs.h mediastreamer2.vcproj mediastream.vcproj videodisplay.vcproj mediastreamer2.def + diff --git a/linphone/mediastreamer2/build/win32native/alldescs.h b/linphone/mediastreamer2/build/win32native/alldescs.h new file mode 100755 index 000000000..ba01dbfda --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/alldescs.h @@ -0,0 +1,90 @@ +#include "mediastreamer2/msfilter.h" + +extern MSFilterDesc ms_alaw_dec_desc; +extern MSFilterDesc ms_alaw_enc_desc; +extern MSFilterDesc ms_ulaw_dec_desc; +extern MSFilterDesc ms_ulaw_enc_desc; +extern MSFilterDesc ms_file_player_desc; +extern MSFilterDesc ms_rtp_send_desc; +extern MSFilterDesc ms_rtp_recv_desc; +extern MSFilterDesc ms_dtmf_gen_desc; +extern MSFilterDesc ms_file_rec_desc; +extern MSFilterDesc ms_speex_dec_desc; +extern MSFilterDesc ms_speex_enc_desc; +extern MSFilterDesc ms_gsm_dec_desc; +extern MSFilterDesc ms_gsm_enc_desc; +extern MSFilterDesc ms_speex_ec_desc; +extern MSFilterDesc ms_tee_desc; +extern MSFilterDesc ms_conf_desc; +//extern MSFilterDesc alsa_write_desc; +//extern MSFilterDesc alsa_read_desc; +//extern MSFilterDesc oss_read_desc; +//extern MSFilterDesc oss_write_desc; +//extern MSFilterDesc ms_arts_read_desc; +//extern MSFilterDesc ms_arts_write_desc; +extern MSFilterDesc ms_v4w_desc; +extern MSFilterDesc ms_video_out_desc; +extern MSFilterDesc ms_h263_enc_desc; +extern MSFilterDesc ms_h263_dec_desc; +extern MSFilterDesc ms_mpeg4_enc_desc; +extern MSFilterDesc ms_mpeg4_dec_desc; +extern MSFilterDesc ms_snow_enc_desc; +extern MSFilterDesc ms_snow_dec_desc; +extern MSFilterDesc ms_theora_enc_desc; +extern MSFilterDesc ms_theora_dec_desc; +//extern MSFilterDesc pasnd_read_desc; +//extern MSFilterDesc pasnd_write_desc; +extern MSFilterDesc ms_size_conv_desc; +extern MSFilterDesc ms_pix_conv_desc; +extern MSFilterDesc ms_join_desc; +extern MSFilterDesc ms_resample_desc; +extern MSFilterDesc ms_volume_desc; +extern MSFilterDesc ms_static_image_desc; +extern MSFilterDesc ms_mire_desc; +MSFilterDesc * ms_filter_descs[]={ +&ms_alaw_dec_desc, +&ms_alaw_enc_desc, +&ms_ulaw_dec_desc, +&ms_ulaw_enc_desc, +&ms_file_player_desc, +&ms_rtp_send_desc, +&ms_rtp_recv_desc, +&ms_dtmf_gen_desc, +&ms_file_rec_desc, +&ms_speex_dec_desc, +&ms_speex_enc_desc, +&ms_gsm_dec_desc, +&ms_gsm_enc_desc, +&ms_speex_ec_desc, +&ms_tee_desc, +&ms_conf_desc, +//&alsa_write_desc, +//&alsa_read_desc, +//&oss_read_desc, +//&oss_write_desc, +//&ms_arts_read_desc, +//&ms_arts_write_desc, +&ms_v4w_desc, +&ms_video_out_desc, +&ms_h263_enc_desc, +&ms_h263_dec_desc, +&ms_mpeg4_enc_desc, +&ms_mpeg4_dec_desc, +&ms_snow_enc_desc, +&ms_snow_dec_desc, +&ms_theora_enc_desc, +&ms_theora_dec_desc, +//&pasnd_read_desc, +//&pasnd_write_desc, +&ms_size_conv_desc, +&ms_pix_conv_desc, +&ms_join_desc, +#ifndef NORESAMPLE +&ms_resample_desc, +#endif +&ms_volume_desc, +&ms_static_image_desc, +&ms_mire_desc, +NULL +}; + diff --git a/linphone/mediastreamer2/build/win32native/mediastream.dev b/linphone/mediastreamer2/build/win32native/mediastream.dev new file mode 100755 index 000000000..30a4e63ed --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/mediastream.dev @@ -0,0 +1,72 @@ +[Project] +FileName=mediastream.dev +Name=mediastream +UnitCount=1 +Type=1 +Ver=3 +IsCpp=1 +Folders= +CommandLine=--local 8000 --remote 127.0.0.1:8000 --payload 0 +CompilerSettings=0000000000000000000000 +PchHead=-1 +PchSource=-1 +ProfilesCount=1 +ProfileIndex=0 + +[Unit1] +FileName=..\..\tests\mediastream.c +CompileCpp=0 +Folder=mediastream +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 + +[Profile1] +ProfileName=Default Profile +Type=1 +ObjFiles= +Includes=../../include;../../../oRTP/include +Libs=../../../oRTP/build/win32native;../../../../linphone-deps/lib +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DINET6 _@@_-DORTP_INET6 _@@_-DORTP_STATIC_@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DDISABLE_RESAMPLE_@@_-DVIDEO_ENABLED_@@_-Wall -Werror_@@_-g_@@_ +CppCompiler= +Linker=libmediastreamer2.a_@@_-lortp_@@_-lgsm_@@_-lspeex_@@_-lws2_32_@@_-liphlpapi_@@_-lwinmm_@@_-lavcodec_@@_-lavutil_@@_-ltheora_@@_-logg_@@_-lvfw32_@@__@@_ +PreprocDefines= +CompilerSettings=0000000000000000000000 +Icon= +ExeOutput= +ObjectOutput=Default Profile +OverrideOutput=0 +OverrideOutputName=mediastream.exe +HostApplication= +CommandLine=--local 8000 --remote 127.0.0.1:8000 --payload 0 +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + diff --git a/linphone/mediastreamer2/build/win32native/mediastream.vcproj b/linphone/mediastreamer2/build/win32native/mediastream.vcproj new file mode 100755 index 000000000..1dd3ec7b0 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/mediastream.vcproj @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/build/win32native/mediastreamer2.def b/linphone/mediastreamer2/build/win32native/mediastreamer2.def new file mode 100755 index 000000000..9fe06c1b1 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/mediastreamer2.def @@ -0,0 +1,99 @@ +LIBRARY mediastreamer2 + +EXPORTS + + ms_init + ms_exit + ms_reload_snd_card + + ms_filter_new + ms_filter_new_from_desc + ms_filter_destroy + ms_filter_create_encoder + ms_filter_create_decoder + ms_filter_call_method + ms_filter_call_method_noarg + ms_filter_link + ms_filter_unlink + ms_filter_preprocess + ms_filter_postprocess + ms_filter_codec_supported + + ms_snd_card_create_reader + ms_snd_card_create_writer + ms_snd_card_get_name + ms_snd_card_get_string_id + ms_snd_card_manager_get + ms_snd_card_manager_get_default_card + ms_snd_card_manager_get_card + ms_snd_card_manager_get_list + ms_snd_card_dup + ms_snd_card_destroy + + ms_ticker_new + ms_ticker_destroy + ms_ticker_attach + ms_ticker_detach + ms_ticker_set_time_func + ms_filter_register + ms_ticker_print_graphs + + ms_bufferizer_init + ms_bufferizer_uninit + ms_bufferizer_read + ms_bufferizer_put + ms_bufferizer_put_from_queue + + audio_stream_start + audio_stream_stop + audio_stream_free + create_duplex_rtpsession + + ms_load_plugins + + ms_display_new + ms_display_set_window_id + ms_display_destroy + + video_preview_stop + video_preview_start + video_stream_new + video_stream_start + video_stream_stop + + ms_is_ipv6 + + ms_queue_flush + + yuv_buf_alloc + yuv_buf_init_from_mblk + yuv_buf_init_from_mblk_with_size + + ms_sleep + ms_filter_new_from_name + + ms_queue_init + + rfc3984_init + rfc3984_uninit + rfc3984_pack + rfc3984_unpack + rfc3984_set_mode + + ms_list_free + ms_list_for_each + ms_list_append + ms_list_remove + ms_filter_set_notify_callback + + ice_sound_send_stun_request + ice_process_stun_message + + ms_web_cam_manager_get_default_cam + ms_web_cam_manager_get + + video_stream_iterate + ms_discover_mtu + ms_set_mtu + + \ No newline at end of file diff --git a/linphone/mediastreamer2/build/win32native/mediastreamer2.dev b/linphone/mediastreamer2/build/win32native/mediastreamer2.dev new file mode 100755 index 000000000..ce8a0df85 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/mediastreamer2.dev @@ -0,0 +1,603 @@ +[Project] +FileName=mediastreamer2.dev +Name=mediastreamer2 +UnitCount=54 +Type=2 +Ver=3 +IsCpp=1 +Folders= +CommandLine= +CompilerSettings=0000000000100000000000 +PchHead=-1 +PchSource=-1 +ProfilesCount=1 +ProfileIndex=0 + +[Unit1] +FileName=..\..\include\mediastreamer2\waveheader.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\mediastreamer2\allfilters.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\mediastreamer2\dtmfgen.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\mediastreamer2\ice.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\mediastreamer2\mediastream.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\mediastreamer2\mscommon.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\include\mediastreamer2\msfileplayer.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\mediastreamer2\msfilerec.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\mediastreamer2\msfilter.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\mediastreamer2\msqueue.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\include\mediastreamer2\msrtp.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\include\mediastreamer2\mssndcard.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\include\mediastreamer2\msticker.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\include\mediastreamer2\msv4l.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\include\mediastreamer2\msvideo.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\src\alaw.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\src\audiostream.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\src\dtmfgen.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\src\gsm.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\src\ice.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\src\mscommon.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\src\msconf.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\src\msfileplayer_win.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\src\msfilerec_win.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\src\msfilter.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\src\msqueue.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\src\msrtp.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\src\mssndcard.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\src\msspeex.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\src\msticker.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\src\speexec.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\src\tee.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\src\ulaw.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\src\msjoin.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\src\pixconv.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\src\rfc2429.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 +UnitCount=48 + +[Unit34] +FileName=alldescs.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\src\sizeconv.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\src\videodec.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\src\videoenc.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\src\videoout.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\src\winsnd2.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\src\videostream.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\src\winvideo.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit45] +FileName=..\..\src\vfw-missing.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\src\theora.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\include\mediastreamer2\msvideoout.h +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Profile1] +ProfileName=Default Profile +Type=3 +ObjFiles= +Includes=../../../oRTP/include;../../include;c:/Dev-Cpp/include/gsm;.;../../../../linphone-deps/include +Libs=../../../../linphone-deps/lib;../../../oRTP/build/win32native +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-ggdb_@@_-DINET6 _@@_-DORTP_INET6 _@@_-D_WORKAROUND_MINGW32_BUGS_@@_-D_WIN32_WINNT=0x0501 _@@_-DNOSDL_@@_-DVIDEO_ENABLED_@@_-DNORESAMPLE_@@_-Wall _@@_-DHAVE_LIBAVCODEC_AVCODEC_H_@@_ +CppCompiler= +Linker=-lortp_@@_-lavcodec_@@_-lavutil_@@_-ltheora_@@_-lspeex_@@_-lgsm_@@_-lws2_32_@@_-lwinmm_@@_-lvfw32_@@_-logg_@@__@@_ +PreprocDefines= +CompilerSettings=0000000000010000000000 +Icon= +ExeOutput=..\WIN32N~1 +ObjectOutput=Default Profile +OverrideOutput=0 +OverrideOutputName=libmediastreamer2.a +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + +[Unit48] +FileName=..\..\src\nowebcam.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd=$(CC) -c nowebcam.c -o "Default Profile/nowebcam.o" $(CFLAGS) + +[Unit49] +FileName=..\..\src\msvolume.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd=$(CC) -c msvolume.c -o "Default Profile/msvolume.o" $(CFLAGS) + +[Unit50] +FileName=..\..\src\msvideo.c +CompileCpp=1 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\src\mswebcam.c +CompileCpp=1 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\src\mire.c +CompileCpp=1 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\src\mtu.c +CompileCpp=0 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd=$(CC) -c mtu.c -o "Default Profile/mtu.o" $(CFLAGS) + +[Unit54] +FileName=..\..\src\rfc3984.c +CompileCpp=1 +Folder=mediastreamer2 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/linphone/mediastreamer2/build/win32native/mediastreamer2.vcproj b/linphone/mediastreamer2/build/win32native/mediastreamer2.vcproj new file mode 100755 index 000000000..45c369001 --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/mediastreamer2.vcproj @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/build/win32native/videodisplay.vcproj b/linphone/mediastreamer2/build/win32native/videodisplay.vcproj new file mode 100755 index 000000000..8e764601d --- /dev/null +++ b/linphone/mediastreamer2/build/win32native/videodisplay.vcproj @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/build/wince/.cvsignore b/linphone/mediastreamer2/build/wince/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/mediastreamer2/build/wince/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/mediastreamer2/build/wince/Makefile.am b/linphone/mediastreamer2/build/wince/Makefile.am new file mode 100755 index 000000000..07d97c86e --- /dev/null +++ b/linphone/mediastreamer2/build/wince/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=alldescs.h mediastreamer2.vcproj mediastreamer2.def + diff --git a/linphone/mediastreamer2/build/wince/alldescs.h b/linphone/mediastreamer2/build/wince/alldescs.h new file mode 100644 index 000000000..380326fa1 --- /dev/null +++ b/linphone/mediastreamer2/build/wince/alldescs.h @@ -0,0 +1,62 @@ +#include "mediastreamer2/msfilter.h" + +extern MSFilterDesc ms_alaw_dec_desc; +extern MSFilterDesc ms_alaw_enc_desc; +extern MSFilterDesc ms_ulaw_dec_desc; +extern MSFilterDesc ms_ulaw_enc_desc; +extern MSFilterDesc ms_file_player_desc; +extern MSFilterDesc ms_rtp_send_desc; +extern MSFilterDesc ms_rtp_recv_desc; +extern MSFilterDesc ms_dtmf_gen_desc; +extern MSFilterDesc ms_file_rec_desc; +extern MSFilterDesc ms_speex_dec_desc; +extern MSFilterDesc ms_speex_enc_desc; +//extern MSFilterDesc ms_gsm_dec_desc; +//extern MSFilterDesc ms_gsm_enc_desc; +extern MSFilterDesc ms_speex_ec_desc; +extern MSFilterDesc ms_tee_desc; +extern MSFilterDesc ms_conf_desc; +//extern MSFilterDesc alsa_write_desc; +//extern MSFilterDesc alsa_read_desc; +//extern MSFilterDesc oss_read_desc; +//extern MSFilterDesc oss_write_desc; +//extern MSFilterDesc ms_arts_read_desc; +//extern MSFilterDesc ms_arts_write_desc; +//extern MSFilterDesc ms_v4l_desc; +extern MSFilterDesc ms_v4w_desc; +//extern MSFilterDesc ms_sdl_out_desc; +//extern MSFilterDesc ms_h263_enc_desc; +//extern MSFilterDesc ms_h263_dec_desc; +extern MSFilterDesc ms_join_desc; +MSFilterDesc * ms_filter_descs[]={ +&ms_alaw_dec_desc, +&ms_alaw_enc_desc, +&ms_ulaw_dec_desc, +&ms_ulaw_enc_desc, +&ms_file_player_desc, +&ms_rtp_send_desc, +&ms_rtp_recv_desc, +&ms_dtmf_gen_desc, +&ms_file_rec_desc, +&ms_speex_dec_desc, +&ms_speex_enc_desc, +//&ms_gsm_dec_desc, +//&ms_gsm_enc_desc, +&ms_speex_ec_desc, +&ms_tee_desc, +&ms_conf_desc, +//&alsa_write_desc, +//&alsa_read_desc, +//&oss_read_desc, +//&oss_write_desc, +//&ms_arts_read_desc, +//&ms_arts_write_desc, +//&ms_v4l_desc, +&ms_v4w_desc, +//&ms_sdl_out_desc, +//&ms_h263_enc_desc, +//&ms_h263_dec_desc, +&ms_join_desc, +NULL +}; + diff --git a/linphone/mediastreamer2/build/wince/mediastreamer2.def b/linphone/mediastreamer2/build/wince/mediastreamer2.def new file mode 100644 index 000000000..4d9606b0a --- /dev/null +++ b/linphone/mediastreamer2/build/wince/mediastreamer2.def @@ -0,0 +1,52 @@ +LIBRARY mediastreamer2 + +EXPORTS + + ms_init + ms_exit + ms_reload_snd_card + + ms_filter_new + ms_filter_new_from_desc + ms_filter_destroy + ms_filter_create_encoder + ms_filter_create_decoder + ms_filter_call_method + ms_filter_call_method_noarg + ms_filter_link + ms_filter_unlink + ms_filter_preprocess + ms_filter_postprocess + ms_filter_register + ms_filter_codec_supported + + ms_snd_card_create_reader + ms_snd_card_create_writer + ms_snd_card_get_name + ms_snd_card_get_string_id + ms_snd_card_manager_get + ms_snd_card_manager_get_default_card + ms_snd_card_manager_get_card + ms_snd_card_manager_get_list + ms_snd_card_dup + ms_snd_card_destroy + + ms_ticker_new + ms_ticker_destroy + ms_ticker_attach + ms_ticker_detach + ms_ticker_set_time_func + ms_ticker_print_graphs + + + ms_bufferizer_init + ms_bufferizer_uninit + ms_bufferizer_read + ms_bufferizer_put + ms_bufferizer_put_from_queue + + ms_load_plugins + + audio_stream_start + ms_discover_mtu + ms_set_mtu diff --git a/linphone/mediastreamer2/build/wince/mediastreamer2.vcproj b/linphone/mediastreamer2/build/wince/mediastreamer2.vcproj new file mode 100644 index 000000000..7bfb50013 --- /dev/null +++ b/linphone/mediastreamer2/build/wince/mediastreamer2.vcproj @@ -0,0 +1,1017 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/mediastreamer2/configure.ac b/linphone/mediastreamer2/configure.ac new file mode 100644 index 000000000..ccc8b1248 --- /dev/null +++ b/linphone/mediastreamer2/configure.ac @@ -0,0 +1,482 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT([mediastreamer],[2.2.0]) + +AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A mediastreaming library for telephony application.]) +AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)]) + +AC_CANONICAL_SYSTEM + +dnl Source packaging numbers +MEDIASTREAMER_MAJOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f1) +MEDIASTREAMER_MINOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f2) +MEDIASTREAMER_MICRO_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f3) +MEDIASTREAMER_EXTRA_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f4) + +LIBMEDIASTREAMER_SO_CURRENT=0 dnl increment this number when you add/change/remove an interface +LIBMEDIASTREAMER_SO_REVISION=1 dnl increment this number when you change source code, without changing interfaces; set to 0 when incrementing CURRENT +LIBMEDIASTREAMER_SO_AGE=0 dnl increment this number when you add an interface, set to 0 if you remove an interface + +LIBMEDIASTREAMER_SO_VERSION=$LIBMEDIASTREAMER_SO_CURRENT:$LIBMEDIASTREAMER_SO_REVISION:$LIBMEDIASTREAMER_SO_AGE +MEDIASTREAMER_VERSION=${MEDIASTREAMER_MAJOR_VERSION}.${MEDIASTREAMER_MINOR_VERSION}.${MEDIASTREAMER_MICRO_VERSION} + +if test -n "$MEDIASTREAMER_EXTRA_VERSION" ; then + MEDIASTREAMER_VERSION="${MEDIASTREAMER_VERSION}.${MEDIASTREAMER_EXTRA_VERSION}" +fi + +AC_SUBST(LIBMEDIASTREAMER_SO_VERSION) +AC_SUBST(MEDIASTREAMER_VERSION) + +PACKAGE=mediastreamer + +OS=`uname|sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` +AC_MSG_RESULT([Building Package on ${OS}]) + +AM_INIT_AUTOMAKE([tar-ustar]) +AC_CONFIG_HEADERS(mediastreamer-config.h) +AC_DEFINE_UNQUOTED(MEDIASTREAMER_MAJOR_VERSION,$MEDIASTREAMER_MAJOR_VERSION, [major version]) +AC_DEFINE_UNQUOTED(MEDIASTREAMER_MINOR_VERSION,$MEDIASTREAMER_MINOR_VERSION, [minor version]) +AC_DEFINE_UNQUOTED(MEDIASTREAMER_MICRO_VERSION,$MEDIASTREAMER_MICRO_VERSION, [micro version]) +AC_DEFINE_UNQUOTED(MEDIASTREAMER_VERSION,"$MEDIASTREAMER_VERSION",[MEDIASTREAMER version number]) + +AC_SUBST([mkdir_p]) + +AC_MSG_CHECKING([warning make an error on compilation]) +AC_ARG_ENABLE(strict, +[ --enable-strict Enable error on compilation warning [default=no]], +[wall_werror=$enableval], +[wall_werror=no] +) + +CFLAGS="-DORTP_INET6 $CFLAGS " + +dnl enable ipv6 support +AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Turn on ipv6 support], + [case "${enableval}" in + yes) ipv6=true;; + no) ipv6=false;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ipv6) ;; + esac],[ipv6=true]) +if test x$ipv6 = xtrue ; then + CFLAGS="$CFLAGS -DINET6" +fi + + +AC_ARG_ENABLE(debug, + [ --enable-debug=[yes/no] enables the display of traces showing the execution of the library. [default=yes]], + [case "${enableval}" in + yes) debug_enabled=yes;; + no) debug_enabled=no;; + *) AC_MSG_ERROR("Bad value for --enable-debug");; + esac], + [debug_enabled=no] ) + + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) + +if test "$GCC" != "yes" ; then + case $target_os in + *hpux*) + dnl we are probably using HPUX cc compiler, so add a +O2 to CFLAGS + CFLAGS="$CFLAGS +O2 -g " + ;; + esac +else + CFLAGS="$CFLAGS -Wall" +fi + + + +if test $debug_enabled = "yes"; then + CFLAGS="$CFLAGS -g -DDEBUG" +else + CFLAGS="$CFLAGS -O2 -g " +fi + +dnl Checks for header files. +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_HEADER_TIME +AC_WORDS_BIGENDIAN +if test x$ac_cv_c_bigendian = xyes ; then + CFLAGS="$CFLAGS -D_BIGENDIAN " +fi + +if test $GCC = yes && test $wall_werror = yes; then + CFLAGS="$CFLAGS -Werror " +fi + +macosx_found=no + +dnl add thread flags +case $OS in + darwin*) + MSPLUGINS_CFLAGS="" + MSPLUGINS_LIBS="-dynamiclib" + macosx_found=yes + ;; + *) + MSPLUGINS_CFLAGS="-pthread" + MSPLUGINS_LIBS="-shared -pthread" + CFLAGS="$CFLAGS -pthread -D_REENTRANT" + LIBS="$LIBS -pthread -lpthread" + ;; +esac + +AM_CONDITIONAL(BUILD_MACOSX, test x$macosx_found = xyes) + +AC_SUBST(MSPLUGINS_CFLAGS) +AC_SUBST(MSPLUGINS_LIBS) + +AC_CHECK_LIB(rt,clock_gettime,[LIBS="$LIBS -lrt"]) + +dnl ********************************* +dnl various checks for soundcard apis +dnl ********************************* + +found_sound=no + +AC_CHECK_HEADERS(soundcard.h sys/soundcard.h machine/soundcard.h sys/audio.h) +if test "${ac_cv_header_sys_soundcard_h}" = "yes" || \ + test "${ac_cv_header_soundcard_h}" = "yes" || \ + test "${ac_cv_header_sys_audio_h}" = "yes" || \ + test "${ac_cv_header_machine_soundcard_h}" = "yes"; then + found_sound=yes +fi + +AM_CONDITIONAL(BUILD_OSS, test x$found_sound = xyes) + +dnl conditionnal build of ALSA support +AC_ARG_ENABLE(alsa, + [ --enable-alsa Turn on alsa native support compiling], + [case "${enableval}" in + yes) alsa=true ;; + no) alsa=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-alsa) ;; + esac],[alsa=true]) + +if test "$alsa" = "true"; then + AC_CHECK_HEADERS(alsa/asoundlib.h, + [ AC_CHECK_LIB(asound,snd_pcm_open, + [ ALSA_LIBS="-lasound" + found_sound=yes + AC_DEFINE(__ALSA_ENABLED__,1,[defined if alsa support is available]) + alsa_enabled=true + ]) + ] + ) +fi +AC_SUBST(ALSA_LIBS) + +AM_CONDITIONAL(BUILD_ALSA, test x$alsa_enabled = xtrue) + + +AC_ARG_ENABLE(artsc, + [ --enable-artsc Turn on artsc (kde) sound input/output (auto) ], + [case "${enableval}" in + yes) artsc=true ;; + no) artsc=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-artsc) ;; + esac],[artsc=true]) + +arts_enabled=false + +if test "$artsc" = "true" ; then + + dnl check for arts (kde sound daemon) support + PKG_CHECK_MODULES(ARTS, [artsc],[ + dnl New detection + arts_enabled=true + ],[ + dnl Old detection + if test x$artsc = xtrue ; then + AC_CHECK_HEADERS(kde/artsc/artsc.h, + [ AC_CHECK_LIB(artsc,arts_init, + [ ARTS_LIBS="-lartsc" + arts_enabled=true + ]) + ] + ) + fi + AC_SUBST(ARTS_LIBS) + ]) +fi + +if test x$arts_enabled = xtrue; then + found_sound=yes + AC_DEFINE(__ARTS_ENABLED__,1,[defined if arts support is available]) +fi + +AM_CONDITIONAL(BUILD_ARTS, test x$arts_enabled = xtrue) + +AC_ARG_ENABLE(portaudio, + [ --enable-portaudio Turn on portaudio native support compiling], + [case "${enableval}" in + yes) portaudio=true ;; + no) portaudio=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-portaudio) ;; + esac],[portaudio=false]) + +if test "$portaudio" = "true"; then + AC_CHECK_HEADERS(portaudio.h, + [ AC_CHECK_LIB(portaudio,Pa_Initialize, + [ PORTAUDIO_LIBS="-lportaudio" + found_sound=yes + AC_DEFINE(__PORTAUDIO_ENABLED__,1,[defined if portaudio support is available]) + portaudio_enabled=true + ]) + ] + ) +fi + +AC_SUBST(PORTAUDIO_LIBS) +AM_CONDITIONAL(BUILD_PORTAUDIO, test x$portaudio_enabled = xtrue) + +AC_ARG_ENABLE(macsnd, + [ --enable-macsnd Turn on native macosx sound support], + [case "${enableval}" in + yes) macsnd=true ;; + no) macsnd=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-macsnd) ;; + esac],[macsnd=false]) + +if test "$macsnd" = "true"; then + AC_DEFINE(__MACSND_ENABLED__,1,[defined if native macosx sound support is available]) + macsnd_enabled=true + found_sound=yes +fi + +AM_CONDITIONAL(BUILD_MACSND, test x$macsnd_enabled = xtrue) + +AC_ARG_ENABLE(macaqsnd, + [ --enable-macaqsnd Turn on native macosx Audio Queue sound support], + [case "${enableval}" in + yes) macaqsnd=true ;; + no) macaqsnd=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-macaqsnd) ;; + esac],[macaqsnd=false]) + +if test "$macsnd" = "true"; then + AC_DEFINE(__MAC_AQ_ENABLED__,1,[defined if native macosx AQ sound support is available]) + macaqsnd_enabled=true + found_sound=yes +fi + +AM_CONDITIONAL(BUILD_MACAQSND, test x$macaqsnd_enabled = xtrue) + +dnl Check for samplerate libraries +dnl Check for jack libraries (sound output plugin) +PKG_CHECK_MODULES(JACK,jack >= 0.15.0, +[ + dnl we' found jack devel files + PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.0.13, + [AC_DEFINE(__JACK_ENABLED__,1,[Jack support]) + found_sound=yes + jack_found=yes] , + [echo "libsamplerate not found, jack support disabled."]) + AC_SUBST(SAMPLERATE_CFLAGS) + AC_SUBST(SAMPLERATE_LIBS) +], +[echo "No jack support."] ) + +if test x$jack_found = xno ; then + dnl reset flags + JACK_CFLAGS= + JACK_LIBS= + SAMPLERATE_CFLAGS= + SAMPLERATE_LIBS= +fi + +AC_SUBST(JACK_CFLAGS) +AC_SUBST(JACK_LIBS) + +if test "$found_sound" = "no"; then + AC_MSG_ERROR([Could not find a support sound driver API]) +fi + + +dnl ************************************* +dnl check for various codecs libraries +dnl ************************************* + +dnl check for installed version of speex +PKG_CHECK_MODULES(SPEEX, speex >= 1.1.12, + [ AC_DEFINE(HAVE_SPEEX_NOISE,1,[tells whether the noise arg of speex_echo_cancel can be used]) ], + [try_other_speex=yes] +) +PKG_CHECK_MODULES(SPEEX, speex >= 1.1.6, build_speex=yes) +PKG_CHECK_MODULES(SPEEXDSP, speexdsp >= 1.2beta3, + [SPEEX_LIBS="$SPEEX_LIBS $SPEEXDSP_LIBS"], [ + AC_MSG_NOTICE([No speexdsp library found.]) +] +) +AC_SUBST(SPEEX_CFLAGS) +AC_SUBST(SPEEX_LIBS) +AM_CONDITIONAL(BUILD_SPEEX, test x$build_speex = xyes ) + +dnl check for gsm +build_gsm=no +AC_ARG_WITH( gsm, + [ --with-gsm Sets the installation prefix of gsm codec library [default=/usr] ], + [ gsmdir=${withval}],[ gsmdir=/usr ]) + +if test x"$gsmdir" != xno ; then + test x"$gmsdir" = xyes && gsmdir=/usr + MS_CHECK_DEP([gsm codec],[GSM],[${gsmdir}/include], + [${gsmdir}/lib],[gsm/gsm.h],[gsm],[gsm_create]) + if test "$GSM_found" = "yes" ; then + build_gsm=yes + fi +else + build_gsm=no +fi +AM_CONDITIONAL(BUILD_GSM, test x$build_gsm = xyes ) + +build_resample=false +AC_CHECK_LIB(resample,resample_open,[LIBS="$LIBS -lresample"; build_resample=yes]) +AM_CONDITIONAL(BUILD_RESAMPLE, test x$build_resample = xyes ) + +MS_CHECK_VIDEO +AM_CONDITIONAL(BUILD_VIDEO, test "$video" = "true") +AM_CONDITIONAL(BUILD_THEORA, test "$have_theora" = "yes") + +dnl ********************************************* +dnl setup oRTP dependency +dnl ********************************************* +AC_ARG_ENABLE(external-ortp, + [ --enable-external-ortp Use external oRTP library], + [case "${enableval}" in + yes) external_ortp=true ;; + no) external_ortp=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-external-ortp) ;; + esac],[external_ortp=false]) + +if test "$external_ortp" = 'false'; then + if test -e $srcdir/../oRTP/include/ortp/ortp.h ; then + echo "building from linphone source tree, using ../oRTP/include/ortp/ortp.h" + ORTP_CFLAGS="-I\$(top_srcdir)/../oRTP/include" + ORTP_LIBS="\$(top_builddir)/../oRTP/src/libortp.la" + if test x$ac_cv_c_bigendian = xyes ; then + ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN" + fi + else + external_ortp=true + fi +fi +if test "$external_ortp" = 'true'; then + PKG_CHECK_MODULES(ORTP, ortp >= 0.9.0, , + [ AC_MSG_ERROR([Couldn't find ortp library]) ] ) +fi +AC_SUBST(ORTP_CFLAGS) +AC_SUBST(ORTP_LIBS) + + +dnl check dlopen support in headers and libraries, so that we can use mediastreamer plugins +AC_CHECK_HEADERS(dlfcn.h) +have_dlopen=false +AC_CHECK_LIB(dl,dlopen,[LIBS="$LIBS -ldl"; have_dlopen=true]) +AC_CHECK_FUNC(dlopen,[have_dlopen=true]) +if test "$have_dlopen" = "true" ; then + AC_DEFINE(HAVE_DLOPEN,1,[Defined if dlopen() is availlable]) +fi + +dnl check various things +AC_FUNC_ALLOCA + +dnl define path of plugins: +PACKAGE_PLUGINS_DIR=`eval echo $prefix/lib/mediastreamer/plugins` +AC_DEFINE_UNQUOTED(PACKAGE_PLUGINS_DIR, "$PACKAGE_PLUGINS_DIR" ,[path of plugins]) +AC_SUBST(PACKAGE_PLUGINS_DIR) + +PACKAGE_DATA_DIR=`eval echo $prefix/share` +AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "$PACKAGE_DATA_DIR" ,[path of data]) +AC_SUBST(PACKAGE_DATA_DIR) + +dnl check for video4linux headers +AC_CHECK_HEADERS(linux/videodev.h linux/videodev2.h) + + +dnl ################################################## +dnl # Check for ESP Packager +dnl ################################################## + +AC_PATH_PROG(EPM,epm,false) +AC_PATH_PROG(MKEPMLIST,mkepmlist,false) +AC_PATH_PROG(EPMINSTALL,epminstall,false) +AM_CONDITIONAL(WITH_EPM,test $EPM != false && test $MKEPMLIST != false && test $EPMINSTALL != false) + + +# Preferred packaging system, as per EPM terminology +case $target in +*-*-linux*) + if test -f /etc/debian_version ; then + EPM_PKG_EXT=deb + else + EPM_PKG_EXT=rpm + fi + ;; +*-hp-hpux*) + EPM_PKG_EXT=depot.gz;; +*-dec-osf*) + EPM_PKG_EXT=setld;; +esac +AC_SUBST(EPM_PKG_EXT) + +# System software User & Group names +case $target in +*-*-linux*) + SYS_USER=root + SYS_GROUP=root + ;; +*-*-hpux*|*-dec-osf*) + SYS_USER=bin + SYS_GROUP=bin + ;; +esac +AC_SUBST(SYS_USER) +AC_SUBST(SYS_GROUP) + +# CPU Architecture +case $target_cpu in +i?86) ARCH=i386;; +*) ARCH=$target_cpu;; +esac +AC_SUBST(ARCH) + +# Various other packaging variables, that can be over-ridden ad `make +# package' time +SUMMARY="A mediastreaming library." +AC_SUBST(SUMMARY) +PACKAGER=anonymous +AC_SUBST(PACKAGER) +LICENSE=GPL +AC_SUBST(LICENSE) +VENDOR=Linphone +AC_SUBST(VENDOR) +RELEASE=1 +AC_SUBST(RELEASE) + + +AC_OUTPUT( +Makefile +include/Makefile +include/mediastreamer2/Makefile +src/Makefile +tests/Makefile +build/Makefile +build/win32native/Makefile +build/win32-novideo/Makefile +build/wince/Makefile +mediastreamer.pc +mediastreamer2.spec +help/Makefile +help/DoxyFile +help/doxygen.dox +) diff --git a/linphone/mediastreamer2/help/DoxyFile.in b/linphone/mediastreamer2/help/DoxyFile.in new file mode 100644 index 000000000..e14d2f4e4 --- /dev/null +++ b/linphone/mediastreamer2/help/DoxyFile.in @@ -0,0 +1,233 @@ +# Doxyfile 1.4.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = mediastreamer2 +PROJECT_NUMBER = @MEDIASTREAMER_VERSION@ +OUTPUT_DIRECTORY = help/doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = help/ \ + include/ +FILE_PATTERNS = *.h \ + *.c \ + *.dox +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = . +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = include/ +INCLUDE_FILE_PATTERNS = *.h +PREDEFINED = DOXYGEN +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/linphone/mediastreamer2/help/Makefile.am b/linphone/mediastreamer2/help/Makefile.am new file mode 100644 index 000000000..25e92d69d --- /dev/null +++ b/linphone/mediastreamer2/help/Makefile.am @@ -0,0 +1,4 @@ + +EXTRA_DIST = DoxyFile.in doxygen.dox.in + +all: DoxyFile doxygen.dox diff --git a/linphone/mediastreamer2/help/doxygen.dox.in b/linphone/mediastreamer2/help/doxygen.dox.in new file mode 100644 index 000000000..422876b86 --- /dev/null +++ b/linphone/mediastreamer2/help/doxygen.dox.in @@ -0,0 +1,187 @@ +/** + * @mainpage + * Project Website: http://savannah.gnu.org/projects/linphone + * + * @verbinclude README + * + */ + +/** + * @defgroup mediastreamer2 mediastreamer2 library - a modular sound and video processing and streaming + * @brief mediastreamer2 Version @MEDIASTREAMER_VERSION@ + * + * @see http://savannah.gnu.org/projects/linphone + * + * @section what_is_it What is mediastreamer2 + * + * mediastreamer2 is a powerful engine to make audio and video streams. + * mediastreamer2 is GPL (COPYING). Please understand the licencing details + * before using it! + * + * For any use of this library beyond the rights granted to you by the + * GPL license, please contact antisip at . + * + * @section definitions Some definitions. + * + * Filter: + * A filter is a mediastreamer2 component that process data. A filter + * have 0 or several INPUT pins and 0 or several OUTPUT pins. + * Here is a list of possible use of filters: + *
+ *   capture audio or video data.
+ *   play audio or display video data.
+ *   send or receive RTP data.
+ *   encode or decode audio or video data.
+ *   transform (resize video, resample audio...) data.
+ *   duplicate any kind of data.
+ *   mix audio/video data.
+ * 
+ * Graph: + * A graph is a manager of filters connected together. It will transfer + * data from OUTPUT pins to INPUT pins and will be responsible for + * running filters. + * + * @section when_do_i_use_mediastreamer2 How do I use mediastremer2? + * + * Mediastreamer2 can be used for a lot of different purpose. The primary + * use is to manage RTP audio and video session. You will need to use + * the API to build filters, link them together in a graph. Then the + * ticker API will help you to start and stop the graph. + * + * Basic graph sample: + * + *
+ *  AUDIO CAPTURE   -->   ENCODE  -->     RTP
+ *      FILTER      -->   FILTER  -->    FILTER
+ * 
+ * + * + * The above graph is composed of three filters. The first one has no input: + * tt captures audio data directly from the drivers and provide it to the + * OUTPUT pin. This data is sent to the INPUT pin of the encoder which of + * course encode the data and send it to its OUTPUT pin. This pin is connected + * to the INPUT pin of a filter capable to build and send RTP packets. + * + * The modular design helps you to encode in many different format just by + * replacing the "ENCODE FILTER" with another one. mediastreamer2 contains + * internal support for g711u, g711a, speex and gsm. You can add new encoding + * format by implementing new filters which can then be dynamically loaded. + * + * @section list_of_filters List of existing filters. + * + * mediastreamer2 already provides a large set of filters. Here is a complete + * list of built-in filters. + * + *
+ * All supported platforms:
+ *   RTP receiver
+ *   RTP sender
+ *   tee (duplicate data)
+ *
+ * Audio Filters:
+ *   audio capture
+ *   audio playback
+ *     mme API (windows)
+ *     alsa API (linux)
+ *     oss API (linux)
+ *     arts API (linux)
+ *     portaudio API (macosx and other)
+ *   macsnd API (native macosx API -please do more testing...-)
+ *   several audio encoder/decoder: PCMU, PCMA, speex, gsm
+ *   wav file reader.
+ *   wav file recorder.
+ *   resampler.
+ *   conference bridge.
+ *   volume analyser.
+ *   acoustic echo canceller.
+ *   dtmf generation filter.
+ *
+ * Video Filters:
+ *   video capture
+ *     v4w API (windows)
+ *     directshow API (windows)
+ *     video4linux API (linux)
+ *   video display
+ *     v4w API (windows)
+ *     SDL API (linux, macosx...)
+ *   several audio encoder/decoder: H263-1998, MP4V-ES, theora
+ *   image resizer.
+ *   format converter. (RBG24, I420...)
+ *
+ * Plugin Filters:
+ *  iLBC decoder/encoder.
+ * 
+ * + * @section what_thanks Thanks + * + * Thanks to all the contributors and to all bug reporters. + * Enjoy mediastreamer2! + * + */ + +/** + * @defgroup mediastreamer2_api Mediastreamer2 API + * @brief All API to manage mediastreamer2 library. + * + */ + +/** + * @defgroup mediastreamer2_init Init API - manage mediastreamer2 library. + * @ingroup mediastreamer2_api + * @brief Init API to manage mediastreamer2 library. + * + * This file provide the API needed to initialize + * and reset the mediastreamer2 library. + */ + +/** + * @defgroup mediastreamer2_soundcard Sound Card API - manage audio capture/play filters. + * @ingroup mediastreamer2_api + * @brief Sound Card API to manage audio capture/play filters. + * + * This file provide the API needed to manage + * soundcard filters. + */ + +/** + * @defgroup mediastreamer2_filter Filter API - manage mediastreamer2 filters. + * @ingroup mediastreamer2_api + * @brief Filter API to manage mediastreamer2 filters. + * + * This file provide the API needed to create, link, + * unlink, find and destroy filter. + * + * It also provides definitions if you wish to implement + * your own filters. + */ + +/** + * @defgroup mediastreamer2_ticker Ticker API - manage mediastreamer2 graphs. + * @ingroup mediastreamer2_api + * @brief Ticker API to manage mediastreamer2 graphs. + * + * This file provide the API needed to create, start + * and stop a graph. + */ + + +/** + * @page mediastreamer2_readme README + * @verbinclude README + */ + +/** + * @page mediastreamer2_install INSTALL + * @verbinclude INSTALL + */ + +/** + * @page mediastreamer2_license COPYING + * @verbinclude COPYING + */ + +/** + * @page mediastreamer2_changelog ChangeLog + * @verbinclude ChangeLog + */ + diff --git a/linphone/mediastreamer2/help/ht0-buildagraph.dox b/linphone/mediastreamer2/help/ht0-buildagraph.dox new file mode 100644 index 000000000..9acc3b0e5 --- /dev/null +++ b/linphone/mediastreamer2/help/ht0-buildagraph.dox @@ -0,0 +1,153 @@ +/** + * @defgroup howto0_samplegraph Howto 1: build a sample audio graph. + * @ingroup mediastreamer2 + +

Initialize mediastreamer2

+ +When using mediastreamer2, your first task is to initialize the +library: + +
+	##include 
+
+	int i;
+
+	i=ms_init();
+	if (i!=0)
+	  return -1;
+
+
+ +Mediastreamer2 provides internal components which are called filters. Those +filters must be linked together so that OUTPUT from one filter is sent to +INPUT of the other filters. + +Usually, filters are used for processing audio or video data. They could +capture data, play/draw data, encode/decode data, mix data (conference), +transform data (echo canceller). One of the most important filter is the +RTP filters that are able to send and receive RTP data. + +

Graph sample

+ +If you are using mediastreamer2, you probably want to do Voice Over IP +and get a graph providing a 2 way communication. This 2 graphs are very +simple: + +This first graph shows the filters needed to capture data from a sound +card, encode them and send it through an RTP session. + +
+             AUDIO    ->    ENCODER   ->   RTP
+            CAPTURE   ->              ->  SENDER
+
+ + This second graph shows the filters needed to receive data from an RTP +session decode it and send it to the playback device. + +
+        RTP      ->    DECODER   ->   DTMF       ->   AUDIO
+       RECEIVER  ->              ->  GENERATION  ->  PLAYBACK
+
+ +

Code to initiate the filters of the Graph sample

+ +Note that the NULL/error checks are not done for better reading. +To build the graph, you'll need some information: you need to +select the sound card and of course have an RTP session created +with oRTP. + +
+	MSSndCard *sndcard;
+	sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
+
+        /* audio capture filter */
+	MSFilter *soundread=ms_snd_card_create_reader(captcard);
+	MSFilter *soundwrite=ms_snd_card_create_writer(playcard);
+
+	MSFilter *encoder=ms_filter_create_encoder("PCMU");
+	MSFilter *decoder=ms_filter_create_decoder("PCMU");
+
+	MSFilter *rtpsend=ms_filter_new(MS_RTP_SEND_ID);
+	MSFilter *rtprecv=ms_filter_new(MS_RTP_RECV_ID);
+
+	RtpSession *rtp_session = *** your_ortp_session *** ;
+
+	ms_filter_call_method(rtpsend,MS_RTP_SEND_SET_SESSION,rtp_session);
+	ms_filter_call_method(rtprecv,MS_RTP_RECV_SET_SESSION,rtp_session);
+
+	MSFilter *dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);
+
+ +In most cases, the above graph is not enough: you'll need to configure +filter's options. As an example, you need to set sampling rate of sound +cards' filters: + +
+        int sr = 8000;
+	int chan=1;
+	ms_filter_call_method(soundread,MS_FILTER_SET_SAMPLE_RATE,&sr);
+	ms_filter_call_method(soundwrite,MS_FILTER_SET_SAMPLE_RATE,&sr);
+	ms_filter_call_method(stream->encoder,MS_FILTER_SET_SAMPLE_RATE,&sr);
+	ms_filter_call_method(stream->decoder,MS_FILTER_SET_SAMPLE_RATE,&sr);
+
+	ms_filter_call_method(soundwrite,MS_FILTER_SET_NCHANNELS, &chan);
+
+        /* if you have some fmtp parameters (from SDP for example!)
+        char *fmtp1 = ** get your fmtp line **;
+        char *fmtp2 = ** get your fmtp line **;
+	ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)fmtp1);
+	ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)fmtp2);
+
+ + +

Code to link the filters and run the graph sample

+ +
+	ms_filter_link(stream->soundread,0,stream->encoder,0);
+	ms_filter_link(stream->encoder,0,stream->rtpsend,0);
+
+	ms_filter_link(stream->rtprecv,0,stream->decoder,0);
+	ms_filter_link(stream->decoder,0,stream->dtmfgen,0);
+	ms_filter_link(stream->dtmfgen,0,stream->soundwrite,0);	
+
+ +Then you need to 'attach' the filters to a ticker. A ticker is a graph +manager responsible for running filters. + +In the above case, there is 2 independant graph within the ticker: you +need to attach the first element of each graph (the one that does not +contains any INPUT pins) + +
+	/* create ticker */
+	MSTicker *ticker=ms_ticker_new();
+
+	ms_ticker_attach(ticker,soundread);
+	ms_ticker_attach(ticker,rtprecv);
+
+ +

Code to unlink the filters and stop the graph sample

+ +
+	ms_ticker_detach(ticker,soundread);
+	ms_ticker_detach(ticker,rtprecv);
+
+	ms_filter_unlink(stream->soundread,0,stream->encoder,0);
+	ms_filter_unlink(stream->encoder,0,stream->rtpsend,0);
+
+	ms_filter_unlink(stream->rtprecv,0,stream->decoder,0);
+	ms_filter_unlink(stream->decoder,0,stream->dtmfgen,0);
+	ms_filter_unlink(stream->dtmfgen,0,stream->soundwrite,0);
+
+	if (rtp_session!=NULL) rtp_session_destroy(rtp_session);
+	if (rtpsend!=NULL) ms_filter_destroy(rtpsend);
+	if (rtprecv!=NULL) ms_filter_destroy(rtprecv);
+	if (soundread!=NULL) ms_filter_destroy(soundread);
+	if (soundwrite!=NULL) ms_filter_destroy(soundwrite);
+	if (encoder!=NULL) ms_filter_destroy(encoder);
+	if (decoder!=NULL) ms_filter_destroy(decoder);
+	if (dtmfgen!=NULL) ms_filter_destroy(dtmfgen);
+	if (ticker!=NULL) ms_ticker_destroy(ticker);
+
+ +*/ \ No newline at end of file diff --git a/linphone/mediastreamer2/include/.cvsignore b/linphone/mediastreamer2/include/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/mediastreamer2/include/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/mediastreamer2/include/Makefile.am b/linphone/mediastreamer2/include/Makefile.am new file mode 100644 index 000000000..c7b5d9316 --- /dev/null +++ b/linphone/mediastreamer2/include/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=mediastreamer2 diff --git a/linphone/mediastreamer2/include/mediastreamer2/.cvsignore b/linphone/mediastreamer2/include/mediastreamer2/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/mediastreamer2/include/mediastreamer2/Makefile.am b/linphone/mediastreamer2/include/mediastreamer2/Makefile.am new file mode 100644 index 000000000..9671e50e7 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/Makefile.am @@ -0,0 +1,26 @@ + +mediastreamer2_includedir=$(includedir)/mediastreamer2 + +mediastreamer2_include_HEADERS= ice.h \ + msfilter.h \ + msqueue.h \ + mscommon.h \ + allfilters.h \ + msticker.h \ + msrtp.h \ + dtmfgen.h \ + msfilerec.h \ + msfileplayer.h \ + mssndcard.h \ + mediastream.h \ + msv4l.h \ + msvideo.h \ + waveheader.h \ + msvideoout.h \ + msvolume.h \ + mstee.h \ + rfc3984.h \ + mswebcam.h + +EXTRA_DIST=$(mediastreamer2_include_HEADERS) + diff --git a/linphone/mediastreamer2/include/mediastreamer2/allfilters.h b/linphone/mediastreamer2/include/mediastreamer2/allfilters.h new file mode 100644 index 000000000..15659cfb2 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/allfilters.h @@ -0,0 +1,88 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef allfilters_h +#define allfilters_h + +/* this is the enum where to add your own filter id. +Please take care of always add new IDs at the end in order to preserve the binary interface*/ +/*this id is used for type checking of methods, events with filters */ +/*it must be used also to create filters */ +typedef enum MSFilterId{ + MS_FILTER_NOT_SET_ID, + MS_FILTER_PLUGIN_ID, /* no type checking will be performed on plugins */ + MS_FILTER_BASE_ID, + MS_ALSA_READ_ID, + MS_ALSA_WRITE_ID, + MS_OSS_READ_ID, + MS_OSS_WRITE_ID, + MS_ULAW_ENC_ID, + MS_ULAW_DEC_ID, + MS_ALAW_ENC_ID, + MS_ALAW_DEC_ID, + MS_RTP_SEND_ID, + MS_RTP_RECV_ID, + MS_FILE_PLAYER_ID, + MS_FILE_REC_ID, + MS_DTMF_GEN_ID, + MS_SPEEX_ENC_ID, + MS_SPEEX_DEC_ID, + MS_GSM_ENC_ID, + MS_GSM_DEC_ID, + MS_V4L_ID, + MS_SDL_OUT_ID, + MS_H263_ENC_ID, + MS_H263_DEC_ID, + MS_ARTS_READ_ID, + MS_ARTS_WRITE_ID, + MS_WINSND_READ_ID, + MS_WINSND_WRITE_ID, + MS_SPEEX_EC_ID, + MS_PIX_CONV_ID, + MS_TEE_ID, + MS_SIZE_CONV_ID, + MS_CONF_ID, + MS_THEORA_ENC_ID, + MS_THEORA_DEC_ID, + MS_PASND_READ_ID, + MS_PASND_WRITE_ID, + MS_MPEG4_ENC_ID, + MS_MPEG4_DEC_ID, + MS_MJPEG_DEC_ID, + MS_JOIN_ID, + MS_RESAMPLE_ID, + MS_VIDEO_OUT_ID, + MS_VOLUME_ID, + MS_SNOW_DEC_ID, + MS_SNOW_ENC_ID, + MS_CA_READ_ID, + MS_CA_WRITE_ID, +#ifdef __DIRECTSOUND_ENABLED__ + MS_WINSNDDS_READ_ID, + MS_WINSNDDS_WRITE_ID, +#endif + MS_STATIC_IMAGE_ID, + MS_V4L2_CAPTURE_ID, + MS_H263_OLD_DEC_ID, + MS_H263_OLD_ENC_ID, + MS_MIRE_ID +} MSFilterId; + + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/dtmfgen.h b/linphone/mediastreamer2/include/mediastreamer2/dtmfgen.h new file mode 100644 index 000000000..0ea4b930d --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/dtmfgen.h @@ -0,0 +1,29 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef dtmfgen_h +#define dtmfgen_h + +#include "msfilter.h" + +#define MS_DTMF_GEN_PUT MS_FILTER_METHOD(MS_DTMF_GEN_ID,0,const char) + +extern MSFilterDesc ms_dtmf_gen_desc; + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/ice.h b/linphone/mediastreamer2/include/mediastreamer2/ice.h new file mode 100644 index 000000000..76d5aa2aa --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/ice.h @@ -0,0 +1,74 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ice_hh +#define ice_hh + +#include "ortp/stun_udp.h" +#include "ortp/stun.h" +#include "ortp/ortp.h" + +/* list of state for STUN connectivity check */ +#define TESTING 0 +#define WAITING 1 +#define RECV_VALID 2 +#define SEND_VALID 3 +#define VALID 4 +#define INVALID 5 + +struct SdpCandidate { + int seq_num; + char candidate_id[256]; + char password[256]; + + char fqdn[256]; + char ipaddr[256]; + int port; + + int mapped_port; + int peer_derived; /* 0: local 1: stun 2: turn */ + + float priority; +}; + +struct CandidatePair { + + struct SdpCandidate local_candidate; + struct SdpCandidate remote_candidate; + int max_sn; + int min_sn; + char max_candidate_id[256]; + UInt128 tid; + int connectivity_check; +}; + + +#ifdef __cplusplus +extern "C"{ +#endif + +int ice_sound_send_stun_request(RtpSession *session, struct CandidatePair *remote_candidates, int round); + +int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_candidates, OrtpEvent *evt); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/mediastream.h b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h new file mode 100644 index 000000000..a6dfa28cd --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h @@ -0,0 +1,155 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#ifndef MEDIASTREAM_H +#define MEDIASTREAM_H + +#include "msfilter.h" +#include "msticker.h" +#include "mssndcard.h" +#include "mswebcam.h" +#include "ortp/ortp.h" +#include "ortp/event.h" + +struct _AudioStream +{ + MSTicker *ticker; + RtpSession *session; + MSFilter *soundread; + MSFilter *soundwrite; + MSFilter *encoder; + MSFilter *decoder; + MSFilter *rtprecv; + MSFilter *rtpsend; + MSFilter *dtmfgen; + MSFilter *ec;/*echo canceler*/ + unsigned int last_packet_count; + time_t last_packet_time; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _AudioStream AudioStream; + +struct _RingStream +{ + MSTicker *ticker; + MSFilter *source; + MSFilter *sndwrite; +}; + +typedef struct _RingStream RingStream; + + + +/* start a thread that does sampling->encoding->rtp_sending|rtp_receiving->decoding->playing */ +AudioStream *audio_stream_start (RtpProfile * prof, int locport, const char *remip, + int remport, int payload_type, int jitt_comp, bool_t echo_cancel); + +AudioStream *audio_stream_start_with_sndcards(RtpProfile * prof, int locport, const char *remip4, int remport, int payload_type, int jitt_comp, MSSndCard *playcard, MSSndCard *captcard, bool_t echocancel); + +int audio_stream_start_with_files (AudioStream * stream, RtpProfile * prof, + const char *remip, int remport, int rem_rtcp_port, + int pt, int jitt_comp, + const char * infile, const char * outfile); + +void audio_stream_play(AudioStream *st, const char *name); +void audio_stream_record(AudioStream *st, const char *name); + +void audio_stream_set_rtcp_information(AudioStream *st, const char *cname, const char *tool); + +/* those two function do the same as audio_stream_start() but in two steps +this is useful to make sure that sockets are open before sending an invite; +or to start to stream only after receiving an ack.*/ +AudioStream *audio_stream_new(int locport, bool_t ipv6); +int audio_stream_start_now(AudioStream * stream, RtpProfile * prof, const char *remip, int remport, int rem_rtcp_port, int payload_type, int jitt_comp,MSSndCard *playcard, MSSndCard *captcard, bool_t echo_cancel); +void audio_stream_set_relay_session_id(AudioStream *stream, const char *relay_session_id); +/*returns true if we are still receiving some data from remote end in the last timeout seconds*/ +bool_t audio_stream_alive(AudioStream * stream, int timeout); + +/* stop the above process*/ +void audio_stream_stop (AudioStream * stream); + +RingStream *ring_start (const char * file, int interval, MSSndCard *sndcard); +RingStream *ring_start_with_cb(const char * file, int interval, MSSndCard *sndcard, MSFilterNotifyFunc func, void * user_data); +void ring_stop (RingStream * stream); + + +/* send a dtmf */ +int audio_stream_send_dtmf (AudioStream * stream, char dtmf); + +void audio_stream_set_default_card(int cardindex); + + +/***************** + Video Support + *****************/ + + +struct _VideoStream +{ + MSTicker *ticker; + RtpSession *session; + MSFilter *source; + MSFilter *predec; + MSFilter *pixconv; + MSFilter *tee; + MSFilter *output; + MSFilter *encoder; + MSFilter *decoder; + MSFilter *rtprecv; + MSFilter *rtpsend; + OrtpEvQueue *evq; + bool_t adapt_bitrate; +}; + + +typedef struct _VideoStream VideoStream; +VideoStream *video_stream_new(int locport, bool_t use_ipv6); +void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno); +int video_stream_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int rem_rtcp_port, + int payload, int jitt_comp, MSWebCam *device); +void video_stream_set_relay_session_id(VideoStream *stream, const char *relay_session_id); +void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const char *tool); +/*function to call periodically to handle various events */ +void video_stream_iterate(VideoStream *stream); +void video_stream_send_vfu(VideoStream *stream); +void video_stream_stop (VideoStream * stream); + +VideoStream * video_preview_start(MSWebCam *device); +void video_preview_stop(VideoStream *stream); + +int video_stream_recv_only_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, int payload, int jitt_comp); +int video_stream_send_only_start(VideoStream * stream, RtpProfile *profile, const char *remip, int remport, + int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *device); +void video_stream_recv_only_stop(VideoStream *stream); +void video_stream_send_only_stop(VideoStream *stream); + + +bool_t ms_is_ipv6(const char *address); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/mscommon.h b/linphone/mediastreamer2/include/mediastreamer2/mscommon.h new file mode 100644 index 000000000..122070508 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/mscommon.h @@ -0,0 +1,210 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef mscommon_h +#define mscommon_h + +#include + +#define ms_malloc ortp_malloc +#define ms_malloc0 ortp_malloc0 +#define ms_realloc ortp_realloc +#define ms_new ortp_new +#define ms_new0 ortp_new0 +#define ms_free ortp_free +#define ms_strdup ortp_strdup +#define ms_strdup_printf ortp_strdup_printf + +#define ms_mutex_t ortp_mutex_t +#define ms_mutex_init ortp_mutex_init +#define ms_mutex_destroy ortp_mutex_destroy +#define ms_mutex_lock ortp_mutex_lock +#define ms_mutex_unlock ortp_mutex_unlock + +#define ms_cond_t ortp_cond_t +#define ms_cond_init ortp_cond_init +#define ms_cond_wait ortp_cond_wait +#define ms_cond_signal ortp_cond_signal +#define ms_cond_broadcast ortp_cond_broadcast +#define ms_cond_destroy ortp_cond_destroy + +#ifdef WIN32 +static inline void ms_debug(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_DEBUG, fmt, args); + va_end (args); +} +#else +#ifdef DEBUG +static inline void ms_debug(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_DEBUG, fmt, args); + va_end (args); +} +#else +#define ms_debug(...) +#endif +#endif + + + +#define ms_message ortp_message +#define ms_warning ortp_warning +#define ms_error ortp_error +#define ms_fatal ortp_fatal + +#define ms_return_val_if_fail(_expr_,_ret_)\ + if (!(_expr_)) { ms_error("assert "#_expr_ "failed"); return (_ret_);} + +#define ms_return_if_fail(_expr_) \ + if (!(_expr_)){ ms_error("assert "#_expr_ "failed"); return ;} + +#define ms_thread_t ortp_thread_t +#define ms_thread_create ortp_thread_create +#define ms_thread_join ortp_thread_join +#define ms_thread_exit ortp_thread_exit + +struct _MSList { + struct _MSList *next; + struct _MSList *prev; + void *data; +}; + +typedef struct _MSList MSList; + + +#define ms_list_next(elem) ((elem)->next) + + +#ifdef __cplusplus +extern "C"{ +#endif + +MSList * ms_list_append(MSList *elem, void * data); +MSList * ms_list_prepend(MSList *elem, void * data); +MSList * ms_list_free(MSList *elem); +MSList * ms_list_concat(MSList *first, MSList *second); +MSList * ms_list_remove(MSList *first, void *data); +int ms_list_size(const MSList *first); +void ms_list_for_each(const MSList *list, void (*func)(void *)); +void ms_list_for_each2(const MSList *list, void (*func)(void *, void *), void *user_data); +MSList *ms_list_remove_link(MSList *list, MSList *elem); +MSList *ms_list_find(MSList *list, void *data); +MSList *ms_list_find_custom(MSList *list, int (*compare_func)(const void *, const void*), void *user_data); +void * ms_list_nth_data(const MSList *list, int index); +int ms_list_position(const MSList *list, MSList *elem); +int ms_list_index(const MSList *list, void *data); +MSList *ms_list_insert_sorted(MSList *list, void *data, int (*compare_func)(const void *, const void*)); +MSList *ms_list_insert(MSList *list, MSList *before, void *data); +MSList *ms_list_copy(const MSList *list); + +#undef MIN +#define MIN(a,b) ((a)>(b) ? (b) : (a)) +#undef MAX +#define MAX(a,b) ((a)>(b) ? (a) : (b)) + +/** + * @file mscommon.h + * @brief mediastreamer2 mscommon.h include file + * + * This file provide the API needed to initialize + * and reset the mediastreamer2 library. + * + */ + +/** + * @defgroup mediastreamer2_init Init API - manage mediastreamer2 library. + * @ingroup mediastreamer2_api + * @{ + */ + + +/** + * Initialize the mediastreamer2 library. + * + * This must be called once before calling any other API. + */ +void ms_init(void); + +/** + * Load plugins from a specific directory. + * + * @param directory A directory where plugins library are available. + * + * Returns: >0 if successfull, 0 if not plugins loaded, -1 otherwise. + */ +int ms_load_plugins(const char *directory); + +/** + * Release resource allocated in the mediastreamer2 library. + * + * This must be called once before closing program. + */ +void ms_exit(void); + +struct _MSSndCardDesc; + +/** + * This can be called when new sound cards have been added. + * + * Warning: It must NOT be called if one filter is currently created. + * You have to unlink, destroy everything before doing this. + * + * @param snd_desc A MSSndCardDesc description. + */ +void ms_reload_snd_card(struct _MSSndCardDesc *snd_desc); + +void ms_sleep(int seconds); + +/** + * The max payload size allowed. + * Filters that generate data that can be sent through RTP should make packets + * whose size is below ms_get_payload_max_size(). + * The default value is 1440 computed as the standart internet MTU minus IPv6 header, + * UDP header and RTP header. As IPV4 header is smaller than IPv6 header, this + * value works for both. + * +**/ +int ms_get_payload_max_size(); + +void ms_set_payload_max_size(int size); + +/** + * Returns the network Max Transmission Unit to reach destination_host. + * This will attempt to send one or more big packets to destination_host, to a random port. + * Those packets are filled with zeroes. +**/ +int ms_discover_mtu(const char *destination_host); + +/** + * Set mediastreamer default mtu, used to compute the default RTP max payload size. + * This function will call ms_set_payload_max_size(mtu-[ipv6 header size]). +**/ +void ms_set_mtu(int mtu); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msfileplayer.h b/linphone/mediastreamer2/include/mediastreamer2/msfileplayer.h new file mode 100644 index 000000000..8e1931448 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msfileplayer.h @@ -0,0 +1,43 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef msfileplayer_h +#define msfileplayer_h + +#include "msfilter.h" + + +/*methods*/ +#define MS_FILE_PLAYER_OPEN MS_FILTER_METHOD(MS_FILE_PLAYER_ID,0,const char*) +#define MS_FILE_PLAYER_START MS_FILTER_METHOD_NO_ARG(MS_FILE_PLAYER_ID,1) +#define MS_FILE_PLAYER_STOP MS_FILTER_METHOD_NO_ARG(MS_FILE_PLAYER_ID,2) +#define MS_FILE_PLAYER_CLOSE MS_FILTER_METHOD_NO_ARG(MS_FILE_PLAYER_ID,3) +/* set loop mode: + -1: no looping, + 0: loop at end of file, + x>0, loop after x miliseconds after eof +*/ +#define MS_FILE_PLAYER_LOOP MS_FILTER_METHOD(MS_FILE_PLAYER_ID,4,int) +#define MS_FILE_PLAYER_DONE MS_FILTER_METHOD(MS_FILE_PLAYER_ID,5,int) +#define MS_FILE_PLAYER_BIG_BUFFER MS_FILTER_METHOD(MS_FILE_PLAYER_ID,6,int) + +/*events*/ +#define MS_FILE_PLAYER_EOF MS_FILTER_EVENT_NO_ARG(MS_FILE_PLAYER_ID,0) + +#endif + diff --git a/linphone/mediastreamer2/include/mediastreamer2/msfilerec.h b/linphone/mediastreamer2/include/mediastreamer2/msfilerec.h new file mode 100644 index 000000000..b46cb38ac --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msfilerec.h @@ -0,0 +1,33 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef msfilerec_h +#define msfilerec_h + +#include "msfilter.h" + +extern MSFilterDesc ms_file_rec_desc; + +#define MS_FILE_REC_OPEN MS_FILTER_METHOD(MS_FILE_REC_ID,0,const char) +#define MS_FILE_REC_START MS_FILTER_METHOD_NO_ARG(MS_FILE_REC_ID,1) +#define MS_FILE_REC_STOP MS_FILTER_METHOD_NO_ARG(MS_FILE_REC_ID,2) +#define MS_FILE_REC_CLOSE MS_FILTER_METHOD_NO_ARG(MS_FILE_REC_ID,3) + + + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msfilter.h b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h new file mode 100644 index 000000000..e4712a964 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msfilter.h @@ -0,0 +1,405 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef msfilter_h +#define msfilter_h + +#include "mscommon.h" +#include "msqueue.h" +#include "allfilters.h" + +/** + * @file msfilter.h + * @brief mediastreamer2 msfilter.h include file + * + * This file provide the API needed to create, link, + * unlink, find and destroy filter. + * + * It also provides definitions if you wish to implement + * your own filters. + * + */ + +/** + * @defgroup mediastreamer2_filter Filter API - manage mediastreamer2 filters. + * @ingroup mediastreamer2_api + * @{ + */ + +/** + * Structure for filter's methods (init, preprocess, process, postprocess, uninit). + * @var MSFilterFunc + */ +typedef void (*MSFilterFunc)(struct _MSFilter *f); + +/** + * Structure for filter's methods used to set filter's options. + * @var MSFilterMethodFunc + */ +typedef int (*MSFilterMethodFunc)(struct _MSFilter *f, void *arg); + +/** + * Structure for filter's methods used as a callback to notify events. + * @var MSFilterNotifyFunc + */ +typedef void (*MSFilterNotifyFunc)(void *userdata , unsigned int id, void *arg); + +struct _MSFilterMethod{ + int id; + MSFilterMethodFunc method; +}; + + +/** + * Structure for holding filter's methods to set filter's options. + * @var MSFilterMethod + */ +typedef struct _MSFilterMethod MSFilterMethod; + +enum _MSFilterCategory{ + MS_FILTER_OTHER, + MS_FILTER_ENCODER, + MS_FILTER_DECODER +}; + +/** + * Structure to describe filter's category. + *
+ *     MS_FILTER_OTHER
+ *     MS_FILTER_ENCODER
+ *     MS_FILTER_DECODER
+ * 
+ * @var MSFilterCategory + */ +typedef enum _MSFilterCategory MSFilterCategory; + +struct _MSFilterDesc{ + MSFilterId id; /* the id declared in allfilters.h */ + const char *name; /* filter name */ + const char *text; /*some descriptive text*/ + MSFilterCategory category; + const char *enc_fmt; /* must be set if MS_FILTER_ENCODER/MS_FILTER_DECODER */ + int ninputs; /*number of inputs */ + int noutputs; /*number of outputs */ + MSFilterFunc init; + MSFilterFunc preprocess; /* called once before processing */ + MSFilterFunc process; /* called every tick to do the filter's job*/ + MSFilterFunc postprocess; /*called once after processing */ + MSFilterFunc uninit; + MSFilterMethod *methods; +}; + +/** + * Structure for filter's description. + * @var MSFilterDesc + */ +typedef struct _MSFilterDesc MSFilterDesc; + +struct _MSFilter{ + MSFilterDesc *desc; + /*protected attributes */ + ms_mutex_t lock; + MSQueue **inputs; + MSQueue **outputs; + MSFilterNotifyFunc notify; + void *notify_ud; + void *data; + struct _MSTicker *ticker; + /*private attributes */ + uint32_t last_tick; + bool_t seen; +}; + + + +/** + * Structure to create/link/unlink/destroy filter's object. + * @var MSFilter + */ +typedef struct _MSFilter MSFilter; + + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * Register a filter description. (plugins use only!) + * + * When you build your own plugin, this method will + * add the encoder or decoder to the internal list + * of supported codec. Then, this plugin can be used + * transparently from the application. + * + * ms_filter_get_encoder, ms_filter_get_decoder, + * ms_filter_create_encoder, ms_filter_create_decoder + * and ms_filter_codec_supported + * can then be used as if the codec was internally. + * supported. + * + * @param desc a filter description. + */ +void ms_filter_register(MSFilterDesc *desc); + +/** + * Retrieve encoders according to codec name. + * + * Internal supported codecs: + * PCMU, PCMA, speex, gsm + * Existing Public plugins: + * iLBC + * + * @param mime A string indicating the codec. + * + * Returns: a MSFilterDesc if successfull, NULL otherwise. + */ +MSFilterDesc * ms_filter_get_encoder(const char *mime); + +/** + * Retrieve decoders according to codec name. + * + * Internal supported codecs: + * PCMU, PCMA, speex, gsm + * Existing Public plugins: + * iLBC + * + * @param mime A string indicating the codec. + * + * Returns: a MSFilterDesc if successfull, NULL otherwise. + */ +MSFilterDesc * ms_filter_get_decoder(const char *mime); + +/** + * Create encoder filter according to codec name. + * + * Internal supported codecs: + * PCMU, PCMA, speex, gsm + * Existing Public plugins: + * iLBC + * + * @param mime A string indicating the codec. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +MSFilter * ms_filter_create_encoder(const char *mime); + +/** + * Create decoder filter according to codec name. + * + * Internal supported codecs: + * PCMU, PCMA, speex, gsm + * Existing Public plugins: + * iLBC + * + * @param mime A string indicating the codec. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +MSFilter * ms_filter_create_decoder(const char *mime); + +/** + * Check if a encode or decode filter exists for a codec name. + * + * Internal supported codecs: + * PCMU, PCMA, speex, gsm + * Existing Public plugins: + * iLBC + * + * @param mime A string indicating the codec. + * + * Returns: TRUE if successfull, FALSE otherwise. + */ +bool_t ms_filter_codec_supported(const char *mime); + +/** + * Create decoder filter according to a filter's MSFilterId. + * + * @param id A MSFilterId identifier for the filter. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +MSFilter *ms_filter_new(MSFilterId id); + +/** + * Create decoder filter according to a filter's name. + * + * @param name A name for the filter. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +MSFilter *ms_filter_new_from_name(const char *name); + +/** + * Create decoder filter according to a filter's description. + * + * The primary use is to create your own filter's in your + * application and avoid registration inside mediastreamer2. + * + * @param desc A MSFilterDesc for the filter. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc); + +/** + * Link one OUTPUT pin from a filter to an INPUT pin of another filter. + * + * All data coming from the OUTPUT pin of one filter will be distributed + * to the INPUT pin of the second filter. + * + * @param f1 A MSFilter object containing the OUTPUT pin + * @param pin1 An index of an OUTPUT pin. + * @param f2 A MSFilter object containing the INPUT pin + * @param pin2 An index of an INPUT pin. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2); + +/** + * Unlink one OUTPUT pin from a filter to an INPUT pin of another filter. + * + * @param f1 A MSFilter object containing the OUTPUT pin + * @param pin1 An index of an OUTPUT pin. + * @param f2 A MSFilter object containing the INPUT pin + * @param pin2 An index of an INPUT pin. + * + * Returns: a MSFilter if successfull, NULL otherwise. + */ +int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2); + +/** + * Call a filter's method to set or get options. + * + * @param f A MSFilter object. + * @param id A private filter ID for the option. + * @param arg A private user data for the filter. + * + * Returns: 0 if successfull, -1 otherwise. + */ +int ms_filter_call_method(MSFilter *f, unsigned int id, void *arg); + +/** + * Call a filter's method to set options. + * + * @param f A MSFilter object. + * @param id A private filter ID for the option. + * + * Returns: 0 if successfull, -1 otherwise. + */ +int ms_filter_call_method_noarg(MSFilter *f, unsigned int id); + +/** + * Set a callback on filter's to be informed of private filter's event. + * + * @param f A MSFilter object. + * @param fn A MSFilterNotifyFunc that will be called. + * @param userdata A pointer to private data. + * + * Returns: 0 if successfull, -1 otherwise. + */ +void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata); + +/** + * Get MSFilterId's filter. + * + * @param f A MSFilter object. + * + * Returns: MSFilterId if successfull, -1 otherwise. + */ +MSFilterId ms_filter_get_id(MSFilter *f); + +/** + * Destroy a filter object. + * + * @param f A MSFilter object. + * + */ +void ms_filter_destroy(MSFilter *f); + +/* I define the id taking the lower bits of the address of the MSFilterDesc object, +the method index (_cnt_) and the argument size */ +/* I hope using this to avoid type mismatch (calling a method on the wrong filter)*/ +#define MS_FILTER_METHOD_ID(_id_,_cnt_,_argsize_) \ + ( (((unsigned long)(_id_)) & 0xFFFF)<<16 | (_cnt_<<8) | (_argsize_ & 0xFF )) + +#define MS_FILTER_METHOD(_id_,_count_,_argtype_) \ + MS_FILTER_METHOD_ID(_id_,_count_,sizeof(_argtype_)) + +#define MS_FILTER_METHOD_NO_ARG(_id_,_count_) \ + MS_FILTER_METHOD_ID(_id_,_count_,0) + + +#define MS_FILTER_BASE_METHOD(_count_,_argtype_) \ + MS_FILTER_METHOD_ID(MS_FILTER_BASE_ID,_count_,sizeof(_argtype_)) + +#define MS_FILTER_BASE_METHOD_NO_ARG(_count_) \ + MS_FILTER_METHOD_ID(MS_FILTER_BASE_ID,_count_,0) + +#define MS_FILTER_EVENT(_id_,_count_,_argtype_) \ + MS_FILTER_METHOD_ID(_id_,_count_,sizeof(_argtype_)) + +#define MS_FILTER_EVENT_NO_ARG(_id_,_count_)\ + MS_FILTER_METHOD_ID(_id_,_count_,0) + +/* some MSFilter base methods:*/ +#define MS_FILTER_SET_SAMPLE_RATE MS_FILTER_BASE_METHOD(0,int) +#define MS_FILTER_GET_SAMPLE_RATE MS_FILTER_BASE_METHOD(1,int) +#define MS_FILTER_SET_BITRATE MS_FILTER_BASE_METHOD(2,int) +#define MS_FILTER_GET_BITRATE MS_FILTER_BASE_METHOD(3,int) +#define MS_FILTER_GET_NCHANNELS MS_FILTER_BASE_METHOD(5,int) +#define MS_FILTER_SET_NCHANNELS MS_FILTER_BASE_METHOD(6,int) +#define MS_FILTER_ADD_FMTP MS_FILTER_BASE_METHOD(7,const char) +#define MS_FILTER_ADD_ATTR MS_FILTER_BASE_METHOD(8,const char) +#define MS_FILTER_SET_MTU MS_FILTER_BASE_METHOD(9,int) +#define MS_FILTER_GET_MTU MS_FILTER_BASE_METHOD(10,int) + +#define MS_FILTER_SET_FRAMESIZE MS_FILTER_BASE_METHOD(11,int) +#define MS_FILTER_SET_FILTERLENGTH MS_FILTER_BASE_METHOD(12,int) +#define MS_FILTER_SET_OUTPUT_SAMPLE_RATE MS_FILTER_BASE_METHOD(13,int) +#define MS_FILTER_ENABLE_DIRECTMODE MS_FILTER_BASE_METHOD(14,int) +#define MS_FILTER_ENABLE_VAD MS_FILTER_BASE_METHOD(15,int) +#define MS_FILTER_GET_STAT_DISCARDED MS_FILTER_BASE_METHOD(16,int) +#define MS_FILTER_GET_STAT_MISSED MS_FILTER_BASE_METHOD(17,int) +#define MS_FILTER_GET_STAT_INPUT MS_FILTER_BASE_METHOD(18,int) +#define MS_FILTER_GET_STAT_OUTPUT MS_FILTER_BASE_METHOD(19,int) +#define MS_FILTER_ENABLE_AGC MS_FILTER_BASE_METHOD(20,int) + +/** @} */ + +/*private methods*/ +void ms_filter_process(MSFilter *f); +void ms_filter_preprocess(MSFilter *f, struct _MSTicker *t); +void ms_filter_postprocess(MSFilter *f); +bool_t ms_filter_inputs_have_data(MSFilter *f); +void ms_filter_notify(MSFilter *f, unsigned int id, void *arg); +void ms_filter_notify_no_arg(MSFilter *f, unsigned int id); +#define ms_filter_lock(f) ms_mutex_lock(&(f)->lock) +#define ms_filter_unlock(f) ms_mutex_unlock(&(f)->lock) +void ms_filter_unregister_all(void); + +#ifdef __cplusplus +} +#endif + +/* used by awk script in Makefile.am to generate alldescs.c */ +#define MS_FILTER_DESC_EXPORT(desc) + + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msqueue.h b/linphone/mediastreamer2/include/mediastreamer2/msqueue.h new file mode 100644 index 000000000..2c819ff83 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msqueue.h @@ -0,0 +1,113 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef MSQUEUE_H +#define MSQUEUE_H + +#include "ortp/str_utils.h" + +/* for the moment these are stupid queues limited to one element*/ + +typedef struct _MSCPoint{ + struct _MSFilter *filter; + int pin; +} MSCPoint; + +typedef struct _MSQueue +{ + queue_t q; + MSCPoint prev; + MSCPoint next; +}MSQueue; + + +MSQueue * ms_queue_new(struct _MSFilter *f1, int pin1, struct _MSFilter *f2, int pin2 ); + +static inline mblk_t *ms_queue_get(MSQueue *q){ + return getq(&q->q); +} + +static inline void ms_queue_put(MSQueue *q, mblk_t *m){ + putq(&q->q,m); + return; +} + +static inline mblk_t * ms_queue_peek_last(MSQueue *q){ + return qlast(&q->q); +} + +static inline bool_t ms_queue_empty(MSQueue *q){ + return qempty(&q->q); +} + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*init a queue on stack*/ +void ms_queue_init(MSQueue *q); + +void ms_queue_flush(MSQueue *q); + +void ms_queue_destroy(MSQueue *q); + +#define mblk_set_timestamp_info(m,ts) (m)->reserved1=(ts); +#define mblk_get_timestamp_info(m) ((m)->reserved1) +#define mblk_set_marker_info(m,bit) (m)->reserved2=((m)->reserved2|bit) +#define mblk_get_marker_info(m) ((m)->reserved2&0x1) +#define mblk_set_rate(m,bits) (m)->reserved2=((m)->reserved2|(bits)<<1) +#define mblk_get_rate(m) (((m)->reserved2>>1)&0x3) +#define mblk_set_payload_type(m,bits) (m)->reserved2=((m)->reserved2|(bits<<3)) +#define mblk_get_payload_type(m) (((m)->reserved2>>3)&0xFF) + + +struct _MSBufferizer{ + queue_t q; + int size; +}; + +typedef struct _MSBufferizer MSBufferizer; + +/*allocates and initialize */ +MSBufferizer * ms_bufferizer_new(void); + +/*initialize in memory */ +void ms_bufferizer_init(MSBufferizer *obj); + +void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m); + +/* put every mblk_t from q, into the bufferizer */ +void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q); + +int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen); + +/* returns the number of bytes available in the bufferizer*/ +static inline int ms_bufferizer_get_avail(MSBufferizer *obj){ + return obj->size; +} + +void ms_bufferizer_uninit(MSBufferizer *obj); + +void ms_bufferizer_destroy(MSBufferizer *obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msrtp.h b/linphone/mediastreamer2/include/mediastreamer2/msrtp.h new file mode 100644 index 000000000..76a4e1c3b --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msrtp.h @@ -0,0 +1,48 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#ifndef msrtp_hh +#define msrtp_hh + +#include "msfilter.h" +#include "ice.h" +#include "ortp/ortp.h" + +#define MS_RTP_RECV_SET_SESSION MS_FILTER_METHOD(MS_RTP_RECV_ID,0,RtpSession*) + +#define MS_RTP_SEND_SET_SESSION MS_FILTER_METHOD(MS_RTP_SEND_ID,0,RtpSession*) + +#define MS_RTP_SEND_SEND_DTMF MS_FILTER_METHOD(MS_RTP_SEND_ID,1,const char) + +#define MS_RTP_RECV_SET_CANDIDATEPAIRS MS_FILTER_METHOD(MS_RTP_RECV_ID,1,struct CandidatePair*) + +#define MS_RTP_SEND_SET_CANDIDATEPAIRS MS_FILTER_METHOD(MS_RTP_SEND_ID,2,struct CandidatePair*) + +#define MS_RTP_SEND_MUTE_MIC MS_FILTER_METHOD_NO_ARG(MS_RTP_SEND_ID,3) + +#define MS_RTP_SEND_UNMUTE_MIC MS_FILTER_METHOD_NO_ARG(MS_RTP_SEND_ID,4) + +#define MS_RTP_SEND_SET_RELAY_SESSION_ID MS_FILTER_METHOD(MS_RTP_RECV_ID,5,const char *) + + +extern MSFilterDesc ms_rtp_send_desc; +extern MSFilterDesc ms_rtp_recv_desc; + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h b/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h new file mode 100644 index 000000000..9a8995b82 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/mssndcard.h @@ -0,0 +1,357 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef sndcard_h +#define sndcard_h + +#include "mscommon.h" + +/** + * @file mssndcard.h + * @brief mediastreamer2 mssndcard.h include file + * + * This file provide the API needed to manage + * soundcard filters. + * + */ + +/** + * @defgroup mediastreamer2_soundcard Sound Card API - manage audio capture/play filters. + * @ingroup mediastreamer2_api + * @{ + */ + +struct _MSSndCardManager{ + MSList *cards; +}; + +/** + * Structure for sound card manager object. + * @var MSSndCardManager + */ +typedef struct _MSSndCardManager MSSndCardManager; + +enum _MSSndCardMixerElem{ + MS_SND_CARD_MASTER, + MS_SND_CARD_PLAYBACK, + MS_SND_CARD_CAPTURE +}; + +/** + * Structure for sound card mixer values. + * @var MSSndCardMixerElem + */ +typedef enum _MSSndCardMixerElem MSSndCardMixerElem; + +enum _MSSndCardCapture { + MS_SND_CARD_MIC, + MS_SND_CARD_LINE +}; + +/** + * Structure for sound card capture source values. + * @var MSSndCardCapture + */ +typedef enum _MSSndCardCapture MSSndCardCapture; + +struct _MSSndCard; + +typedef void (*MSSndCardDetectFunc)(MSSndCardManager *obj); +typedef void (*MSSndCardInitFunc)(struct _MSSndCard *obj); +typedef void (*MSSndCardUninitFunc)(struct _MSSndCard *obj); +typedef void (*MSSndCardSetLevelFunc)(struct _MSSndCard *obj, MSSndCardMixerElem e, int percent); +typedef void (*MSSndCardSetCaptureFunc)(struct _MSSndCard *obj, MSSndCardCapture e); +typedef int (*MSSndCardGetLevelFunc)(struct _MSSndCard *obj, MSSndCardMixerElem e); +typedef struct _MSFilter * (*MSSndCardCreateReaderFunc)(struct _MSSndCard *obj); +typedef struct _MSFilter * (*MSSndCardCreateWriterFunc)(struct _MSSndCard *obj); +typedef struct _MSSndCard * (*MSSndCardDuplicateFunc)(struct _MSSndCard *obj); + +struct _MSSndCardDesc{ + const char *driver_type; + MSSndCardDetectFunc detect; + MSSndCardInitFunc init; + MSSndCardSetLevelFunc set_level; + MSSndCardGetLevelFunc get_level; + MSSndCardSetCaptureFunc set_capture; + MSSndCardCreateReaderFunc create_reader; + MSSndCardCreateWriterFunc create_writer; + MSSndCardUninitFunc uninit; + MSSndCardDuplicateFunc duplicate; + +}; + +/** + * Structure for sound card description object. + * @var MSSndCardDesc + */ +typedef struct _MSSndCardDesc MSSndCardDesc; + +#define MS_SND_CARD_CAP_CAPTURE (1) +#define MS_SND_CARD_CAP_PLAYBACK (1<<1) + +struct _MSSndCard{ + MSSndCardDesc *desc; + char *name; + char *id; + unsigned int capabilities; + void *data; +}; + +/** + * Structure for sound card object. + * @var MSSndCard + */ +typedef struct _MSSndCard MSSndCard; + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * @defgroup mediastreamer2_soundcardmanager Sound Card Manager API + * @ingroup mediastreamer2_soundcard + * @{ + */ + +/** + * Retreive a sound card manager object. + * + * Returns: MSSndCardManager if successfull, NULL otherwise. + */ +MSSndCardManager * ms_snd_card_manager_get(void); + +/** + * Destroy a sound card manager object. + * + */ +void ms_snd_card_manager_destroy(void); + +/** + * Retreive a sound card object based on its name. + * + * @param m A sound card manager containing sound cards. + * @param id A name for card to search. + * + * Returns: MSSndCard if successfull, NULL otherwise. + */ +MSSndCard * ms_snd_card_manager_get_card(MSSndCardManager *m, const char *id); + +/** + * Retreive the default sound card object. + * + * @param m A sound card manager containing sound cards. + * + * Returns: MSSndCard if successfull, NULL otherwise. + */ +MSSndCard * ms_snd_card_manager_get_default_card(MSSndCardManager *m); + +/** + * Retreive the list of sound card objects. + * + * @param m A sound card manager containing sound cards. + * + * Returns: MSList of cards if successfull, NULL otherwise. + */ +const MSList * ms_snd_card_manager_get_list(MSSndCardManager *m); + +/** + * Add a sound card object in a sound card manager's list. + * + * @param m A sound card manager containing sound cards. + * @param c A sound card object. + * + */ +void ms_snd_card_manager_add_card(MSSndCardManager *m, MSSndCard *c); + +/** + * Register a sound card description in a sound card manager. + * + * @param m A sound card manager containing sound cards. + * @param desc A sound card description object. + * + */ +void ms_snd_card_manager_register_desc(MSSndCardManager *m, MSSndCardDesc *desc); + +/** @} */ + +/** + * @defgroup mediastreamer2_soundcardfilter Sound Card Filter API + * @ingroup mediastreamer2_soundcard + * @{ + */ + +/** + * Create an INPUT filter based on the selected sound card. + * + * @param obj A sound card object. + * + * Returns: A MSFilter if successfull, NULL otherwise. + */ +struct _MSFilter * ms_snd_card_create_reader(MSSndCard *obj); + +/** + * Create an OUPUT filter based on the selected sound card. + * + * @param obj A sound card object. + * + * Returns: A MSFilter if successfull, NULL otherwise. + */ +struct _MSFilter * ms_snd_card_create_writer(MSSndCard *obj); + +/** + * Create a new sound card object. + * + * @param desc A sound card description object. + * + * Returns: MSSndCard if successfull, NULL otherwise. + */ +MSSndCard * ms_snd_card_new(MSSndCardDesc *desc); + +/** + * Destroy sound card object. + * + * @param obj A MSSndCard object. + */ +void ms_snd_card_destroy(MSSndCard *obj); + +/** + * Duplicate a sound card object. + * + * This helps to open several time a sound card. + * + * @param card A sound card object. + * + * Returns: MSSndCard if successfull, NULL otherwise. + */ +MSSndCard * ms_snd_card_dup(MSSndCard *card); + +/** + * Retreive a sound card's driver type string. + * + * Internal driver types are either: "OSS, ALSA, WINSND, PASND, CA" + * + * @param obj A sound card object. + * + * Returns: a string if successfull, NULL otherwise. + */ +const char *ms_snd_card_get_driver_type(const MSSndCard *obj); + +/** + * Retreive a sound card's name. + * + * @param obj A sound card object. + * + * Returns: a string if successfull, NULL otherwise. + */ +const char *ms_snd_card_get_name(const MSSndCard *obj); + +/** + * Retreive sound card's name ($driver_type: $name). + * + * @param obj A sound card object. + * + * Returns: A string if successfull, NULL otherwise. + */ +const char *ms_snd_card_get_string_id(MSSndCard *obj); + + +/** + * Retreive sound card's capabilities. + * + *
+ *   MS_SND_CARD_CAP_CAPTURE
+ *   MS_SND_CARD_CAP_PLAYBACK
+ *   MS_SND_CARD_CAP_CAPTURE|MS_SND_CARD_CAP_PLAYBACK
+ * 
+ * + * @param obj A sound card object. + * + * Returns: A unsigned int if successfull, 0 otherwise. + */ +unsigned int ms_snd_card_get_capabilities(const MSSndCard *obj); + +/** + * Set some mixer level value. + * + *
+ *   MS_SND_CARD_MASTER,
+ *   MS_SND_CARD_PLAYBACK,
+ *   MS_SND_CARD_CAPTURE
+ * 
+ * Note: not implemented on all sound card filters. + * + * @param obj A sound card object. + * @param e A sound card mixer object. + * @param percent A volume level. + * + */ +void ms_snd_card_set_level(MSSndCard *obj, MSSndCardMixerElem e, int percent); + +/** + * Get some mixer level value. + * + *
+ *   MS_SND_CARD_MASTER,
+ *   MS_SND_CARD_PLAYBACK,
+ *   MS_SND_CARD_CAPTURE
+ * 
+ * Note: not implemented on all sound card filters. + * + * @param obj A sound card object. + * @param e A sound card mixer object. + * + * Returns: A int if successfull, 0 otherwise. + */ +int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e); + +/** + * Set some source for capture. + * + *
+ *   MS_SND_CARD_MIC,
+ *   MS_SND_CARD_LINE
+ * 
+ * Note: not implemented on all sound card filters. + * + * @param obj A sound card object. + * @param c A sound card capture value. + * + * Returns: A int if successfull, 0 otherwise. + */ +void ms_snd_card_set_capture(MSSndCard *obj, MSSndCardCapture c); + +/** + * Create a alsa card with user supplied pcm name and mixer name. + * @param pcmdev The pcm device name following alsa conventions (ex: plughw:0) + * @param mixdev The mixer device name following alsa conventions. + * + * Returns: a MSSndCard object, NULL if alsa support is not available. + */ +MSSndCard * ms_alsa_card_new_custom(const char *pcmdev, const char *mixdev); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/mstee.h b/linphone/mediastreamer2/include/mediastreamer2/mstee.h new file mode 100644 index 000000000..dd418bfda --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/mstee.h @@ -0,0 +1,30 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef mstee_h +#define mstee_h + +#include "msfilter.h" + +/*mute/unmute some outputs of the MSTee */ +#define MS_TEE_UNMUTE MS_FILTER_METHOD(MS_TEE_ID,0,int) +#define MS_TEE_MUTE MS_FILTER_METHOD(MS_TEE_ID,1,int) + + + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msticker.h b/linphone/mediastreamer2/include/mediastreamer2/msticker.h new file mode 100644 index 000000000..d13bc2e30 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msticker.h @@ -0,0 +1,145 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#ifndef MS_TICKER_H +#define MS_TICKER_H + + +#include "msfilter.h" +#include "mscommon.h" + +/** + * @file msticker.h + * @brief mediastreamer2 msticker.h include file + * + * This file provide the API needed to create, start + * and stop a graph. + * + */ + +/** + * @defgroup mediastreamer2_ticker Ticker API - manage mediastreamer2 graphs. + * @ingroup mediastreamer2_api + * @{ + */ + + +/** + * Structure for method getting time in miliseconds from an external source. + * @var MSTickerTimeFunc + */ +typedef uint64_t (*MSTickerTimeFunc)(void *); + +struct _MSTicker +{ + ms_mutex_t lock; + ms_cond_t cond; + MSList *execution_list; /* the list of source filters to be executed.*/ + ms_thread_t thread; /* the thread ressource*/ + int interval; /* in miliseconds*/ + int exec_id; + uint32_t ticks; + uint64_t time; /* a time since the start of the ticker expressed in milisec*/ + uint64_t orig; /* a relative time to take in account difference between time base given by consecutive get_cur_time_ptr() functions.*/ + MSTickerTimeFunc get_cur_time_ptr; + void *get_cur_time_data; + bool_t run; /* flag to indicate whether the ticker must be run or not */ +#ifdef WIN32_TIMERS + HANDLE TimeEvent; +#endif +}; + +/** + * Structure for ticker object. + * @var MSTicker + */ +typedef struct _MSTicker MSTicker; + + +#ifdef __cplusplus +extern "C"{ +#endif + + +/** + * Create a ticker that will be used to start + * and stop a graph. + * + * Returns: MSTicker * if successfull, NULL otherwise. + */ +MSTicker *ms_ticker_new(void); + +/** + * Attach a chain of filters to a ticker. + * The processing chain will be executed until ms_ticker_detach + * will be called. + * + * @param ticker A #MSTicker object. + * @param f A #MSFilter object. + * + * Returns: 0 if successfull, -1 otherwise. + */ +int ms_ticker_attach(MSTicker *ticker,MSFilter *f); + +/** + * Dettach a chain of filters to a ticker. + * The processing chain will no more be executed. + * + * @param ticker A #MSTicker object. + * @param f A #MSFilter object. + * + * + * Returns: 0 if successfull, -1 otherwise. + */ +int ms_ticker_detach(MSTicker *ticker,MSFilter *f); + +/** + * Destroy a ticker. + * + * @param ticker A #MSTicker object. + * + */ +void ms_ticker_destroy(MSTicker *ticker); + +/** + * Destroy a ticker. + * + * @param ticker A #MSTicker object. + * @param func A replacement method for calculating "current time" + * @param user_data Any pointer to user private data. + */ +void ms_ticker_set_time_func(MSTicker *ticker, MSTickerTimeFunc func, void *user_data); + +/** + * Print on stdout all filters of a ticker. (INTERNAL: DO NOT USE) + * + * @param ticker A #MSTicker object. + */ +void ms_ticker_print_graphs(MSTicker *ticker); + +/* private functions:*/ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msv4l.h b/linphone/mediastreamer2/include/mediastreamer2/msv4l.h new file mode 100644 index 000000000..2d7056d0b --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msv4l.h @@ -0,0 +1,30 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef msv4l_h +#define msv4l_h + +#include "msfilter.h" + +#define MS_V4L_START MS_FILTER_METHOD_NO_ARG(MS_V4L_ID,0) +#define MS_V4L_STOP MS_FILTER_METHOD_NO_ARG(MS_V4L_ID,1) +#define MS_V4L_SET_DEVICE MS_FILTER_METHOD(MS_V4L_ID,2,int) +#define MS_V4L_SET_IMAGE MS_FILTER_METHOD(MS_V4L_ID,3,char) + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msvideo.h b/linphone/mediastreamer2/include/mediastreamer2/msvideo.h new file mode 100644 index 000000000..8e6d892a9 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msvideo.h @@ -0,0 +1,117 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef msvideo_h +#define msvideo_h + +#include "msfilter.h" + +/* some global constants for video MSFilter(s) */ +#define MS_VIDEO_SIZE_CIF_W 352 +#define MS_VIDEO_SIZE_CIF_H 288 +#define MS_VIDEO_SIZE_QCIF_W 176 +#define MS_VIDEO_SIZE_QCIF_H 144 +#define MS_VIDEO_SIZE_4CIF_W 704 +#define MS_VIDEO_SIZE_4CIF_H 576 + +#define MS_VIDEO_SIZE_QQVGA_W 160 +#define MS_VIDEO_SIZE_QQVGA_H 120 + +#define MS_VIDEO_SIZE_QVGA_W 320 +#define MS_VIDEO_SIZE_QVGA_H 240 + +#define MS_VIDEO_SIZE_VGA_W 640 +#define MS_VIDEO_SIZE_VGA_H 480 + +#define MS_VIDEO_SIZE_720P_W 1280 +#define MS_VIDEO_SIZE_720P_H 720 + + +#define MS_VIDEO_SIZE_NS1_W 324 +#define MS_VIDEO_SIZE_NS1_H 248 + +#define MS_VIDEO_SIZE_MAX_W MS_VIDEO_SIZE_720P_W +#define MS_VIDEO_SIZE_MAX_H MS_VIDEO_SIZE_720P_H + +typedef struct MSVideoSize{ + int width,height; +} MSVideoSize; + +typedef struct MSRect{ + int x,y,w,h; +} MSRect; + +#define MS_VIDEO_SIZE_CIF (MSVideoSize){MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H} +#define MS_VIDEO_SIZE_QCIF (MSVideoSize){MS_VIDEO_SIZE_QCIF_W,MS_VIDEO_SIZE_QCIF_H} +#define MS_VIDEO_SIZE_4CIF (MSVideoSize){MS_VIDEO_SIZE_4CIF_W,MS_VIDEO_SIZE_4CIF_H} + +#define MS_VIDEO_SIZE_QQVGA (MSVideoSize){MS_VIDEO_SIZE_QQVGA_W,MS_VIDEO_SIZE_QQVGA_H} +#define MS_VIDEO_SIZE_QVGA (MSVideoSize){MS_VIDEO_SIZE_QVGA_W,MS_VIDEO_SIZE_QVGA_H} +#define MS_VIDEO_SIZE_VGA (MSVideoSize){MS_VIDEO_SIZE_VGA_W,MS_VIDEO_SIZE_VGA_H} + +#define MS_VIDEO_SIZE_720P (MSVideoSize){MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H} + +#define MS_VIDEO_SIZE_NS1 (MSVideoSize){MS_VIDEO_SIZE_NS1_W,MS_VIDEO_SIZE_NS1_H} + +typedef enum{ + MS_YUV420P, + MS_YUYV, + MS_RGB24, + MS_MJPEG, + MS_UYVY, + MS_YUY2 /* -> same as MS_YUYV */ +}MSPixFmt; + +typedef struct _MSPicture{ + int w,h; + uint8_t *planes[4]; /*we usually use 3 planes, 4th is for compatibility */ + int strides[4]; /*with ffmpeg's swscale.h */ +}MSPicture; + +typedef struct _MSPicture YuvBuf; /*for backward compatibility*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +int ms_pix_fmt_to_ffmpeg(MSPixFmt fmt); +MSPixFmt ffmpeg_pix_fmt_to_ms(int fmt); +void ms_ffmpeg_check_init(void); +int yuv_buf_init_from_mblk(MSPicture *buf, mblk_t *m); +void yuv_buf_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, int w, int h); +mblk_t * yuv_buf_alloc(MSPicture *buf, int w, int h); +void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[], + uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi); +#ifdef __cplusplus +} +#endif + +#define MS_FILTER_SET_VIDEO_SIZE MS_FILTER_BASE_METHOD(100,MSVideoSize) +#define MS_FILTER_GET_VIDEO_SIZE MS_FILTER_BASE_METHOD(101,MSVideoSize) + +#define MS_FILTER_SET_PIX_FMT MS_FILTER_BASE_METHOD(102,MSPixFmt) +#define MS_FILTER_GET_PIX_FMT MS_FILTER_BASE_METHOD(103,MSPixFmt) + +#define MS_FILTER_SET_FPS MS_FILTER_BASE_METHOD(104,float) +#define MS_FILTER_GET_FPS MS_FILTER_BASE_METHOD(105,float) + +/* request a video-fast-update (=I frame for H263,MP4V-ES) to a video encoder*/ +#define MS_FILTER_REQ_VFU MS_FILTER_BASE_METHOD_NO_ARG(106) + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msvideoout.h b/linphone/mediastreamer2/include/mediastreamer2/msvideoout.h new file mode 100644 index 000000000..0d2eee84d --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msvideoout.h @@ -0,0 +1,93 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef msvideoout_h +#define msvideoout_h + +#include +#include + + +struct _MSDisplay; + +typedef enum _MSDisplayEventType{ + MS_DISPLAY_RESIZE_EVENT +}MSDisplayEventType; + +typedef struct _MSDisplayEvent{ + MSDisplayEventType evtype; + int w,h; +}MSDisplayEvent; + +typedef struct _MSDisplayDesc{ + /*init requests setup of the display window at the proper size, given + in frame_buffer argument. Memory buffer (data,strides) must be fulfilled + at return. init() might be called several times upon screen resize*/ + bool_t (*init)(struct _MSDisplay *, MSPicture *frame_buffer); + void (*lock)(struct _MSDisplay *);/*lock before writing to the framebuffer*/ + void (*unlock)(struct _MSDisplay *);/*unlock after writing to the framebuffer*/ + void (*update)(struct _MSDisplay *); /*display the picture to the screen*/ + void (*uninit)(struct _MSDisplay *); + bool_t (*pollevent)(struct _MSDisplay *, MSDisplayEvent *ev); +}MSDisplayDesc; + +typedef struct _MSDisplay{ + MSDisplayDesc *desc; + long window_id; /*window id if the display should use an existing window*/ + void *data; +} MSDisplay; + + +#define ms_display_init(d,fbuf) (d)->desc->init(d,fbuf) +#define ms_display_lock(d) if ((d)->desc->lock) (d)->desc->lock(d) +#define ms_display_unlock(d) if ((d)->desc->unlock) (d)->desc->unlock(d) +#define ms_display_update(d) if ((d)->desc->update) (d)->desc->update(d) +bool_t ms_display_poll_event(MSDisplay *d, MSDisplayEvent *ev); + +extern MSDisplayDesc ms_sdl_display_desc; + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(MEDIASTREAMER_STATIC) +#ifdef MEDIASTREAMER2_EXPORTS + #define MSVAR_DECLSPEC __declspec(dllexport) +#else + #define MSVAR_DECLSPEC __declspec(dllimport) +#endif +#else + #define MSVAR_DECLSPEC extern +#endif + +#ifdef __cplusplus +extern "C"{ +#endif + +MSVAR_DECLSPEC MSDisplayDesc ms_win_display_desc; + +MSDisplay *ms_display_new(MSDisplayDesc *desc); +void ms_display_set_window_id(MSDisplay *d, long window_id); +void ms_display_destroy(MSDisplay *d); + +#define MS_VIDEO_OUT_SET_DISPLAY MS_FILTER_METHOD(MS_VIDEO_OUT_ID,0,MSDisplay*) +#define MS_VIDEO_OUT_HANDLE_RESIZING MS_FILTER_METHOD_NO_ARG(MS_VIDEO_OUT_ID,1) +#define MS_VIDEO_OUT_SET_CORNER MS_FILTER_METHOD(MS_VIDEO_OUT_ID,2,int*) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/msvolume.h b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h new file mode 100644 index 000000000..e02744f04 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h @@ -0,0 +1,30 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef msvolume_h +#define msvolume_h + +#include "msfilter.h" + +/*returns a volume meter in db0 (max=0 db0)*/ +#define MS_VOLUME_GET MS_FILTER_METHOD(MS_VOLUME_ID,0,float) + +extern MSFilterDesc ms_volume_desc; + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/mswebcam.h b/linphone/mediastreamer2/include/mediastreamer2/mswebcam.h new file mode 100644 index 000000000..b0e11d599 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/mswebcam.h @@ -0,0 +1,226 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef webcam_h +#define webcam_h + +#include "mscommon.h" + +/** + * @file mswebcam.h + * @brief mediastreamer2 mswebcam.h include file + * + * This file provide the API needed to manage + * soundcard filters. + * + */ + +/** + * @defgroup mediastreamer2_soundcard Sound Card API - manage audio capture/play filters. + * @ingroup mediastreamer2_api + * @{ + */ + +struct _MSWebCamManager{ + MSList *cams; +}; + +/** + * Structure for webcam manager object. + * @var MSWebCamManager + */ +typedef struct _MSWebCamManager MSWebCamManager; + + +struct _MSWebCam; + +typedef void (*MSWebCamDetectFunc)(MSWebCamManager *obj); +typedef void (*MSWebCamInitFunc)(struct _MSWebCam *obj); +typedef void (*MSWebCamUninitFunc)(struct _MSWebCam *obj); +typedef struct _MSFilter * (*MSWebCamCreateReaderFunc)(struct _MSWebCam *obj); + +struct _MSWebCamDesc{ + const char *driver_type; + MSWebCamDetectFunc detect; + MSWebCamInitFunc init; + MSWebCamCreateReaderFunc create_reader; + MSWebCamUninitFunc uninit; +}; + +/** + * Structure for sound card description object. + * @var MSWebCamDesc + */ +typedef struct _MSWebCamDesc MSWebCamDesc; + +struct _MSWebCam{ + MSWebCamDesc *desc; + char *name; + char *id; + void *data; +}; + +/** + * Structure for sound card object. + * @var MSWebCam + */ +typedef struct _MSWebCam MSWebCam; + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * @defgroup mediastreamer2_webcammanager WebCam Manager API + * @ingroup mediastreamer2_webcam + * @{ + */ + +/** + * Retreive a webcam manager object. + * + * Returns: MSWebCamManager if successfull, NULL otherwise. + */ +MSWebCamManager * ms_web_cam_manager_get(void); + +/** + * Destroy a sound card manager object. + * + */ +void ms_web_cam_manager_destroy(void); + +/** + * Retreive a sound card object based on its name. + * + * @param m A sound card manager containing sound cards. + * @param id A name for card to search. + * + * Returns: MSWebCam if successfull, NULL otherwise. + */ +MSWebCam * ms_web_cam_manager_get_cam(MSWebCamManager *m, const char *id); + +/** + * Retreive the default sound card object. + * + * @param m A sound card manager containing sound cards. + * + * Returns: MSWebCam if successfull, NULL otherwise. + */ +MSWebCam * ms_web_cam_manager_get_default_cam(MSWebCamManager *m); + +/** + * Retreive the list of webcam objects. + * + * @param m A webcam manager containing webcams. + * + * Returns: MSList of cards if successfull, NULL otherwise. + */ +const MSList * ms_web_cam_manager_get_list(MSWebCamManager *m); + +/** + * Add a sound card object in a sound card manager's list. + * + * @param m A sound card manager containing sound cards. + * @param c A sound card object. + * + */ +void ms_web_cam_manager_add_cam(MSWebCamManager *m, MSWebCam *c); + +/** + * Register a sound card description in a sound card manager. + * + * @param m A sound card manager containing sound cards. + * @param desc A sound card description object. + * + */ +void ms_web_cam_manager_register_desc(MSWebCamManager *m, MSWebCamDesc *desc); + +/** @} */ + +/** + * @defgroup mediastreamer2_webcamfilter Sound Card Filter API + * @ingroup mediastreamer2_webcam + * @{ + */ + +/** + * Create an INPUT filter based on the selected camera. + * + * @param obj A sound card object. + * + * Returns: A MSFilter if successfull, NULL otherwise. + */ +struct _MSFilter * ms_web_cam_create_reader(MSWebCam *obj); + +/** + * Create a new webcam object. + * + * @param desc A webcam description object. + * + * Returns: MSWebCam if successfull, NULL otherwise. + */ +MSWebCam * ms_web_cam_new(MSWebCamDesc *desc); + +/** + * Destroy webcam object. + * + * @param obj A MSWebCam object. + */ +void ms_web_cam_destroy(MSWebCam *obj); + + +/** + * Retreive a webcam's driver type string. + * + * Internal driver types are either: "V4L V4LV2" + * + * @param obj A webcam object. + * + * Returns: a string if successfull, NULL otherwise. + */ +const char *ms_web_cam_get_driver_type(const MSWebCam *obj); + +/** + * Retreive a webcam's name. + * + * @param obj A webcam object. + * + * Returns: a string if successfull, NULL otherwise. + */ +const char *ms_web_cam_get_name(const MSWebCam *obj); + +/** + * Retreive webcam's id: ($driver_type: $name). + * + * @param obj A webcam object. + * + * Returns: A string if successfull, NULL otherwise. + */ +const char *ms_web_cam_get_string_id(MSWebCam *obj); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/linphone/mediastreamer2/include/mediastreamer2/rfc3984.h b/linphone/mediastreamer2/include/mediastreamer2/rfc3984.h new file mode 100644 index 000000000..aa9a45127 --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/rfc3984.h @@ -0,0 +1,60 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef rfc3984_h +#define rfc3984_h + +#include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msqueue.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef struct Rfc3984Context{ + MSQueue q; + mblk_t *m; + int maxsz; + uint32_t last_ts; + uint8_t mode; + bool_t stap_a_allowed; + uint8_t reserved; +} Rfc3984Context; + +void rfc3984_init(Rfc3984Context *ctx); + +void rfc3984_set_mode(Rfc3984Context *ctx, int mode); + +/* some stupid phones don't decode STAP-A packets ...*/ +void rfc3984_enable_stap_a(Rfc3984Context *ctx, bool_t yesno); + +/*process NALUs and pack them into rtp payloads */ +void rfc3984_pack(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts); + +/*process incoming rtp data and output NALUs, whenever possible*/ +void rfc3984_unpack(Rfc3984Context *ctx, mblk_t *im, MSQueue *naluq); + +void rfc3984_uninit(Rfc3984Context *ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/linphone/mediastreamer2/include/mediastreamer2/waveheader.h b/linphone/mediastreamer2/include/mediastreamer2/waveheader.h new file mode 100644 index 000000000..015bf65ef --- /dev/null +++ b/linphone/mediastreamer2/include/mediastreamer2/waveheader.h @@ -0,0 +1,90 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* the following code was taken from a free software utility that I don't remember the name. */ +/* sorry */ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#ifndef waveheader_h +#define waveheader_h + +/* all integer in wav header must be read in least endian order */ +static inline uint16_t swap16(uint16_t a) +{ + return ((a & 0xFF) << 8) | ((a & 0xFF00) >> 8); +} + +static inline uint32_t swap32(uint32_t a) +{ + return ((a & 0xFF) << 24) | ((a & 0xFF00) << 8) | + ((a & 0xFF0000) >> 8) | ((a & 0xFF000000) >> 24); +} + +#ifdef WORDS_BIGENDIAN +#define le_uint32(a) (swap32((a))) +#define le_uint16(a) (swap16((a))) +#define le_int16(a) ( (int16_t) swap16((uint16_t)((a))) ) +#else +#define le_uint32(a) (a) +#define le_uint16(a) (a) +#define le_int16(a) (a) +#endif + +typedef struct _riff_t { + char riff[4] ; /* "RIFF" (ASCII characters) */ + uint32_t len ; /* Length of package (binary, little endian) */ + char wave[4] ; /* "WAVE" (ASCII characters) */ +} riff_t; + +/* The FORMAT chunk */ + +typedef struct _format_t { + char fmt[4] ; /* "fmt_" (ASCII characters) */ + uint32_t len ; /* length of FORMAT chunk (always 0x10) */ + uint16_t type; /* codec type*/ + uint16_t channel ; /* Channel numbers (0x01 = mono, 0x02 = stereo) */ + uint32_t rate ; /* Sample rate (binary, in Hz) */ + uint32_t bps ; /* Average Bytes Per Second */ + uint16_t blockalign ; /*number of bytes per sample */ + uint16_t bitpspl ; /* bits per sample */ +} format_t; + +/* The DATA chunk */ + +typedef struct _data_t { + char data[4] ; /* "data" (ASCII characters) */ + int len ; /* length of data */ +} data_t; + +typedef struct _wave_header_t +{ + riff_t riff_chunk; + format_t format_chunk; + data_t data_chunk; +} wave_header_t; + + +#define wave_header_get_rate(header) le_uint32((header)->format_chunk.rate) +#define wave_header_get_channel(header) le_uint16((header)->format_chunk.channel) +#define wave_header_get_bpsmpl(header) \ + le_uint16((header)->format_chunk.blockalign) +#endif diff --git a/linphone/mediastreamer2/mediastreamer.pc.in b/linphone/mediastreamer2/mediastreamer.pc.in new file mode 100644 index 000000000..e2c6106ef --- /dev/null +++ b/linphone/mediastreamer2/mediastreamer.pc.in @@ -0,0 +1,11 @@ +# This is a comment +prefix=@prefix@ +exec_prefix=@exec_prefix@ +includedir=@includedir@ + +Name: mediastreamer +Description: A mediastreaming library for telephony applications +Depends: ortp +Version: @MEDIASTREAMER_VERSION@ +Libs: -L@libdir@ -lmediastreamer +Cflags: -I@includedir@ diff --git a/linphone/mediastreamer2/mediastreamer2.spec.in b/linphone/mediastreamer2/mediastreamer2.spec.in new file mode 100644 index 000000000..ff1e4492e --- /dev/null +++ b/linphone/mediastreamer2/mediastreamer2.spec.in @@ -0,0 +1,81 @@ +# -*- rpm-spec -*- +# +# mediastreamer2 -- A mediastreaming library for telephony applications +# + +%ifarch %ix86 +%define mediastreamer2_cpu pentium4 +%endif + +Summary: Audio/Video real-time streaming +Name: mediastreamer2 +Version: @MEDIASTREAMER2_PKGCONFIG_VERSION@ +Release: 1 +License: LGPL +Group: Applications/Communications +URL: http://linphone.org/mediastreamer2/ +Source0: %{name}-@MEDIASTREAMER2_PKGCONFIG_VERSION@.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +%ifarch %ix86 +BuildArch: i686 +%endif + +%description +Mediastreamer2 is a GPL licensed library to make audio and video +real-time streaming and processing. Written in pure C, it is based +upon the oRTP library. + +%package devel +Summary: Headers, libraries and docs for the mediastreamer2 library +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Mediastreamer2 is a GPL licensed library to make audio and video +real-time streaming and processing. Written in pure C, it is based +upon the ortp library. + +This package contains header files and development libraries needed to +develop programs using the mediastreamer2 library. + +%ifarch %ix86 +%define mediastreamer2_arch_cflags -malign-double -march=i686 -mcpu=%{mediastreamer2_cpu} +%else +# Must be non-empty +%define mediastreamer2_arch_cflags -Wall +%endif +%define mediastreamer2_cflags %mediastreamer2_arch_cflags -Wall -g -pipe -pthread -O3 -fomit-frame-pointer -fno-schedule-insns -fschedule-insns2 -fstrict-aliasing + +%prep +%setup -q + +%build +%configure \ +--enable-gtk-doc=no \ +--enable-shared --enable-static +make -j$RPM_BUILD_NCPUS CFLAGS="%mediastreamer2_cflags" CXXFLAGS="%mediastreamer2_cflags" + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO +%{_libdir}/*.so.* + +%files devel +%defattr(-,root,root,-) +%doc docs/html +%{_libdir}/*.la +%{_libdir}/*.a +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_includedir} + +%changelog +* Tue Oct 25 2005 Francois-Xavier Kowalski +- Add to mediastreamer2 distribution with "make rpm" target diff --git a/linphone/mediastreamer2/pkg.list b/linphone/mediastreamer2/pkg.list new file mode 100644 index 000000000..cee1171f7 --- /dev/null +++ b/linphone/mediastreamer2/pkg.list @@ -0,0 +1,43 @@ +# -*- rpm-spec -*- ############################################################ +# +# EPM list file. See epm(1) and epm.list(5) for details +# +############################################################################### + +%product ${SUMMARY} +%version ${VERSION} +%release ${RELEASE} +%description ${SUMMARY} +%vendor ${VENDOR} +%copyright ${LICENSE} +%license ${LICENSE} +%readme ${srcdir}/README +%packager ${PACKAGER} + +%system linux + +# Compress man pages +%define __spec_install_post /usr/lib/rpm/brp-compress || : + +# Package all-in one: should be split later on... +%provides ortp-devel + +%postinstall << EOF +ldconfig 2>&1 | logger -i -s -t ${PACKAGE} +makewhatis -u -w 2>&1 | logger -i -s -t ${PACKAGE} +EOF + +%postremove << EOF +ldconfig 2>&1 | logger -i -s -t ${PACKAGE} +makewhatis -u -w 2>&1 | logger -i -s -t ${PACKAGE} +EOF + +%system hpux + +%system all + +%include files.list + +%provides mediastreamer2 +%replaces mediastreamer2 + diff --git a/linphone/mediastreamer2/plugins/.cvsignore b/linphone/mediastreamer2/plugins/.cvsignore new file mode 100644 index 000000000..6cecb663c --- /dev/null +++ b/linphone/mediastreamer2/plugins/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +plugins.mk diff --git a/linphone/mediastreamer2/plugins/msilbc/AUTHORS b/linphone/mediastreamer2/plugins/msilbc/AUTHORS new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/mediastreamer2/plugins/msilbc/COPYING b/linphone/mediastreamer2/plugins/msilbc/COPYING new file mode 100644 index 000000000..623b6258a --- /dev/null +++ b/linphone/mediastreamer2/plugins/msilbc/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/linphone/mediastreamer2/plugins/msilbc/ChangeLog b/linphone/mediastreamer2/plugins/msilbc/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/mediastreamer2/plugins/msilbc/INSTALL b/linphone/mediastreamer2/plugins/msilbc/INSTALL new file mode 100644 index 000000000..23e5f25d0 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msilbc/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/linphone/mediastreamer2/plugins/msilbc/Makefile.am b/linphone/mediastreamer2/plugins/msilbc/Makefile.am new file mode 100644 index 000000000..34b360d4c --- /dev/null +++ b/linphone/mediastreamer2/plugins/msilbc/Makefile.am @@ -0,0 +1,11 @@ +EXTRA_DIST=ilbc-rfc3951.tar.gz + +plugindir=$(PACKAGE_PLUGINS_DIR) + +plugin_LTLIBRARIES=libmsilbc.la + +libmsilbc_la_SOURCES=ilbc.c + +libmsilbc_la_LIBADD=$(ILBC_LIBS) + +AM_CFLAGS=$(ILBC_CFLAGS) \ No newline at end of file diff --git a/linphone/mediastreamer2/plugins/msilbc/NEWS b/linphone/mediastreamer2/plugins/msilbc/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/mediastreamer2/plugins/msilbc/README b/linphone/mediastreamer2/plugins/msilbc/README new file mode 100644 index 000000000..e18f0b05a --- /dev/null +++ b/linphone/mediastreamer2/plugins/msilbc/README @@ -0,0 +1,13 @@ + + +* compile and install the ilbc source: + tar -xvzf ilbc-rfc3951.tar.gz + cd ilbc-rfc2951 + ./configure --prefix=/usr && make + make install (as root) + cd .. + +* compile and install the plugin: + ./configure --prefix= + make + make install diff --git a/linphone/mediastreamer2/plugins/msilbc/configure.ac b/linphone/mediastreamer2/plugins/msilbc/configure.ac new file mode 100644 index 000000000..d8418f211 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msilbc/configure.ac @@ -0,0 +1,152 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT([msilbc],[2.0.0]) + +AM_INIT_AUTOMAKE([tar-ustar]) + +AC_CANONICAL_SYSTEM + +AC_MSG_CHECKING([warning make an error on compilation]) +AC_ARG_ENABLE(strict, +[ --enable-strict Enable error on compilation warning [default=yes]], +[wall_werror=$enableval], +[wall_werror=yes] +) + + +AC_ARG_ENABLE(debug, + [ --enable-debug=[yes/no] enables the display of traces showing the execution of the library. [default=yes]], + [case "${enableval}" in + yes) debug_enabled=yes;; + no) debug_enabled=no;; + *) AC_MSG_ERROR("Bad value for --enable-debug");; + esac], + [debug_enabled=no] ) + + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) + +if test "$GCC" != "yes" ; then + case $host_os in + *hpux*) + dnl we are probably using HPUX cc compiler, so add a +O2 to CFLAGS + CFLAGS="$CFLAGS +O2 -g " + ;; + esac +else + CFLAGS="$CFLAGS -Wall" +fi + + + +if test $debug_enabled = "yes"; then + CFLAGS="$CFLAGS -DDEBUG" +fi + +dnl Checks for header files. +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_HEADER_TIME +AC_WORDS_BIGENDIAN +if test x$ac_cv_c_bigendian = xyes ; then + CFLAGS="$CFLAGS -D_BIGENDIAN" +fi + +if test $GCC = yes && test $wall_werror = yes; then + CFLAGS="$CFLAGS -Werror " +fi + +PKG_CHECK_MODULES(MEDIASTREAMER, mediastreamer >= 2.0.0) + +AC_ARG_WITH( ilbc, + [ --with-ilbc Sets the installation prefix of ilbc codec, [default=/usr] ], + [ ilbcdir=${withval}],[ ilbcdir=/usr ]) + +if test "$ilbcdir" != "/usr" ; then + ILBC_CFLAGS="$ilbcdir/include" + ILBC_LIBS="$ilbcdir/lib" +fi +ILBC_LIBS="$ILBC_LIBS -lilbc" + +AC_SUBST(ILBC_CFLAGS) +AC_SUBST(ILBC_LIBS) + +CFLAGS="$CFLAGS \$(MEDIASTREAMER_CFLAGS) " +LIBS="$LIBS \$(MEDIASTREAMER_LIBS) " +LDFLAGS="$LDFLAGS -rdynamic " + +dnl define path of plugins: +PACKAGE_PLUGINS_DIR=`eval echo $prefix/lib/mediastreamer/plugins` +AC_DEFINE_UNQUOTED(PACKAGE_PLUGINS_DIR, "$PACKAGE_PLUGINS_DIR" ,[path of plugins]) +AC_SUBST(PACKAGE_PLUGINS_DIR) + +dnl ################################################## +dnl # Check for ESP Packager +dnl ################################################## + +AC_PATH_PROG(EPM,epm,false) +AC_PATH_PROG(MKEPMLIST,mkepmlist,false) +AC_PATH_PROG(EPMINSTALL,epminstall,false) +AM_CONDITIONAL(WITH_EPM,test $EPM != false && test $MKEPMLIST != false && test $EPMINSTALL != false) + + +# Preferred packaging system, as per EPM terminology +case $target in +*-*-linux*) + if test -f /etc/debian_version ; then + EPM_PKG_EXT=deb + else + EPM_PKG_EXT=rpm + fi + ;; +*-hp-hpux*) + EPM_PKG_EXT=depot.gz;; +*-dec-osf*) + EPM_PKG_EXT=setld;; +esac +AC_SUBST(EPM_PKG_EXT) + +# System software User & Group names +case $target in +*-*-linux*) + SYS_USER=root + SYS_GROUP=root + ;; +*-*-hpux*|*-dec-osf*) + SYS_USER=bin + SYS_GROUP=bin + ;; +esac +AC_SUBST(SYS_USER) +AC_SUBST(SYS_GROUP) + +# CPU Architecture +case $target_cpu in +i?86) ARCH=i386;; +*) ARCH=$target_cpu;; +esac +AC_SUBST(ARCH) + +# Various other packaging variables, that can be over-ridden ad `make +# package' time +SUMMARY="A mediastreamer plugin." +AC_SUBST(SUMMARY) +PACKAGER=anonymous +AC_SUBST(PACKAGER) +LICENSE=GPL +AC_SUBST(LICENSE) +VENDOR=Linphone +AC_SUBST(VENDOR) +RELEASE=1 +AC_SUBST(RELEASE) + + +AC_OUTPUT( +Makefile +) diff --git a/linphone/mediastreamer2/plugins/msilbc/ilbc-rfc3951.tar.gz b/linphone/mediastreamer2/plugins/msilbc/ilbc-rfc3951.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e5160f402c2a87e8878765ca1fed39a0a0a721ed GIT binary patch literal 330306 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

0DK^-3auzggRH~?6N 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

$lIPh%bh+Ii zs);wYkI?srSU;hp{12%chDoS{A-`(fdYf}-XabD%vR8JS&GbnTlrk=YPCG3QIAgEr zfLe&7dBA}AtZhUA?~nF?)c%#<_`%o(uC^xp(QfnX4ZIFY`<5~C4uaxiI}WVMb|(lH zonw|oyX5PRaZ&%;Vp$lHI~!)#S?P9)YX2t1(J*@RVR0Ektc}{-feLw^yn7~|Io~3i z?5(rrN?H+Z=?>eXbcYG{H|Q=;d5@OmZdsyS+%#uXoDxA-l_S_Lw4| z9_`$j+}>2TWub{8O)PMn{Iq!JDW`aua%(uRIZM-M`6UsrQEPL*c6P2~k5$RJWthlN zzb5k9=)DP4vQaPlRV@rv^jK4u-AKlz-#!JR?{j` z>>9-wLo@@nbPPh)gnRM4Om{jhpGbijC6#bcuh*1Xq%%$f*1kInT-G$6Js8px@QPn# zS5KP4nWkSU@;iAd-6wB%9a95Nk1R693mk>1*ht@JX|ZU>Tn|!4WA05)njQg4US&?_ zmPBCp$xFHX<(*rXd*3$GsOvAR$Hn)w)%~ejcfLgRyyM4tY6-s@42qyo(6rzms%}&B zr(~kt08tGL%*Hx{&erNy7o5IGaTR% z(Y-TOAKT2DvM`|`673bZ9baIdPZGn~=6VWg{Vg7B`6f(!#bN3&s|;mPj$V#?doV4K$Ws;zd_Y>*%BeTd4hl zN1M*dDjb`5_z?xViF8eWmxw+dLo0Uygx>$}Q`y_Rh@r-)nb{7ai1>C%y6Z(D1>;X;1Q8cDI`cFwe+dY@8o*t` zDtv5*^jK4#*#@3)oSx@7b<3Do%rF2x7NeJ3|VN?tGl-=EQI8~sJc9#=mZ==hH zN5cs+Dv3Yj=JpKnmfD6fqREPS)wl*w&fW=jGugPv@WW(573Rr!l}eAmR7H%A}& zJ?B1=c|bnctFr(<;HwaZ_B&@|!1zIWHu+n%Y&VZq4oBI3%0KI9r!!3q8*Tyx!6I0Z zd(c#yhEH4J4e2kGe7)}}hN5)vxX z#xG5TRh^TJ7VM}#tU6S`eOT|8Uv2g8m0^~Q1Bvi^d|$T}39o@3l5?e2{b;p}7uqQy zXL$TpJBy-xufgZ|9mq?3ww29~VCQQXScCVr+(#CP(~``oQSm2r1dM_P`sVeQ5)!ZF za98o2$gnh_b+GRwe;9rP6iEm8YX`3A?{itp+G{2Sz?(zQqiuKx3h7!pXDH2S*(({h zA1gEPib(TnSy-*tqQiD!yu&mmzyNbiAclg@i_?y5^KlSevyRidkUo-uHZI?*Y@Pg_ zxhE^Xg_4cu#&^iGj0m8}R-g4JG9LVH<~hLk>uqst4%p>+|FAPOBZTAU`VbT@=t#<+ zJU9`^Hw=UAy2Y8Suw_`M_pReyn_8+LOCiwWW0&7aWU@WldSaAFEnPz76H$fb+s_H`5rtAww1u8+bNDQdM>G5>;exWorJTQexRC1R-l&JW*?;k*oulgKdYL zf9PN>YAmN7bv~-b^tuUU%8nYCK5rRH*L&nd7kUt9)3BntXUjLAh}YuOa}t2H7*I#u z{UwouK3hfoZ86nSgHaAo@shpJsI0#}EFqy*>sMz`jt-cd-WGT=Sb6h3^1ZOG+v_y4 zS;6?+{v|3Aa@E^7T$20BWj3fn+lVbl`BL6CS;ig0VLwR&spqI;5`SGMTmoqhQ0Q>^ zRi+D}r_{FS35jtPRon{syy)7QfR|M}ic}T@AjC7g#r9^paRlgVg6+i`(o8S)fx|^* zSP;OGFRIN*-fCj*&TuTn`3Jl}am5|UAC|Gnm{U{ISC@61rE!`owuen2vBtWLwW z2B}!g9`Yfb6Xu*&gLU6Tq*_f3{aR;$MOwBmP}koXOKsS@lV(pIE5C!$F@s6mtQ;AL zX*I+-fO}8`O=A+))PeEYD4`IbfO0h+kz1oAie|#ha^WBYmz$bW58BoovxghFCRK3% zjvTzlS2;D+*s_2E_s4J|T}qRzJ5vOW4v%ZL0cKpDxWdkc?pLedpyZjO!RA>|KXC3_ zS3FTn{U~z;ivZx5W&+UM>z02}k?DA+B5TLcNF0bNBPns&LWq+sfvAq#=GBhp|C;)T z*itk&m77~>(M_)%Y8aSczFKM88A?s5HkMKZe~ z^L?11jndyy90z==T+!1z_@R}8yYN*AibgR3ZB^7#rW}}W3Oj{0Z3Wc52Q7q6Q*+-aH&SPSu_I9^4VN?Vr|Hz}$kZnAF?N@=B+2Of zin|#n^#Uj3g25B9aQ8v46spLQDl>*lZBD?sWid{L9JL+4xSn%DIhnEu61(d9$Kr#y z;pzurf@xn4%{)q5=|4wCWg3duzBI&@&cK{)zOQhKQ=##&`?=TN7Id%$eBeH01J>DN z0QhoeH1PFmKY;pM-Uu1U6%SX*)a|3LKJ>l+TWf@+VuK49&9O=h(dytPnpSF{=75*u zj-k;Swzfl>IHm8T)t``JIk1?EezoQF$?3h%gkmbv41uNCU9mQLhY$0$LfCyLTyINq0;1wW_+j;x)!?x&S)o!gx7s$IK3l5rZ98y13w#C4-$=19&uoGq1wy~qRKAvx# zH;EN>Of79@wCj-L;DT4n*&Pafe~$H;3mjguma%HJVO;#kytUQUEDc40SU9<_-U$Xb zWE@d4NH3YJ{Y}fQ9e5qO{j*WetM7v~a+K-1sA@o8Le^^iLsQspTY-8U3~Ph7T+7%R zHRkU11hy*D__rrZyRpsR>0PD2eOIS6SZ=H1mTqUa>^Ud~sTP0L6aHz=Ag;IA?=J(H zvazBdirBZ@(4S7OPf|G$khlv6d&a*d0u7*;#t;N?z$jv(_1I8+&r?>Ri7M@b2tlpw z&OKkVl53yEW)DNiIP3v|CC~>~5VsH!;dZhDKk|-^U7+R}brQ-s-BscYw6WcESXp%1 ziPy3U&dM|bc+8_BSk360JQaZbwds^q%0GiZRz-#BT zoKLhEZv!i+{^j2z97|(3&48XK+dNvDyLT*WEvtjX(hifPp}@YUmZb5;LX!C!M`k*~ z7XDTnVxwZxN({k>HKYckd;5C(u-u@Xn-)Ds`I%DQ+wong1!hkF*0r1GizjuBO4OM4 z*$rnk1+cICaBkpksM&KqKlk?8oYd!QJRW&o*)|Zd`{nB6xKjvN@r~H|J-I+>e`UHj z55NOHm!bc}T?z5LCUzf`@uj7g#Ex*J+I9gUnjH7v?oU*)!N)o9fByR(xs|E{&)oH{ z6r^PBzlp4-1y)l_8cV5{D*zPp9Lw$+6H-eg!NQvTUg7+mBmlqt#~GUw5oKkixEn+D z8g-0p`{DOSG_Dy%!btYCi)Z$V?DcL7F;ihiuUHxs*gcVj^s@W;^~*TwuRSuoP@4iE z3srkKvnSJMte6owy$WM3qGMaLs!?g0DS5dLt&n%|?6>F+REf69>&UAv4Pcgq62hy! zW>Vwb1}ZD}qhMbU%B!jkXntrH9qyJTPuRA#Wm(9ur)egR9slA%-98EXvTD(ca>Q?c z9xv^J=%h%m$Hu)Mtz-m~mHqf@n<4-G>1OntaXtF-Sb%{)|7o|8#26d#wSV-5qwVwO z`#Z9_RiE3sx{NrNDqm^NdTI|hq_sQcB{Kx}-JmSB?}awh8L!;7D*P={5zY{Wr+zYp zGsEvVgnR>{9VO=L>3Fd}^jdf(S`gWAA6n$M7D3d`0{NL@9$xa9+b6z(oAUtN8b2|a z9l&yY0Pl*BudnOF$0|^hL*z5sCm17%rxiV)yiv42OW5)eBDwZzsRqY-ee+j!&0&4u z3&5i2tVvk6q2?uNmd9Z<`^w)R`W@)|gg+zQYWY=n1eEwFBO<>d_*RI%27EJQ$j89j z#e1wee}9w1*Tv3XESM?_HDAZ`wG;`nxII)zXn3U8XVba{#yj~*q+(-EB)+K4>IW2S zmp^qQL}Y*`ORBS-`9kJjGxv2v-&76PUBE!mw>tB94EV|*4HEdaGxRl4rjGKbYvTm7 z=w7mCq|NR}&%I96c9N=X576z4<0W7Rvd0T}t^fokZvx-aeu6|x@$q_ocmqcQw1xto z`Zq62I@e`eapv27u#|nVls`Jf(XW3wTwh~Pxjws?d^+e}^zv?O>)*yNJ_FIVxh?{h z<*y!kzk$-^rYF6Pk7dI6``|nd5qy2p3MOqAI;q3tK?!Vkk?Vizbq$yoUZA(uIpM?J=pg82#hOG86B+7G>e7ADn+%oA-xoMN4Q;OhzwX%e#|jSedVY>LC|HY;3==LAOC z;(mfLLjP0Vw+wC@Va3C`po>-_JE%mj+mu;55AqFANxex(G?q4>96yT_!PBJ{cy%x` zJuP5Uj`SI$CbhBX^LXxUmY*%)u;fz@I_V~`eic?vhYSBE8Rs=*6rRd&%Drv`^c(G= znC+jgG=5(Fggcb=UPNzM?t7`X)5WrnbilkmmPOR{kqkhuPXC##DBL?XA;Osl<~l4N z$JDCqd77#PgShW~k=@CU!B{t_evjy`_8}!8(xO`k){gID3|yTm;F9+K51kJH?Axv0}nY z8SL4tW_8{g&PdSgn?rvmNF{eDYgk{LeK&PAiXHF8Cc_8oHp5}5yYv&qYSkv_60mt) z5Q1>w2;d-C1IX{r@Ej6HB176@ZLlQtXzCrNt5rk~VIgEgv->XWbK-{LAYt+tSD&E7 z*h1CkD*)s*?=#Qb2G&Hkgr5e)vzwls4vWA1kQ$Zy6a&w{F)*eD7|ou#{1& zk(BOzP{$O(`lF)H6Os-ivRg>Q)KC=eR8Z?w;yr07n@$7@6E@Ps3@_xmO>ILYc9pwj z1(2Sq#IHtvF3|5Ab{&t-!2Oxzg~%@-%JSSh9`0`Ya7TT!*@EcI6R6a=0sW~5PC*A{ zlf{S4*s&2qE<^AOjSaz0;1BtqIC=KL-uJiZ-42BbcIGRg5Zj7eXrgi zc0=R$sGyszTxBhHIil60hP+VABUd|gL8$jfn)fTmP1Q=`Hb|VCAQL>_LB8r!;w zof}IMpSTA@T-2%sTcoia4%r@>DuLzm($26AI)74+*i*h6WqaPS1OvG_9f#RLI0_+Y zEPZtt=~B(Sn#AT${1b&brUTo>hx;8)UwgV0`=l^3M|TIYJIzIp({?2fk>@RrrI%WW zzt;r7pvgo?ayupnQ}GXn196G3eDbzv;Ah;vkZOA^@FqT)dkV!6zT2ytuW-QQrhOlSnd;1qQ>CfdD1eJ?+2nVljhvg*iRcXLU_{abcV1I{fl-aegXRs4r&C{ znOYQvMro+9$X|Q8CWbuxx!AO*Vtj-}C2N{RDoRExEMPMnHD!BLvE6M2ZkAShK)0Vg zwVCNjKuOy_N15ufJU73|l`i0W-oSkz;Id5)6X)rPR&C%~nQ9S{e`Hzky@luv8luWS z)2`4{#(+%mmn)l-f9WOWC11z)|D!i!nMu=d2^Q}PtftyUH%N8aBOtimlF4)M+KYt~ z(V8!eG#Ni?o!}Oa{g;N4Em(VOZ(T~!zq!<=pfU2Zu5>K{Q~k_#TILadfij;?A)Ol^ z&I>OR$r>j+4d&ZH{`uI3&wGL1k+w^)w9p8z7ZNlL0@F_yb5kSw!s*YAjlD6uq-J@3 zmUrceCIIz?Du&aHlfi7{Gg7Ac?U{+S^z&`?s}!P z-zn*Ztf%a>&~`HnVPqB|o^_CRQ@9;gSqJSi(vIRYl1f>A_*+16u1r@GcR;0~gSfOO zXt`ii2uw8C_TN`zK?SJq0MgSoUPKc$7CljIV-RL6hF}oggEg=)sipMzxvfA=y$@W2 zBW|wW|?injkQnAW#{4A~ExeO3EcC(j7)p?M8v$cDJf@p!zm2I+=U+pcgCD z<7@lc;EPTBeJQ7BIJW2C{X56?tC3TVZI5Be67wame&+K1_6d(uORX%tAGT;OoHOUl zmPe|spf?G{+oRG1jrHr=4JJKcb?P&?!N2YzyadJOYwPvtBcN4FRyg z#7(Uad|wz{f-pjmQtRjox>B>pO3IhSvVemsBCiiJ10c1M(A}$K(3f(#Kl)9)=(*%! z9TGvWcKGw~!pr1V6`PO2)P)~M-Sb)3md3re!PHqdZ`Jc+^_GTkGmb@tWFpSD6EP?z3dQQBFKg-CQUC|H4=3 zD3!Kq`f~^#{9_e@?h8RMBXolMpZlm^bljp?=oYcfW83aho9S=nZPRXPm5Ajk6%^Uj zsbC!Z$l&)`mQGZ&5$9gA5F6V59RL8-ltird|55|@4JP74T|6JgMGQFCK;Q&XipCu| zZu~|*51MbAMlic5xRZ+Y_PfBy%K91&Ct7_RVx^`l2cN5WeYgL!wkFj7a!cML%W7%# z-R$(T*G)FIp%#Z?G)jj-R`ebKd^0t?dE37Zq zeu-%?p(1Ek?`WXKeQlB8>*~xKAFD1%Y;>4e^H5rEMe+lX(BAmkU>VtAfnE=2bo{8+ z`*|XgP$RlUtE3$|()nC%G*E+S6B`FbeBi#migz=y4SWuW(~OsVA-C2kFXNY_iNvsx z%1(j4@pQYKs3P~23aM{$5`Ib#JZUZUR8ythPNN5V<%jN&Y-Y9yIl08pTYmPs*57aD z4zuT^iu={N$^C(N%%mF25<2Z>PT8Sf1XvrBnzO9*Rv=I@22HW?H8atB&N5&7?U>5G ziP2OX^^q#uZA_TOH2G6+W?=eyaeMHqz)>N*2rl6-4i>H)xn@Qs>?khjpnqy3BA}XZ z$TF`19nzOjW8Q3!HJi1ycIQ)E|VUM9E$j^R)ig zf;StlV~M$pI72_= z$J=#kHSM_}=wY1Pz z2rxgS$}$44V$#B|`2#3@3_&MWmKxwlBfa`+Wcy99 zra`E#nD~v3m}stg3W8`p5mrd3Qfkt4K_&XIAezb>G0~mcl3}_jMAWVEy4%ZB_%^Nb z^$YN(c7^Z+PwxnrX-#C-K4)X6O$2O%$V7u}SADKan?7kefUPW@v6ftJeu4oXYx0d+wOSZOK^<)<1tpNN@j@%N&j}ZL+8Z%OXV;0 zvWhS&GwIWAIjz;BL#hYAqIAH6iOght>Q|2;ee}+>5lqj#o zw4p(7goicfFa-1dlo0=jzPQ%<&(fl7BP zu1#c}zaJc5`46>f19yEVDwSP6C6~*AJDWoRUsh*AzOt#kc|E2}=_Lp0zAowX?=!jd z@9UM38wtR}^F<&6Dj87rWb+nyo%g@7tjItj!tXTR_b0sLfW01_E=f4ojrXwO)02pYW5@XYIvhn0h{5HFbCA;K*CHsQdYhlAZm;za20TRNqZQ!VH=r zkk2Y0>?4?in4jv!I)-<6;`x4DKU4O~N;GavoT>iqTP4{TeGj&8W+bd{+^x3n3`X)% z*d(MN!~_`P4Mmh%a=((D*EMVw-^DoHR{9`FO_q)Et-4QX7AK+Pr{6QcwP+qM@0Pqs z27Pzdh>aYA4iVYW{%5NZ>!ojH$#~WSd8H`X`IxVWrICSjH#9e+sP4~;zAdP~zdvT{ z$~uI{Sofr;UwzTeO*5^q5@ifzx@DbA270+THt7$>5BchHd@N5aE1HRsc?eof(G9Yl z@%2wSNIDSq^87zMZ~5)d+Z&7`)k{jKOKd^oUWBWChajK!KVF=Ve_ecyKBq933<8Wk zF#@m@mr-2@DvS$WJS zTO3O1T)Q-K(^2j-ZjrW6hN*z~b>_wcp4U&e!;r~&v=Y`h(4L9@ZO(sgyq@%O!! z|CsXC@8(dFpT9=b86sO9sD#cbypM`OpfJQ~RCOVjrq1%Go%0iGuwmDOWi{ z8_}!wcb!jij{XF(BCOPx;Xt1+!97E2WXfiLY5()n+r6?Z{p6!BW6hEJ>A>BB87xi} z=cznVZ;hg5HirJI!YyxCt>vQmuq0_U)l3&>T10JZBtH-1K0hpfrS3bN#DV7=yws!1 z28IglQ>X@!_VfkYq#1Z{P!^Jp7%y#~Y_;5OSVu*59d(HMdCW8oyOPCpvt*u*QO1B- z3^S2At~o&uLqrq`JIs}0u7V1jKPERvHqpD*XH)zz$g!U=?8e1rEzZ6 zJPM}8>7IjJ{=(a5M#1CAB)$N*LK!zZ{_yH|4)Y~kP%VKhOp3`lNOmjUx^&EM9OH3G zN$FSWq`UifcT(DKiR}=^4YYs5G!B+ZcjEPE+-irP^8+TSkx?**S7r2eskd zXpP?q0C45@k(eALhc79-5+A&$nJ4%Ui&bOT;4vZ#_nPaXu@Ap7)KL!&d2z-dqzdd0 zL_rkBURXj@lHGL`a6M6J-pEzXnpWU_^s{#r(8$i39W5M&q|&&5;Wx3B|0SB4PA0m> zR;0InS}*|LK_oTxhz5Dj2A8vM-b*1e67t4;lF{a_w&wL435_xnz_q8IW8CEEbmc|t z$C&~{vUTGwqv{>X)IyMZ9JJ~zSc{{8cRi+k?+Ug(^zW@3FU7dbc~7nUIVn)e;g&rX z{KMT$)@ExctsvIUB&m{EZT34@@Q{xU8Ts|cyxJ-B%TuBKnQiX2CK9nu*#2(JV?R^J zz3k=cg4Fe2T4?$@^ShQnt#2_!gY5i@SxfG$pwHC2PLT}Z$Glb*8#ol?ey&VA0OPvq z(go5t0z}+}?izNM?4O7UGQCVOM;_4;^o zc1LjPA*x?PT6U6B9eEb>*FH7TM{ZViP6Mg@$WBJ}XHC8Z3iD_LBoB5<{X<3XF;-%|5(f@D?MEZ>~C ziK=XoQ*CUpP8``Zf2=JCi0F4NTX~~nbzL#30oc8TuVf6p6?4a zt$q!Yzrx!CkR2~zB4X&UxsB~U53*Hrl8jW_6$ViHa#snnztROcn<2coVK?;0P^1vd z{37%RpSE?hC}gnz{ZJ=@)Y??U|*@}@KEQE)nN|0>KU(VQn`iS*o zyBc&_zCDB1wCNznfIf~!m_2W!n#otweL6^m%6jD-S4-?Mpe$oQvy>gowoA=3UaO2V zyn*p6)1X@7V_gp73gb%G(hbcLt#PUQU*O5@a5tP!?YC^JVc3$=sfJ@Gok5Et=BG}n z@!V~j_1qSR%5EYfA&)T@kNf;je{SUb8mZQL4#3Eb%a^iUehm$=@5DzOt`q@ycOI_j zb4|_?kp}eXYqx_2bi++82eW@!psgCH)e1Boc?$@F%cz$mk)7wFjC;M*=QHpkMjT= zeKoYZjX)aL9B$-CB6q{;aSfojYSOQrqx%{a&U8B0e9bYFw=2U?$C`h=h$!bDn8wg zm8!|mO*L2HnR#~a`l)}G^)R$en#boS+)s?WTvx^_Zw(&K(WXtHSLzjFTqGDn==$lJ zQpq;*I6iGS&E*2F_G^R9R^pfYHVNZ0T{Q*Vy}O|#M0pq*E(0;58h2z5W4Db=@|^XD ztOj#!I@8tWpyPU3L|ladgMz$V*F|xzTo*$U zUCYEfcDu9W`xq7oz2JJZx;MBfTH9~9o@TbY=EW6mb5@LiHhZDvVuhOII9$Qnv?Y_q)CCHwy5cOSsf@K0j`h_ksE@Wyr* zkh;`E!s7TK#I$u&4^qWWT-RIBD4PcH2cpu#14j7T|LXti;SbCQ3hiDJ_JQ +#include + +#include "mediastreamer2/msfilter.h" + +typedef struct EncState{ + int nsamples; + int nbytes; + int ms_per_frame; + int ptime; + uint32_t ts; + MSBufferizer bufferizer; + iLBC_Enc_Inst_t ilbc_enc; +}EncState; + +static void enc_init(MSFilter *f){ + EncState *s=ms_new(EncState,1); + s->nsamples=BLOCKL_20MS; + s->nbytes=NO_OF_BYTES_20MS; + s->ms_per_frame=20; + s->ptime=0; + s->ts=0; + ms_bufferizer_init(&s->bufferizer); + f->data=s; +} + +static void enc_uninit(MSFilter *f){ + EncState *s=(EncState*)f->data; + ms_bufferizer_uninit(&s->bufferizer); + ms_free(f->data); +} + +static void enc_preprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + initEncode(&s->ilbc_enc,s->ms_per_frame); +} + +static int enc_add_fmtp(MSFilter *f, void *arg){ + char buf[64]; + const char *fmtp=(const char *)arg; + EncState *s=(EncState*)f->data; + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "mode", buf, sizeof(buf)); + if (buf[0]=='\0'){ + ms_warning("unsupported fmtp parameter (%s)!", fmtp); + } + else if (strstr(buf,"20")!=NULL){ + s->nsamples=BLOCKL_20MS; + s->nbytes=NO_OF_BYTES_20MS; + s->ms_per_frame=20; + }else if (strstr(buf,"30")!=NULL){ + s->nsamples=BLOCKL_30MS; + s->nbytes=NO_OF_BYTES_30MS; + s->ms_per_frame=30; + } + return 0; +} + +static int enc_add_attr(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + EncState *s=(EncState*)f->data; + if (strstr(fmtp,"ptime:20")!=NULL){ + s->ptime=20; + }else if (strstr(fmtp,"ptime:30")!=NULL){ + s->ptime=30; + }else if (strstr(fmtp,"ptime:40")!=NULL){ + s->ptime=40; + }else if (strstr(fmtp,"ptime:60")!=NULL){ + s->ptime=60; + }else if (strstr(fmtp,"ptime:80")!=NULL){ + s->ptime=80; + }else if (strstr(fmtp,"ptime:90")!=NULL){ + s->ptime=90; + }else if (strstr(fmtp,"ptime:100")!=NULL){ + s->ptime=100; + }else if (strstr(fmtp,"ptime:120")!=NULL){ + s->ptime=120; + }else if (strstr(fmtp,"ptime:140")!=NULL){ + s->ptime=140; + } + return 0; +} + +static void enc_process(MSFilter *f){ + EncState *s=(EncState*)f->data; + mblk_t *im,*om; + int size=s->nsamples*2; + int16_t samples[1610]; /* BLOCKL_MAX * 7 is the largest size for ptime == 140 */ + float samples2[BLOCKL_MAX]; + int i; + int frame_per_packet=1; + + if (s->ptime>=20 && s->ms_per_frame>0 && s->ptime%s->ms_per_frame==0) + { + frame_per_packet = s->ptime/s->ms_per_frame; + } + + if (frame_per_packet<=0) + frame_per_packet=1; + if (frame_per_packet>7) /* 7*20 == 140 ms max */ + frame_per_packet=7; + + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + ms_bufferizer_put(&s->bufferizer,im); + } + while(ms_bufferizer_read(&s->bufferizer,(uint8_t*)samples,size*frame_per_packet)==(size*frame_per_packet)){ + int k; + om=allocb(s->nbytes*frame_per_packet,0); + for (k=0;knsamples;i++){ + samples2[i]=samples[i+(s->nsamples*k)]; + } + iLBC_encode((uint8_t*)om->b_wptr,samples2,&s->ilbc_enc); + om->b_wptr+=s->nbytes; + s->ts+=s->nsamples; + } + mblk_set_timestamp_info(om,s->ts-s->nsamples); + ms_queue_put(f->outputs[0],om); + } +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_ADD_FMTP, enc_add_fmtp }, + { MS_FILTER_ADD_ATTR, enc_add_attr}, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_ilbc_enc_desc={ + MS_FILTER_PLUGIN_ID, + "MSIlbcEnc", + "iLBC encoder", + MS_FILTER_ENCODER, + "iLBC", + 1, + 1, + enc_init, + enc_preprocess, + enc_process, + NULL, + enc_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_ilbc_enc_desc={ + .id=MS_FILTER_PLUGIN_ID, + .name="MSIlbcEnc", + .text="iLBC encoder", + .category=MS_FILTER_ENCODER, + .enc_fmt="iLBC", + .ninputs=1, + .noutputs=1, + .init=enc_init, + .preprocess=enc_preprocess, + .process=enc_process, + .uninit=enc_uninit, + .methods=enc_methods +}; + +#endif + +typedef struct DecState{ + int nsamples; + int nbytes; + int ms_per_frame; + iLBC_Dec_Inst_t ilbc_dec; +}DecState; + + +static void dec_init(MSFilter *f){ + DecState *s=ms_new(DecState,1); + s->nsamples=0; + s->nbytes=0; + s->ms_per_frame=0; + f->data=s; +} + +static void dec_uninit(MSFilter *f){ + ms_free(f->data); +} + +static void dec_process(MSFilter *f){ + DecState *s=(DecState*)f->data; + mblk_t *im,*om; + int nbytes; + float samples[BLOCKL_MAX]; + int i; + + while ((im=ms_queue_get(f->inputs[0]))!=NULL){ + nbytes=msgdsize(im); + if (nbytes<=0) + return; + if (nbytes%38!=0 && nbytes%50!=0) + return; + if (nbytes%38==0 && s->nbytes!=NO_OF_BYTES_20MS) + { + /* not yet configured, or misconfigured */ + s->ms_per_frame=20; + s->nbytes=NO_OF_BYTES_20MS; + s->nsamples=BLOCKL_20MS; + initDecode(&s->ilbc_dec,s->ms_per_frame,0); + } + else if (nbytes%50==0 && s->nbytes!=NO_OF_BYTES_30MS) + { + /* not yet configured, or misconfigured */ + s->ms_per_frame=30; + s->nbytes=NO_OF_BYTES_30MS; + s->nsamples=BLOCKL_30MS; + initDecode(&s->ilbc_dec,s->ms_per_frame,0); + } + if (s->nbytes>0 && nbytes>=s->nbytes){ + int frame_per_packet = nbytes/s->nbytes; + int k; + + for (k=0;knsamples*2,0); + iLBC_decode(samples,(uint8_t*)im->b_rptr+(k*s->nbytes),&s->ilbc_dec,1); + for (i=0;insamples;i++,om->b_wptr+=2){ + *((int16_t*)om->b_wptr)=samples[i]; + } + ms_queue_put(f->outputs[0],om); + } + }else{ + ms_warning("bad iLBC frame !"); + } + freemsg(im); + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_ilbc_dec_desc={ + MS_FILTER_PLUGIN_ID, + "MSIlbcDec", + "iLBC decoder", + MS_FILTER_DECODER, + "iLBC", + 1, + 1, + dec_init, + NULL, + dec_process, + NULL, + dec_uninit, + NULL +}; + +#else + +MSFilterDesc ms_ilbc_dec_desc={ + .id=MS_FILTER_PLUGIN_ID, + .name="MSIlbcDec", + .text="iLBC decoder", + .category=MS_FILTER_DECODER, + .enc_fmt="iLBC", + .ninputs=1, + .noutputs=1, + .init=dec_init, + .process=dec_process, + .uninit=dec_uninit +}; + +#endif + +#ifdef _MSC_VER +#define MS_PLUGIN_DECLARE(type) __declspec(dllexport) type +#else +#define MS_PLUGIN_DECLARE(type) type +#endif + +MS_PLUGIN_DECLARE(void) libmsilbc_init(){ + ms_filter_register(&ms_ilbc_enc_desc); + ms_filter_register(&ms_ilbc_dec_desc); +} diff --git a/linphone/mediastreamer2/plugins/msx264/AUTHORS b/linphone/mediastreamer2/plugins/msx264/AUTHORS new file mode 100644 index 000000000..16d2ea646 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/AUTHORS @@ -0,0 +1 @@ +Simon Morlat \ No newline at end of file diff --git a/linphone/mediastreamer2/plugins/msx264/COPYING b/linphone/mediastreamer2/plugins/msx264/COPYING new file mode 100644 index 000000000..623b6258a --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/linphone/mediastreamer2/plugins/msx264/ChangeLog b/linphone/mediastreamer2/plugins/msx264/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/mediastreamer2/plugins/msx264/INSTALL b/linphone/mediastreamer2/plugins/msx264/INSTALL new file mode 100644 index 000000000..d3c5b40a9 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/INSTALL @@ -0,0 +1,237 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 6. Often, you can also type `make uninstall' to remove the installed + files again. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/linphone/mediastreamer2/plugins/msx264/Makefile.am b/linphone/mediastreamer2/plugins/msx264/Makefile.am new file mode 100644 index 000000000..5cb64b1c7 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/Makefile.am @@ -0,0 +1,3 @@ +EXTRA_DIST=autogen.sh + +SUBDIRS=src diff --git a/linphone/mediastreamer2/plugins/msx264/NEWS b/linphone/mediastreamer2/plugins/msx264/NEWS new file mode 100644 index 000000000..5b0622361 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/NEWS @@ -0,0 +1,2 @@ +Wednesday August 20, 2008: msx264-1.1.0 + - compiled together with x264-snapshot-20080421-2245+multislicing-patch.tar.gz, allows packetization-mode=0 diff --git a/linphone/mediastreamer2/plugins/msx264/README b/linphone/mediastreamer2/plugins/msx264/README new file mode 100644 index 000000000..6836540f6 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/README @@ -0,0 +1,17 @@ +msx264 - a GPL plugin to bring video H264 encoding/decoding capabilities to mediastreamer2 applications. +It is based on ffmpeg for decoding and x264 for encoding. + +It works with any version of x264. However if you want better performance and interroperability, it is +highly recommended to use a modified x264 version patched with the patch mentionned here: +http://mailman.videolan.org/pipermail/x264-devel/2008-April/004427.html + +Unfortunately for bad reasons this patch hasn't been merged by x264 developpers, and no more applies with +recent versions. + +This patch enables multi-slicing, ie smaller video packets that fit into the network mtu. +It enable RFC3984 packetization-mode=0 to work. +A x264 version modified by this patch can be found here: +http://download.savannah.gnu.org/releases/linphone/plugins/sources/x264-snapshot-20080421-2245+multislicing-patch.tar.gz + +So compile x264-snapshot-20080421-2245+multislicing-patch.tar.gz with ./configure && make && make install +Then compile msx264 with ./configure --enable-hacked-x264 && make && make install diff --git a/linphone/mediastreamer2/plugins/msx264/autogen.sh b/linphone/mediastreamer2/plugins/msx264/autogen.sh new file mode 100755 index 000000000..d342f286b --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/autogen.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +#AM_VERSION=1.10 +#1.9 was the recommended version +if test -n "$AM_VERSION" ; then + ACLOCAL=aclocal-${AM_VERSION} + AUTOMAKE=automake-${AM_VERSION} +else + ACLOCAL=aclocal + AUTOMAKE=automake +fi + +echo "Generating build scripts in this mediastreamer plugin" +set -x +libtoolize --copy --force +$ACLOCAL +$AUTOMAKE --force-missing --add-missing --copy +autoconf +rm -rf config.cache + diff --git a/linphone/mediastreamer2/plugins/msx264/configure.ac b/linphone/mediastreamer2/plugins/msx264/configure.ac new file mode 100644 index 000000000..ce3083822 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/configure.ac @@ -0,0 +1,143 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT([msx264],[1.1.2]) + +AM_INIT_AUTOMAKE([tar-ustar]) + +AC_CANONICAL_SYSTEM + +AC_MSG_CHECKING([warning make an error on compilation]) +AC_ARG_ENABLE(strict, +[ --enable-strict Enable error on compilation warning [default=yes]], +[wall_werror=$enableval], +[wall_werror=yes] +) + + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) + + +CFLAGS="$CFLAGS -Wall" + + +dnl Checks for header files. +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_HEADER_TIME +AC_WORDS_BIGENDIAN +if test x$ac_cv_c_bigendian = xyes ; then + CFLAGS="$CFLAGS -D_BIGENDIAN" +fi + +if test $GCC = yes && test $wall_werror = yes; then + CFLAGS="$CFLAGS -Werror " +fi + +PKG_CHECK_MODULES(MEDIASTREAMER, mediastreamer >= 2.1.0) + +PKG_CHECK_MODULES(X264, x264 >= 0.58.0) + +AC_ARG_ENABLE(hacked-x264, +[ --enable-hacked-x264 Turn on compilation over a patched x264 that allows multislicing [default=no]], +[hacked_x264=$enableval], +[hacked_x264=no] +) + +dnl test for ffmpeg presence +PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 50.0.0 ],ffmpeg_found=yes , ffmpeg_found=no) +dnl workaround for debian... +PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 0d.50.0.0 ], ffmpeg_found=yes, ffmpeg_found=no) +if test x$ffmpeg_found = xno ; then + AC_MSG_ERROR([Could not find ffmpeg headers and library. This is mandatory for video support]) +fi + +dnl check for new/old ffmpeg header file layout +CPPFLAGS_save=$CPPFLAGS +CPPFLAGS=$FFMPEG_CFLAGS +AC_CHECK_HEADERS(libavcodec/avcodec.h) +CPPFLAGS=$CPPFLAGS_save + +CFLAGS="$CFLAGS \$(MEDIASTREAMER_CFLAGS) \$(FFMPEG_CFLAGS)" +if test "$hacked_x264" = "yes" ; then + AC_MSG_WARN([Trying to compile with multislicing patched version of X264]) + CFLAGS="$CFLAGS -DHACKED_X264" +fi + +LIBS="$LIBS \$(X264_LIBS) " +LDFLAGS="$LDFLAGS -rdynamic " + +dnl define path of plugins: +PACKAGE_PLUGINS_DIR="\$(libdir)/mediastreamer/plugins" +AC_SUBST(PACKAGE_PLUGINS_DIR) + +dnl ################################################## +dnl # Check for ESP Packager +dnl ################################################## + +AC_PATH_PROG(EPM,epm,false) +AC_PATH_PROG(MKEPMLIST,mkepmlist,false) +AC_PATH_PROG(EPMINSTALL,epminstall,false) +AM_CONDITIONAL(WITH_EPM,test $EPM != false && test $MKEPMLIST != false && test $EPMINSTALL != false) + + +# Preferred packaging system, as per EPM terminology +case $target in +*-*-linux*) + if test -f /etc/debian_version ; then + EPM_PKG_EXT=deb + else + EPM_PKG_EXT=rpm + fi + ;; +*-hp-hpux*) + EPM_PKG_EXT=depot.gz;; +*-dec-osf*) + EPM_PKG_EXT=setld;; +esac +AC_SUBST(EPM_PKG_EXT) + +# System software User & Group names +case $target in +*-*-linux*) + SYS_USER=root + SYS_GROUP=root + ;; +*-*-hpux*|*-dec-osf*) + SYS_USER=bin + SYS_GROUP=bin + ;; +esac +AC_SUBST(SYS_USER) +AC_SUBST(SYS_GROUP) + +# CPU Architecture +case $target_cpu in +i?86) ARCH=i386;; +*) ARCH=$target_cpu;; +esac +AC_SUBST(ARCH) + +# Various other packaging variables, that can be over-ridden ad `make +# package' time +SUMMARY="A H264 codec mediastreamer plugin" +AC_SUBST(SUMMARY) +PACKAGER=anonymous +AC_SUBST(PACKAGER) +LICENSE=GPL +AC_SUBST(LICENSE) +VENDOR=Linphone +AC_SUBST(VENDOR) +RELEASE=1 +AC_SUBST(RELEASE) + + +AC_OUTPUT( +Makefile +src/Makefile +) diff --git a/linphone/mediastreamer2/plugins/msx264/msx264.dev b/linphone/mediastreamer2/plugins/msx264/msx264.dev new file mode 100755 index 000000000..c27baaaa2 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/msx264.dev @@ -0,0 +1,95 @@ +[Project] +FileName=msx264.dev +Name=msx264 +UnitCount=1 +PchHead=-1 +PchSource=-1 +Ver=3 +IsCpp=1 +ProfilesCount=2 +ProfileIndex=0 +Folders= + +[Unit1] +FileName=src\msx264.c +CompileCpp=0 +Folder=msx264 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription= +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 + +[Profile1] +ProfileName=MingW 3.4.2 +Type=3 +ObjFiles= +Includes=../../include;../../../oRTP/include;../../../../linphone-deps/include +Libs=../../../../linphone-deps/lib;../../../mediastreamer2/build/win32native;../../../oRTP/build/win32native +ResourceIncludes= +MakeIncludes= +Compiler=-DBUILDING_DLL=1_@@_-DORTP_INET6_@@_-DHAVE_LIBAVCODEC_AVCODEC_H_@@_-DHACKED_X264_@@_ +CppCompiler=-DBUILDING_DLL=1_@@_ +Linker=-no-undefined_@@_--enable-runtime-pseudo-reloc_@@_-lx264_@@_-lmediastreamer2_@@_-lortp_@@_-lavcodec_@@_ +PreprocDefines= +CompilerSettings=0000000001001000000000 +Icon= +ExeOutput= +ObjectOutput=Output\MingW +OverrideOutput=1 +OverrideOutputName=libmsx264.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + +[Profile2] +ProfileName=Visual C++ 2005 +Type=3 +ObjFiles= +Includes= +Libs= +ResourceIncludes= +MakeIncludes= +Compiler=/DBUILDING_DLL=1 +CppCompiler=/DBUILDING_DLL=1 +Linker= +PreprocDefines= +CompilerSettings=000000000000010000000000000000000000 +Icon= +ExeOutput=Output\Visual C++ 2005 +ObjectOutput=Objects\Visual C++ 2005 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +compilerType=1 + diff --git a/linphone/mediastreamer2/plugins/msx264/msx264.iss b/linphone/mediastreamer2/plugins/msx264/msx264.iss new file mode 100755 index 000000000..faeea2fe0 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/msx264.iss @@ -0,0 +1,35 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +[Setup] +AppName=msx264 +AppVerName=msx264 H.264 plugin for linphone. Plugin version is 1.1.2. +AppPublisher=linphone.org +AppPublisherURL=http://www.linphone.org +AppSupportURL=http://www.linphone.org +AppUpdatesURL=http://www.linphone.org +DefaultDirName={pf}\Linphone +DefaultGroupName=Linphone +LicenseFile=C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\plugins\msx264\COPYING +InfoBeforeFile=C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\plugins\msx264\README +OutputBaseFilename=setup +Compression=lzma +SolidCompression=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +;Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "C:\Documents and Settings\simorl.EMEA\cvs\linphone\mediastreamer2\plugins\msx264\libmsx264.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +;Name: "{group}\Linphone"; Filename: "{app}\linphone-wx.exe" ; WorkingDir: "{app}" +;Name: "{userdesktop}\Linphone"; Filename: "{app}\linphone-wx.exe"; WorkingDir: "{app}" ; Tasks: desktopicon + +[Run] +;Filename: "{app}\linphone-wx.exe"; Description: "{cm:LaunchProgram,Linphone}"; WorkingDir: "{app}" ; Flags: nowait postinstall skipifsilent + diff --git a/linphone/mediastreamer2/plugins/msx264/src/Makefile.am b/linphone/mediastreamer2/plugins/msx264/src/Makefile.am new file mode 100644 index 000000000..88b3f2415 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/src/Makefile.am @@ -0,0 +1,6 @@ +pluginsdir=$(PACKAGE_PLUGINS_DIR) + +plugins_LTLIBRARIES=libmsx264.la + +libmsx264_la_SOURCES=msx264.c + diff --git a/linphone/mediastreamer2/plugins/msx264/src/msx264.c b/linphone/mediastreamer2/plugins/msx264/src/msx264.c new file mode 100644 index 000000000..327500281 --- /dev/null +++ b/linphone/mediastreamer2/plugins/msx264/src/msx264.c @@ -0,0 +1,517 @@ +/* +mediastreamer2 x264 plugin +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/rfc3984.h" + +#include "ortp/b64.h" + +#include + +#ifdef HAVE_LIBAVCODEC_AVCODEC_H +#include +#include +#else +#include +#include +#endif + +#define REMOVE_PREVENTING_BYTES 1 + +typedef struct _EncData{ + x264_t *enc; + MSVideoSize vsize; + int bitrate; + float fps; + int mode; + uint64_t framenum; + Rfc3984Context packer; + bool_t generate_keyframe; +}EncData; + + +static void enc_init(MSFilter *f){ + EncData *d=ms_new(EncData,1); + d->enc=NULL; + d->bitrate=384000; + d->vsize=MS_VIDEO_SIZE_CIF; + d->fps=30; + d->mode=0; + d->framenum=0; + d->generate_keyframe=FALSE; + f->data=d; +} + +static void enc_uninit(MSFilter *f){ + EncData *d=(EncData*)f->data; + ms_free(d); +} + +static void enc_preprocess(MSFilter *f){ + EncData *d=(EncData*)f->data; + x264_param_t params; + rfc3984_init(&d->packer); + rfc3984_set_mode(&d->packer,d->mode); + rfc3984_enable_stap_a(&d->packer,FALSE); + x264_param_default(¶ms); + params.i_width=d->vsize.width; + params.i_height=d->vsize.height; + params.i_fps_num=(int)d->fps; + params.i_fps_den=1; +#ifdef HACKED_X264 + ms_message("Lucky guy, you have a hacked x264 lib that allows multislicing !"); + params.slice_size_threshold=ms_get_payload_max_size()-100; /*-100 security margin*/ +#endif + /*params.i_level_idc=10;*/ + params.rc.i_rc_method = X264_RC_ABR; + params.rc.i_bitrate=(int)( ( ((float)d->bitrate)*0.8)/1000.0); + params.rc.f_rate_tolerance=0.1; + params.rc.i_vbv_max_bitrate=(int) (((float)d->bitrate)*0.9/1000.0); + params.rc.i_vbv_buffer_size=params.rc.i_vbv_max_bitrate; + params.rc.f_vbv_buffer_init=0.5; + params.b_repeat_headers=1; + params.b_cabac=0;//disable cabac to be baseline + params.i_bframe=0;/*no B frames*/ + d->enc=x264_encoder_open(¶ms); + if (d->enc==NULL) ms_error("Fail to create x264 encoder."); + d->framenum=0; +} + +static void x264_nals_to_msgb(x264_nal_t *xnals, int num_nals, MSQueue * nalus){ + int i; + mblk_t *m; + /*int bytes;*/ + for (i=0;ib_wptr, &bytes, 0, &xnals[i] ); + m->b_wptr+=bytes; + */ + *m->b_wptr=( 0x00 << 7 ) | ( xnals[i].i_ref_idc << 5 ) | xnals[i].i_type; + m->b_wptr++; + memcpy(m->b_wptr,xnals[i].p_payload,xnals[i].i_payload); + m->b_wptr+=xnals[i].i_payload; + if (xnals[i].i_type==7) { + ms_message("A SPS is being sent."); + }else if (xnals[i].i_type==8) { + ms_message("A PPS is being sent."); + } + ms_queue_put(nalus,m); + } +} + +static void enc_process(MSFilter *f){ + EncData *d=(EncData*)f->data; + uint32_t ts=f->ticker->time*90LL; + mblk_t *im; + MSPicture pic; + MSQueue nalus; + ms_queue_init(&nalus); + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + if (yuv_buf_init_from_mblk(&pic,im)==0){ + x264_picture_t xpic; + x264_picture_t oxpic; + x264_nal_t *xnals=NULL; + int num_nals=0; + + if (d->generate_keyframe){ + xpic.i_type=X264_TYPE_IDR; + d->generate_keyframe=FALSE; + }else xpic.i_type=X264_TYPE_AUTO; + xpic.i_qpplus1=0; + xpic.i_pts=d->framenum; + xpic.img.i_csp=X264_CSP_I420; + xpic.img.i_plane=3; + xpic.img.i_stride[0]=pic.strides[0]; + xpic.img.i_stride[1]=pic.strides[1]; + xpic.img.i_stride[2]=pic.strides[2]; + xpic.img.i_stride[3]=0; + xpic.img.plane[0]=pic.planes[0]; + xpic.img.plane[1]=pic.planes[1]; + xpic.img.plane[2]=pic.planes[2]; + xpic.img.plane[3]=0; + if (x264_encoder_encode(d->enc,&xnals,&num_nals,&xpic,&oxpic)==0){ + x264_nals_to_msgb(xnals,num_nals,&nalus); + rfc3984_pack(&d->packer,&nalus,f->outputs[0],ts); + d->framenum++; + }else{ + ms_error("x264_encoder_encode() error."); + } + } + freemsg(im); + } +} + +static void enc_postprocess(MSFilter *f){ + EncData *d=(EncData*)f->data; + rfc3984_uninit(&d->packer); + if (d->enc!=NULL){ + x264_encoder_close(d->enc); + d->enc=NULL; + } +} + +static int enc_set_br(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + d->bitrate=*(int*)arg; + if (d->bitrate>=384000){ + d->vsize=MS_VIDEO_SIZE_CIF; + d->fps=30; + }else if (d->bitrate>=256000){ + d->vsize=MS_VIDEO_SIZE_CIF; + d->fps=15; + }else if (d->bitrate>=128000){ + d->vsize=MS_VIDEO_SIZE_CIF; + d->fps=15; + }else if (d->bitrate>=64000){ + d->vsize=MS_VIDEO_SIZE_CIF; + d->fps=10; + }else if (d->bitrate>=32000){ + d->vsize=MS_VIDEO_SIZE_QCIF; + d->fps=10; + }else{ + d->vsize=MS_VIDEO_SIZE_QCIF; + d->fps=5; + } + ms_message("bitrate set to %i",d->bitrate); + return 0; +} + +static int enc_set_fps(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + d->fps=*(float*)arg; + return 0; +} + +static int enc_get_fps(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + *(float*)arg=d->fps; + return 0; +} + +static int enc_get_vsize(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + *(MSVideoSize*)arg=d->vsize; + return 0; +} + +static int enc_add_fmtp(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + const char *fmtp=(const char *)arg; + char value[12]; + if (fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){ + d->mode=atoi(value); + ms_message("packetization-mode set to %i",d->mode); + } + return 0; +} + +static int enc_req_vfu(MSFilter *f, void *arg){ + EncData *d=(EncData*)f->data; + d->generate_keyframe=TRUE; + return 0; +} + + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_SET_FPS , enc_set_fps }, + { MS_FILTER_SET_BITRATE , enc_set_br }, + { MS_FILTER_GET_FPS , enc_get_fps }, + { MS_FILTER_GET_VIDEO_SIZE, enc_get_vsize }, + { MS_FILTER_ADD_FMTP , enc_add_fmtp }, + { MS_FILTER_REQ_VFU , enc_req_vfu }, + { 0 , NULL } +}; + +static MSFilterDesc x264_enc_desc={ + .id=MS_FILTER_PLUGIN_ID, + .name="MSX264Enc", + .text="A H264 encoder based on x264 project.", + .category=MS_FILTER_ENCODER, + .enc_fmt="H264", + .ninputs=1, + .noutputs=1, + .init=enc_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=enc_methods +}; + +typedef struct _DecData{ + mblk_t *yuv_msg; + mblk_t *sps,*pps; + Rfc3984Context unpacker; + MSPicture outbuf; + struct SwsContext *sws_ctx; + AVCodecContext av_context; + unsigned int packet_num; + uint8_t bitstream[65000]; +}DecData; + +static void ffmpeg_init(){ + static bool_t done=FALSE; + if (!done){ + avcodec_init(); + avcodec_register_all(); + done=TRUE; + } +} + +static void dec_open(DecData *d){ + AVCodec *codec; + int error; + codec=avcodec_find_decoder(CODEC_ID_H264); + if (codec==NULL) ms_fatal("Could not find H264 decoder in ffmpeg."); + avcodec_get_context_defaults(&d->av_context); + error=avcodec_open(&d->av_context,codec); + if (error!=0){ + ms_fatal("avcodec_open() failed."); + } +} + +static void dec_init(MSFilter *f){ + DecData *d=(DecData*)ms_new(DecData,1); + ffmpeg_init(); + d->yuv_msg=NULL; + d->sps=NULL; + d->pps=NULL; + d->sws_ctx=NULL; + rfc3984_init(&d->unpacker); + d->packet_num=0; + dec_open(d); + d->outbuf.w=0; + d->outbuf.h=0; + f->data=d; +} + +static void dec_reinit(DecData *d){ + avcodec_close(&d->av_context); + dec_open(d); +} + +static void dec_uninit(MSFilter *f){ + DecData *d=(DecData*)f->data; + rfc3984_uninit(&d->unpacker); + avcodec_close(&d->av_context); + if (d->yuv_msg) freemsg(d->yuv_msg); + if (d->sps) freemsg(d->sps); + if (d->pps) freemsg(d->pps); + ms_free(d); +} + +static mblk_t *get_as_yuvmsg(MSFilter *f, DecData *s, AVFrame *orig){ + AVCodecContext *ctx=&s->av_context; + + if (s->outbuf.w!=ctx->width || s->outbuf.h!=ctx->height){ + if (s->sws_ctx!=NULL){ + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + freemsg(s->yuv_msg); + s->yuv_msg=NULL; + } + ms_message("Getting yuv picture of %ix%i",ctx->width,ctx->height); + s->yuv_msg=yuv_buf_alloc(&s->outbuf,ctx->width,ctx->height); + s->outbuf.w=ctx->width; + s->outbuf.h=ctx->height; + s->sws_ctx=sws_getContext(ctx->width,ctx->height,ctx->pix_fmt, + ctx->width,ctx->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR, + NULL, NULL, NULL); + } + if (sws_scale(s->sws_ctx,orig->data,orig->linesize, 0, + ctx->height, s->outbuf.planes, s->outbuf.strides)<0){ + ms_error("%s: error in sws_scale().",f->desc->name); + } + return dupmsg(s->yuv_msg); +} + +static void update_sps(DecData *d, mblk_t *sps){ + if (d->sps) + freemsg(d->sps); + d->sps=dupb(sps); +} + +static void update_pps(DecData *d, mblk_t *pps){ + if (d->pps) + freemsg(d->pps); + d->pps=dupb(pps); +} + +static bool_t check_sps_pps_change(DecData *d, mblk_t *sps, mblk_t *pps){ + bool_t ret1=FALSE,ret2=FALSE; + if (d->sps){ + if (sps){ + ret1=(msgdsize(sps)!=msgdsize(d->sps)) || (memcmp(d->sps->b_rptr,sps->b_rptr,msgdsize(sps))!=0); + if (ret1) { + update_sps(d,sps); + ms_message("SPS changed !"); + } + } + }else if (sps) { + ms_message("Receiving first SPS"); + update_sps(d,sps); + } + if (d->pps){ + if (pps){ + ret2=(msgdsize(pps)!=msgdsize(d->pps)) || (memcmp(d->pps->b_rptr,pps->b_rptr,msgdsize(pps))!=0); + if (ret2) { + update_sps(d,pps); + ms_message("PPS changed ! %i,%i",msgdsize(pps),msgdsize(d->pps)); + } + } + }else if (pps) { + ms_message("Receiving first PPS"); + update_pps(d,pps); + } + return ret1 || ret2; +} + +static int nalusToFrame(DecData *d, MSQueue *naluq, uint8_t *bitstream, int size, bool_t *new_sps_pps){ + mblk_t *im; + uint8_t *dst=bitstream,*src; + bool_t start_picture=TRUE; + uint8_t nalu_type; + *new_sps_pps=FALSE; + while((im=ms_queue_get(naluq))!=NULL){ + src=im->b_rptr; + nalu_type=(*src) & ((1<<5)-1); + if (nalu_type==7) + *new_sps_pps=check_sps_pps_change(d,im,NULL) || *new_sps_pps; + if (nalu_type==8) + *new_sps_pps=check_sps_pps_change(d,NULL,im) || *new_sps_pps; + if (start_picture || nalu_type==7/*SPS*/ || nalu_type==8/*PPS*/ ){ + *dst++=0; + start_picture=FALSE; + } + /*prepend nal marker*/ + *dst++=0; + *dst++=0; + *dst++=1; + *dst++=*src++; + while(src<(im->b_wptr-3)){ +#ifdef REMOVE_PREVENTING_BYTES + if (src[0]==0 && src[1]==0 && src[2]<=3){ + *dst++=0; + *dst++=0; + *dst++=3; + src+=2; + } +#endif + *dst++=*src++; + } + *dst++=*src++; + *dst++=*src++; + *dst++=*src++; + freemsg(im); + } + return dst-bitstream; +} + +static void dec_process(MSFilter *f){ + DecData *d=(DecData*)f->data; + mblk_t *im; + MSQueue nalus; + AVFrame orig; + ms_queue_init(&nalus); + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + /*push the sps/pps given in sprop-parameter-sets if any*/ + if (d->packet_num==0 && d->sps && d->pps){ + mblk_set_timestamp_info(d->sps,mblk_get_timestamp_info(im)); + mblk_set_timestamp_info(d->pps,mblk_get_timestamp_info(im)); + rfc3984_unpack(&d->unpacker,d->sps,&nalus); + rfc3984_unpack(&d->unpacker,d->pps,&nalus); + d->sps=NULL; + d->pps=NULL; + } + rfc3984_unpack(&d->unpacker,im,&nalus); + if (!ms_queue_empty(&nalus)){ + int size; + uint8_t *p,*end; + bool_t need_reinit=FALSE; + + size=nalusToFrame(d,&nalus,d->bitstream,sizeof(d->bitstream),&need_reinit); + if (need_reinit) + dec_reinit(d); + p=d->bitstream; + end=d->bitstream+size; + while (end-p>0) { + int len; + int got_picture=0; + avcodec_get_frame_defaults(&orig); + len=avcodec_decode_video(&d->av_context,&orig,&got_picture,p,end-p); + if (len<=0) { + ms_warning("ms_AVdecoder_process: error %i.",len); + break; + } + if (got_picture) { + ms_queue_put(f->outputs[0],get_as_yuvmsg(f,d,&orig)); + } + p+=len; + } + } + d->packet_num++; + } +} + +static int dec_add_fmtp(MSFilter *f, void *arg){ + DecData *d=(DecData*)f->data; + const char *fmtp=(const char *)arg; + char value[256]; + if (fmtp_get_value(fmtp,"sprop-parameter-sets",value,sizeof(value))){ + char * b64_sps=value; + char * b64_pps=strchr(value,','); + if (b64_pps){ + *b64_pps='\0'; + ++b64_pps; + ms_message("Got sprop-parameter-sets : sps=%s , pps=%s",b64_sps,b64_pps); + d->sps=allocb(sizeof(value),0); + d->sps->b_wptr+=b64_decode(b64_sps,strlen(b64_sps),d->sps->b_wptr,sizeof(value)); + d->pps=allocb(sizeof(value),0); + d->pps->b_wptr+=b64_decode(b64_pps,strlen(b64_pps),d->pps->b_wptr,sizeof(value)); + } + } + return 0; +} + +static MSFilterMethod h264_dec_methods[]={ + { MS_FILTER_ADD_FMTP , dec_add_fmtp }, + { 0 , NULL } +}; + +static MSFilterDesc h264_dec_desc={ + .id=MS_FILTER_PLUGIN_ID, + .name="MSH264Dec", + .text="A H264 decoder based on ffmpeg project.", + .category=MS_FILTER_DECODER, + .enc_fmt="H264", + .ninputs=1, + .noutputs=1, + .init=dec_init, + .process=dec_process, + .uninit=dec_uninit, + .methods=h264_dec_methods +}; + +void libmsx264_init(void){ + ms_filter_register(&x264_enc_desc); + ms_filter_register(&h264_dec_desc); +} diff --git a/linphone/mediastreamer2/src/.cvsignore b/linphone/mediastreamer2/src/.cvsignore new file mode 100644 index 000000000..9c4a34a80 --- /dev/null +++ b/linphone/mediastreamer2/src/.cvsignore @@ -0,0 +1,8 @@ +Makefile.in +Makefile +.libs +.deps +*.la +*.lo +alldescs.h +filterdescs.txt diff --git a/linphone/mediastreamer2/src/Makefile.am b/linphone/mediastreamer2/src/Makefile.am new file mode 100644 index 000000000..5d4e03694 --- /dev/null +++ b/linphone/mediastreamer2/src/Makefile.am @@ -0,0 +1,136 @@ + +EXTRA_DIST= winsnd2.c winsnd.c winvideo.c winvideods.c wincevideods.c dxfilter.h dxfilter.cpp msfileplayer_win.c msfilerec_win.c winsndds.cpp nowebcamCIF.jpg + +BUILT_SOURCES=alldescs.h + +CLEANFILES=alldescs.h filterdescs.txt + +INCLUDES=-I$(top_srcdir)/include/ + +lib_LTLIBRARIES=libmediastreamer.la + +libmediastreamer_la_SOURCES= mscommon.c \ + msfilter.c \ + msqueue.c \ + msticker.c \ + alaw.c \ + ulaw.c \ + mssndcard.c \ + msfileplayer.c \ + msrtp.c \ + dtmfgen.c \ + msfilerec.c \ + ice.c \ + tee.c \ + msconf.c \ + msjoin.c \ + g711common.h \ + msvolume.c \ + mswebcam.c \ + mtu.c + + +libmediastreamer_la_SOURCES+=audiostream.c + +if BUILD_RESAMPLE +libmediastreamer_la_SOURCES+=msresample.c +endif + +if BUILD_ALSA +libmediastreamer_la_SOURCES+=alsa.c +endif + +if BUILD_OSS +libmediastreamer_la_SOURCES+=oss.c +endif + +if BUILD_ARTS +libmediastreamer_la_SOURCES+=arts.c +endif + +if BUILD_PORTAUDIO +libmediastreamer_la_SOURCES+=pasnd.c +endif + +if BUILD_MACSND +libmediastreamer_la_SOURCES+=macsnd.c +endif + +if BUILD_MACAQSND +libmediastreamer_la_SOURCES+=aqsnd.c +endif + + +if BUILD_VIDEO + +if BUILD_MACOSX +libmediastreamer_la_SOURCES+=msv4m.c +else +libmediastreamer_la_SOURCES+=msv4l.c msv4l2.c +endif + +libmediastreamer_la_SOURCES+= sdlout.c \ + videoenc.c \ + videodec.c \ + pixconv.c \ + sizeconv.c \ + rfc2429.h \ + nowebcam.c nowebcam.h \ + videoout.c \ + msvideo.c \ + rfc3984.c \ + mire.c \ + swscale.h ffmpeg-priv.h + +libmediastreamer_la_SOURCES+=videostream.c + +endif + +if BUILD_THEORA +libmediastreamer_la_SOURCES+=theora.c +endif + +if BUILD_SPEEX +libmediastreamer_la_SOURCES+=msspeex.c speexec.c +endif + +if BUILD_GSM +libmediastreamer_la_SOURCES+=gsm.c +endif + +alldescs.h: Makefile.am $(libmediastreamer_la_SOURCES) + builddir=`pwd` && cd $(srcdir) && \ + awk 'BEGIN { FS="[()]" ; }; /^\t*MS_FILTER_DESC_EXPORT/{ printf("%s\n", $$2) } ' > $$builddir/filterdescs.txt $(libmediastreamer_la_SOURCES) && \ + awk 'BEGIN { print("#include \"mediastreamer2/msfilter.h\"\n") } { printf("extern MSFilterDesc %s;\n",$$1) } ' $$builddir/filterdescs.txt > $$builddir/$@ && \ + awk 'BEGIN { print("MSFilterDesc * ms_filter_descs[]={") } { printf("&%s,\n",$$1) } END{ print("NULL\n};\n") } ' $$builddir/filterdescs.txt >> $$builddir/$@ + + +libmediastreamer_la_LIBADD= $(ORTP_LIBS) \ + $(PORTAUDIO_LIBS) \ + $(ALSA_LIBS) \ + $(ARTS_LIBS) \ + $(SPEEX_LIBS) \ + $(GSM_LIBS) \ + $(THEORA_LIBS) + +libmediastreamer_la_LDFLAGS=-rdynamic + +if BUILD_VIDEO +libmediastreamer_la_LIBADD+=$(VIDEO_LIBS) +endif + + +AM_CFLAGS= -I$(top_srcdir) \ + $(ORTP_CFLAGS) \ + $(SPEEX_CFLAGS) \ + $(GSM_CFLAGS) \ + $(STRICT_OPTIONS) + +if BUILD_VIDEO +AM_CFLAGS+=$(VIDEO_CFLAGS) +endif + +imgdir=$(datadir)/images/ + +img_DATA=nowebcamCIF.jpg + diff --git a/linphone/mediastreamer2/src/alaw.c b/linphone/mediastreamer2/src/alaw.c new file mode 100644 index 000000000..ff07ce1da --- /dev/null +++ b/linphone/mediastreamer2/src/alaw.c @@ -0,0 +1,222 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" +#include "g711common.h" + +typedef struct _AlawEncData{ + MSBufferizer *bz; + int ptime; + uint32_t ts; +} AlawEncData; + +static AlawEncData * alaw_enc_data_new(){ + AlawEncData *obj=(AlawEncData *)ms_new(AlawEncData,1); + obj->bz=ms_bufferizer_new(); + obj->ptime=0; + obj->ts=0; + return obj; +} + +static void alaw_enc_data_destroy(AlawEncData *obj){ + ms_bufferizer_destroy(obj->bz); + ms_free(obj); +} + +static void alaw_enc_init(MSFilter *obj){ + obj->data=alaw_enc_data_new(); +} + +static void alaw_enc_uninit(MSFilter *obj){ + alaw_enc_data_destroy((AlawEncData*)obj->data); +} + +static void alaw_enc_process(MSFilter *obj){ + AlawEncData *dt=(AlawEncData*)obj->data; + MSBufferizer *bz=dt->bz; + uint8_t buffer[2240]; + int frame_per_packet=2; + int size_of_pcm=320; + + mblk_t *m; + + if (dt->ptime>=10) + { + frame_per_packet = dt->ptime/10; + } + + if (frame_per_packet<=0) + frame_per_packet=1; + if (frame_per_packet>14) /* 7*20 == 140 ms max */ + frame_per_packet=14; + + size_of_pcm = 160*frame_per_packet; /* ex: for 20ms -> 160*2==320 */ + + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + ms_bufferizer_put(bz,m); + } + while (ms_bufferizer_read(bz,buffer,size_of_pcm)==size_of_pcm){ + mblk_t *o=allocb(size_of_pcm/2,0); + int i; + for (i=0;ib_wptr=s16_to_alaw(((int16_t*)buffer)[i]); + o->b_wptr++; + } + mblk_set_timestamp_info(o,dt->ts); + dt->ts+=size_of_pcm/2; + ms_queue_put(obj->outputs[0],o); + } +} + +static int enc_add_fmtp(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + AlawEncData *s=(AlawEncData*)f->data; + char tmp[30]; + if (fmtp_get_value(fmtp,"ptime",tmp,sizeof(tmp))){ + s->ptime=atoi(tmp); + ms_message("MSAlawEnc: got ptime=%i",s->ptime); + } + return 0; +} + +static int enc_add_attr(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + AlawEncData *s=(AlawEncData*)f->data; + if (strstr(fmtp,"ptime:10")!=NULL){ + s->ptime=10; + }else if (strstr(fmtp,"ptime:20")!=NULL){ + s->ptime=20; + }else if (strstr(fmtp,"ptime:30")!=NULL){ + s->ptime=30; + }else if (strstr(fmtp,"ptime:40")!=NULL){ + s->ptime=40; + }else if (strstr(fmtp,"ptime:50")!=NULL){ + s->ptime=50; + }else if (strstr(fmtp,"ptime:60")!=NULL){ + s->ptime=60; + }else if (strstr(fmtp,"ptime:70")!=NULL){ + s->ptime=70; + }else if (strstr(fmtp,"ptime:80")!=NULL){ + s->ptime=80; + }else if (strstr(fmtp,"ptime:90")!=NULL){ + s->ptime=90; + }else if (strstr(fmtp,"ptime:100")!=NULL){ + s->ptime=100; + }else if (strstr(fmtp,"ptime:110")!=NULL){ + s->ptime=110; + }else if (strstr(fmtp,"ptime:120")!=NULL){ + s->ptime=120; + }else if (strstr(fmtp,"ptime:130")!=NULL){ + s->ptime=130; + }else if (strstr(fmtp,"ptime:140")!=NULL){ + s->ptime=140; + } + return 0; +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_ADD_ATTR , enc_add_attr}, + { MS_FILTER_ADD_FMTP , enc_add_fmtp}, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_alaw_enc_desc={ + MS_ALAW_ENC_ID, + "MSAlawEnc", + "ITU-G.711 alaw encoder", + MS_FILTER_ENCODER, + "pcma", + 1, + 1, + alaw_enc_init, + NULL, + alaw_enc_process, + NULL, + alaw_enc_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_alaw_enc_desc={ + .id=MS_ALAW_ENC_ID, + .name="MSAlawEnc", + .text="ITU-G.711 alaw encoder", + .category=MS_FILTER_ENCODER, + .enc_fmt="pcma", + .ninputs=1, + .noutputs=1, + .init=alaw_enc_init, + .process=alaw_enc_process, + .uninit=alaw_enc_uninit, + .methods=enc_methods +}; + +#endif + +static void alaw_dec_process(MSFilter *obj){ + mblk_t *m; + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + mblk_t *o; + msgpullup(m,-1); + o=allocb((m->b_wptr-m->b_rptr)*2,0); + for(;m->b_rptrb_wptr;m->b_rptr++,o->b_wptr+=2){ + *((int16_t*)(o->b_wptr))=alaw_to_s16(*m->b_rptr); + } + freemsg(m); + ms_queue_put(obj->outputs[0],o); + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_alaw_dec_desc={ + MS_ALAW_DEC_ID, + "MSAlawDec", + "ITU-G.711 alaw decoder", + MS_FILTER_DECODER, + "pcma", + 1, + 1, + NULL, + NULL, + alaw_dec_process, + NULL, + NULL +}; + +#else + +MSFilterDesc ms_alaw_dec_desc={ + .id=MS_ALAW_DEC_ID, + .name="MSAlawDec", + .text="ITU-G.711 alaw decoder", + .category=MS_FILTER_DECODER, + .enc_fmt="pcma", + .ninputs=1, + .noutputs=1, + .process=alaw_dec_process, +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_alaw_dec_desc) +MS_FILTER_DESC_EXPORT(ms_alaw_enc_desc) diff --git a/linphone/mediastreamer2/src/alsa.c b/linphone/mediastreamer2/src/alsa.c new file mode 100644 index 000000000..8dd3f25f3 --- /dev/null +++ b/linphone/mediastreamer2/src/alsa.c @@ -0,0 +1,948 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + + +#include + + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/mssndcard.h" + +//#define THREADED_VERSION + +/*in case of troubles with a particular driver, try incrementing ALSA_PERIOD_SIZE +to 512, 1024, 2048, 4096... +then try incrementing the number of periods*/ +#define ALSA_PERIODS 8 +#define ALSA_PERIOD_SIZE 256 + +/*uncomment the following line if you have problems with an alsa driver +having sound quality trouble:*/ +/*#define EPIPE_BUGFIX 1*/ + +static MSSndCard * alsa_card_new(int id); +static MSSndCard *alsa_card_duplicate(MSSndCard *obj); +static MSFilter * ms_alsa_read_new(const char *dev); +static MSFilter * ms_alsa_write_new(const char *dev); + + +struct _AlsaData{ + char *pcmdev; + char *mixdev; +}; + +typedef struct _AlsaData AlsaData; + + +static int alsa_set_params(snd_pcm_t *pcm_handle, int rw, int bits, int stereo, int rate) +{ + snd_pcm_hw_params_t *hwparams=NULL; + snd_pcm_sw_params_t *swparams=NULL; + int dir; + uint exact_uvalue; + unsigned long exact_ulvalue; + int channels; + int periods=ALSA_PERIODS; + int periodsize=ALSA_PERIOD_SIZE; + int err; + int format; + + /* Allocate the snd_pcm_hw_params_t structure on the stack. */ + snd_pcm_hw_params_alloca(&hwparams); + + /* Init hwparams with full configuration space */ + if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) { + ms_warning("alsa_set_params: Cannot configure this PCM device."); + return -1; + } + + if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + ms_warning("alsa_set_params: Error setting access."); + return -1; + } + /* Set sample format */ + format=SND_PCM_FORMAT_S16; + if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) < 0) { + ms_warning("alsa_set_params: Error setting format."); + return -1; + } + /* Set number of channels */ + if (stereo) channels=2; + else channels=1; + if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels) < 0) { + ms_warning("alsa_set_params: Error setting channels."); + return -1; + } + /* Set sample rate. If the exact rate is not supported */ + /* by the hardware, use nearest possible rate. */ + exact_uvalue=rate; + dir=0; + if ((err=snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_uvalue, &dir))<0){ + ms_warning("alsa_set_params: Error setting rate to %i:%s",rate,snd_strerror(err)); + return -1; + } + if (dir != 0) { + ms_warning("alsa_set_params: The rate %d Hz is not supported by your hardware.\n " + "==> Using %d Hz instead.", rate, exact_uvalue); + } + /* choose greater period size when rate is high */ + periodsize=periodsize*(rate/8000); + + /* Set buffer size (in frames). The resulting latency is given by */ + /* latency = periodsize * periods / (rate * bytes_per_frame) */ + /* set period size */ + exact_ulvalue=periodsize; + dir=0; + if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &exact_ulvalue, &dir) < 0) { + ms_warning("alsa_set_params: Error setting period size."); + return -1; + } + if (dir != 0) { + ms_warning("alsa_set_params: The period size %d is not supported by your hardware.\n " + "==> Using %d instead.", periodsize, (int)exact_ulvalue); + } + ms_warning("alsa_set_params: periodsize:%d Using %d", periodsize, (int)exact_ulvalue); + periodsize=exact_ulvalue; + /* Set number of periods. Periods used to be called fragments. */ + exact_uvalue=periods; + dir=0; + if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &exact_uvalue, &dir) < 0) { + ms_warning("alsa_set_params: Error setting periods."); + return -1; + } + ms_warning("alsa_set_params: period:%d Using %d", periods, exact_uvalue); + if (dir != 0) { + ms_warning("alsa_set_params: The number of periods %d is not supported by your hardware.\n " + "==> Using %d instead.", periods, exact_uvalue); + } + /* Apply HW parameter settings to */ + /* PCM device and prepare device */ + if ((err=snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { + ms_warning("alsa_set_params: Error setting HW params:%s",snd_strerror(err)); + return -1; + } + /*prepare sw params */ + if (rw){ + snd_pcm_sw_params_alloca(&swparams); + snd_pcm_sw_params_current(pcm_handle, swparams); + if ((err=snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,periodsize*2 ))<0){ + ms_warning("alsa_set_params: Error setting start threshold:%s",snd_strerror(err)); + } + if ((err=snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams,periodsize*periods ))<0){ + ms_warning("alsa_set_params: Error setting stop threshold:%s",snd_strerror(err)); + } + if ((err=snd_pcm_sw_params(pcm_handle, swparams))<0){ + ms_warning("alsa_set_params: Error setting SW params:%s",snd_strerror(err)); + return -1; + } + } + return 0; +} + +#ifdef EPIPE_BUGFIX +static void alsa_fill_w (snd_pcm_t *pcm_handle) +{ + snd_pcm_hw_params_t *hwparams=NULL; + int channels; + snd_pcm_uframes_t buffer_size; + int buffer_size_bytes; + void *buffer; + + /* Allocate the snd_pcm_hw_params_t structure on the stack. */ + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_hw_params_current(pcm_handle, hwparams); + + /* get channels */ + snd_pcm_hw_params_get_channels (hwparams, &channels); + + /* get buffer size */ + snd_pcm_hw_params_get_buffer_size (hwparams, &buffer_size); + + /* fill half */ + buffer_size /= 2; + + /* allocate buffer assuming 2 bytes per sample */ + buffer_size_bytes = buffer_size * channels * 2; + buffer = alloca (buffer_size_bytes); + memset (buffer, 0, buffer_size_bytes); + + /* write data */ + snd_pcm_writei(pcm_handle, buffer, buffer_size); +} +#endif + +static snd_pcm_t * alsa_open_r(const char *pcmdev,int bits,int stereo,int rate) +{ + snd_pcm_t *pcm_handle; + int err; + + ms_message("alsa_open_r: opening %s at %iHz, bits=%i, stereo=%i",pcmdev,rate,bits,stereo); + + +#ifndef THREADED_VERSION + if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_CAPTURE,SND_PCM_NONBLOCK) < 0) { + ms_warning("alsa_open_r: Error opening PCM device %s",pcmdev ); + return NULL; + } +#else + /* want blocking mode for threaded version */ + if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_CAPTURE,0) < 0) { + ms_warning("alsa_open_r: Error opening PCM device %s",pcmdev ); + return NULL; + } +#endif + if (alsa_set_params(pcm_handle,0,bits,stereo,rate)<0){ + snd_pcm_close(pcm_handle); + return NULL; + } + err=snd_pcm_start(pcm_handle); + if (err<0){ + ms_warning("snd_pcm_start() failed: %s", snd_strerror(err)); + } + return pcm_handle; +} + +static snd_pcm_t * alsa_open_w(const char *pcmdev,int bits,int stereo,int rate) +{ + snd_pcm_t *pcm_handle; + + if (snd_pcm_open(&pcm_handle, pcmdev,SND_PCM_STREAM_PLAYBACK,SND_PCM_NONBLOCK) < 0) { + ms_warning("alsa_open_w: Error opening PCM device %s",pcmdev ); + return NULL; + } + if (alsa_set_params(pcm_handle,1,bits,stereo,rate)<0){ + snd_pcm_close(pcm_handle); + return NULL; + } + return pcm_handle; +} + +static int alsa_can_read(snd_pcm_t *dev, int frames) +{ + snd_pcm_sframes_t avail; + int err; + + avail = snd_pcm_avail_update(dev); + ms_debug("*** %s %d %d", __FUNCTION__, (long)avail, frames); + if (avail < 0) { + ms_error("snd_pcm_avail_update: %s", snd_strerror(avail)); // most probably -EPIPE + /* overrun occured, snd_pcm_state() would return SND_PCM_STATE_XRUN + FIXME: handle other error conditions*/ + ms_error("*** alsa_can_read fixup, trying to recover"); + snd_pcm_drain(dev); /* Ignore possible error, at least -EAGAIN.*/ + err = snd_pcm_recover(dev, avail, 0); + if (err){ + ms_error("snd_pcm_recover() failed with err %d: %s", err, snd_strerror(err)); + return -1; + } + err = snd_pcm_start(dev); + if (err){ + ms_error("snd_pcm_start() failed with err %d: %s", err, snd_strerror(err)); + return -1; + } + ms_message("Recovery done"); + } + return avail; +} + +static int alsa_read(snd_pcm_t *handle,unsigned char *buf,int nsamples) +{ + int err; + err=snd_pcm_readi(handle,buf,nsamples); + if (err<0) { + ms_warning("alsa_read: snd_pcm_readi() returned %i",err); + if (err==-EPIPE){ + snd_pcm_prepare(handle); + err=snd_pcm_readi(handle,buf,nsamples); + if (err<0) ms_warning("alsa_read: snd_pcm_readi() failed:%s.",snd_strerror(err)); + }else if (err!=-EWOULDBLOCK){ + ms_warning("alsa_read: snd_pcm_readi() failed:%s.",snd_strerror(err)); + } + }else if (err==0){ + ms_warning("alsa_read: snd_pcm_readi() returned 0"); + } + return err; +} + + +static int alsa_write(snd_pcm_t *handle,unsigned char *buf,int nsamples) +{ + int err; + if ((err=snd_pcm_writei(handle,buf,nsamples))<0){ + if (err==-EPIPE){ + snd_pcm_prepare(handle); +#ifdef EPIPE_BUGFIX + alsa_fill_w (handle); +#endif + err=snd_pcm_writei(handle,buf,nsamples); + if (err<0) ms_warning("alsa_card_write: Error writing sound buffer (nsamples=%i):%s",nsamples,snd_strerror(err)); + }else if (err!=-EWOULDBLOCK){ + ms_warning("alsa_card_write: snd_pcm_writei() failed:%s.",snd_strerror(err)); + } + }else if (err!=nsamples) { + ms_debug("Only %i samples written instead of %i",err,nsamples); + } + return err; +} + + +static snd_mixer_t *alsa_mixer_open(const char *mixdev){ + snd_mixer_t *mixer=NULL; + int err; + err=snd_mixer_open(&mixer,0); + if (err<0){ + ms_warning("Could not open alsa mixer: %s",snd_strerror(err)); + return NULL; + } + if ((err = snd_mixer_attach (mixer, mixdev)) < 0){ + ms_warning("Could not attach mixer to card: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + if ((err = snd_mixer_selem_register (mixer, NULL, NULL)) < 0){ + ms_warning("snd_mixer_selem_register: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + if ((err = snd_mixer_load (mixer)) < 0){ + ms_warning("snd_mixer_load: %s",snd_strerror(err)); + snd_mixer_close(mixer); + return NULL; + } + return mixer; +} + +static void alsa_mixer_close(snd_mixer_t *mix){ + snd_mixer_close(mix); +} + +typedef enum {CAPTURE, PLAYBACK, CAPTURE_SWITCH, PLAYBACK_SWITCH} MixerAction; + +static int get_mixer_element(snd_mixer_t *mixer,const char *name, MixerAction action){ + long value=0; + const char *elemname; + snd_mixer_elem_t *elem; + int err; + long sndMixerPMin=0; + long sndMixerPMax=0; + long newvol=0; + elem=snd_mixer_first_elem(mixer); + while (elem!=NULL){ + elemname=snd_mixer_selem_get_name(elem); + //ms_message("Found alsa mixer element %s.",elemname); + if (strcmp(elemname,name)==0){ + switch (action){ + case CAPTURE: + if (snd_mixer_selem_has_capture_volume(elem)){ + snd_mixer_selem_get_capture_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + err=snd_mixer_selem_get_capture_volume(elem,SND_MIXER_SCHN_UNKNOWN,&newvol); + newvol-=sndMixerPMin; + value=(100*newvol)/(sndMixerPMax-sndMixerPMin); + if (err<0) ms_warning("Could not get capture volume for %s:%s",name,snd_strerror(err)); + //else ms_message("Successfully get capture level for %s.",elemname); + break; + } + break; + case PLAYBACK: + if (snd_mixer_selem_has_playback_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + err=snd_mixer_selem_get_playback_volume(elem,SND_MIXER_SCHN_FRONT_LEFT,&newvol); + newvol-=sndMixerPMin; + value=(100*newvol)/(sndMixerPMax-sndMixerPMin); + if (err<0) ms_warning("Could not get playback volume for %s:%s",name,snd_strerror(err)); + //else ms_message("Successfully get playback level for %s.",elemname); + break; + } + break; + case CAPTURE_SWITCH: + + break; + case PLAYBACK_SWITCH: + + break; + } + } + elem=snd_mixer_elem_next(elem); + } + + return value; +} + + +static void set_mixer_element(snd_mixer_t *mixer,const char *name, int level,MixerAction action){ + const char *elemname; + snd_mixer_elem_t *elem; + long sndMixerPMin=0; + long sndMixerPMax=0; + long newvol=0; + + elem=snd_mixer_first_elem(mixer); + + while (elem!=NULL){ + elemname=snd_mixer_selem_get_name(elem); + //ms_message("Found alsa mixer element %s.",elemname); + if (strcmp(elemname,name)==0){ + switch(action){ + case CAPTURE: + if (snd_mixer_selem_has_capture_volume(elem)){ + snd_mixer_selem_get_capture_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; + snd_mixer_selem_set_capture_volume_all(elem,newvol); + //ms_message("Successfully set capture level for %s.",elemname); + return; + } + break; + case PLAYBACK: + if (snd_mixer_selem_has_playback_volume(elem)){ + snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax); + newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin; + snd_mixer_selem_set_playback_volume_all(elem,newvol); + //ms_message("Successfully set playback level for %s.",elemname); + return; + } + break; + case CAPTURE_SWITCH: + if (snd_mixer_selem_has_capture_switch(elem)){ + snd_mixer_selem_set_capture_switch_all(elem,level); + //ms_message("Successfully set capture switch for %s.",elemname); + } + break; + case PLAYBACK_SWITCH: + if (snd_mixer_selem_has_playback_switch(elem)){ + snd_mixer_selem_set_playback_switch_all(elem,level); + //ms_message("Successfully set capture switch for %s.",elemname); + } + break; + + } + } + elem=snd_mixer_elem_next(elem); + } + + return ; +} + + +static void alsa_card_set_level(MSSndCard *obj,MSSndCardMixerElem e,int a) +{ + snd_mixer_t *mixer; + AlsaData *ad=(AlsaData*)obj->data; + mixer=alsa_mixer_open(ad->mixdev); + if (mixer==NULL) return ; + switch(e){ + case MS_SND_CARD_MASTER: + set_mixer_element(mixer,"Master",a,PLAYBACK); + break; + case MS_SND_CARD_CAPTURE: + set_mixer_element(mixer,"Capture",a,CAPTURE); + break; + case MS_SND_CARD_PLAYBACK: + set_mixer_element(mixer,"PCM",a,PLAYBACK); + break; + default: + ms_warning("alsa_card_set_level: unsupported command."); + } + alsa_mixer_close(mixer); +} + +static int alsa_card_get_level(MSSndCard *obj, MSSndCardMixerElem e) +{ + snd_mixer_t *mixer; + AlsaData *ad=(AlsaData*)obj->data; + int value = -1; + mixer=alsa_mixer_open(ad->mixdev); + if (mixer==NULL) return 0; + switch(e){ + case MS_SND_CARD_MASTER: + value=get_mixer_element(mixer,"Master",PLAYBACK); + break; + case MS_SND_CARD_CAPTURE: + value=get_mixer_element(mixer,"Capture",CAPTURE); + break; + case MS_SND_CARD_PLAYBACK: + value=get_mixer_element(mixer,"PCM",PLAYBACK); + break; + default: + ms_warning("alsa_card_set_level: unsupported command."); + } + alsa_mixer_close(mixer); + return value; +} + +static void alsa_card_set_source(MSSndCard *obj,MSSndCardCapture source) +{ + snd_mixer_t *mixer; + AlsaData *ad=(AlsaData*)obj->data; + mixer=alsa_mixer_open(ad->mixdev); + if (mixer==NULL) return; + switch (source){ + case MS_SND_CARD_MIC: + set_mixer_element(mixer,"Mic",1,CAPTURE_SWITCH); + set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); + break; + case MS_SND_CARD_LINE: + set_mixer_element(mixer,"Line",1,CAPTURE_SWITCH); + set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH); + break; + } + alsa_mixer_close(mixer); +} + +static MSFilter *alsa_card_create_reader(MSSndCard *card) +{ + AlsaData *ad=(AlsaData*)card->data; + MSFilter *f=ms_alsa_read_new(ad->pcmdev); + return f; +} + +static MSFilter *alsa_card_create_writer(MSSndCard *card) +{ + AlsaData *ad=(AlsaData*)card->data; + MSFilter *f=ms_alsa_write_new(ad->pcmdev); + return f; +} + + +static void alsa_card_init(MSSndCard *obj){ + AlsaData *ad=ms_new0(AlsaData,1); + obj->data=ad; +} + +static void alsa_card_uninit(MSSndCard *obj){ + AlsaData *ad=(AlsaData*)obj->data; + if (ad->pcmdev!=NULL) ms_free(ad->pcmdev); + if (ad->mixdev!=NULL) ms_free(ad->mixdev); + ms_free(ad); +} + +static void alsa_card_detect(MSSndCardManager *m){ + int i; + for (i=-1;i<10;i++){ + MSSndCard *card=alsa_card_new(i); + if (card!=NULL) + ms_snd_card_manager_add_card(m,card); + } +} + +MSSndCardDesc alsa_card_desc={ + .driver_type="ALSA", + .detect=alsa_card_detect, + .init=alsa_card_init, + .set_level=alsa_card_set_level, + .get_level=alsa_card_get_level, + .set_capture=alsa_card_set_source, + .create_reader=alsa_card_create_reader, + .create_writer=alsa_card_create_writer, + .uninit=alsa_card_uninit, + .duplicate=alsa_card_duplicate +}; + +static MSSndCard *alsa_card_duplicate(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&alsa_card_desc); + AlsaData* dcard=(AlsaData*)card->data; + AlsaData* dobj=(AlsaData*)obj->data; + card->name=ms_strdup(obj->name); + card->id=ms_strdup(obj->id); + dcard->pcmdev=ms_strdup(dobj->pcmdev); + dcard->mixdev=ms_strdup(dobj->mixdev); + return card; +} + +MSSndCard * ms_alsa_card_new_custom(const char *pcmdev, const char *mixdev){ + MSSndCard * obj; + AlsaData *ad; + obj=ms_snd_card_new(&alsa_card_desc); + ad=(AlsaData*)obj->data; + obj->name=ms_strdup(pcmdev); + ad->pcmdev=ms_strdup(pcmdev); + ad->mixdev=ms_strdup(mixdev); + return obj; +} + +static MSSndCard * alsa_card_new(int id) +{ + MSSndCard * obj; + char *name=NULL; + AlsaData *ad; + int err; + if (id!=-1){ + err=snd_card_get_name(id,&name); + if (err<0) { + return NULL; + } + } + obj=ms_snd_card_new(&alsa_card_desc); + ad=(AlsaData*)obj->data; + if (id==-1) { + /* the default pcm device */ + obj->name=ms_strdup("default device"); + ad->pcmdev=ms_strdup("default"); + ad->mixdev=ms_strdup("default"); + }else{ + /* remove trailing spaces from card name */ + char *pos1, *pos2; + pos1=ms_strdup(name); + pos2=pos1+strlen(pos1)-1; + for (; pos2>pos1 && *pos2==' '; pos2--) *pos2='\0'; + obj->name=pos1; + ad->pcmdev=ms_strdup_printf("default:%i",id); + ad->mixdev=ms_strdup_printf("default:%i",id); + } + free(name); + /*ms_message("alsa device %s found",obj->name);*/ + return obj; +} + +struct _AlsaReadData{ + char *pcmdev; + snd_pcm_t *handle; + int rate; + int nchannels; + +#ifdef THREADED_VERSION + ms_thread_t thread; + ms_mutex_t mutex; + MSBufferizer * bufferizer; + bool_t read_started; + bool_t write_started; +#endif +}; + +typedef struct _AlsaReadData AlsaReadData; + +void alsa_read_init(MSFilter *obj){ + AlsaReadData *ad=ms_new(AlsaReadData,1); + ad->pcmdev=NULL; + ad->handle=NULL; + ad->rate=8000; + ad->nchannels=1; + obj->data=ad; + +#ifdef THREADED_VERSION + ad->read_started=FALSE; + ad->write_started=FALSE; + ad->bufferizer=ms_bufferizer_new(); + ms_mutex_init(&ad->mutex,NULL); + ad->thread=0; +#endif +} + +#ifdef THREADED_VERSION + +static void * alsa_write_thread(void *p){ + AlsaReadData *ad=(AlsaReadData*)p; + int samples=(160*ad->rate)/8000; + int err; + int count=0; + mblk_t *om=NULL; + struct timeval timeout; + if (ad->handle==NULL && ad->pcmdev!=NULL){ + ad->handle=alsa_open_r(ad->pcmdev,16,ad->nchannels==2,ad->rate); + } + if (ad->handle==NULL) return NULL; + + while (ad->read_started) + { + count = alsa_can_read(ad->handle,samples); + if (count==24) + { /* keep this value for this driver */ } + else if (count<=0) + { + count = samples; + } + else if (count>0) + { + //ms_warning("%i count", count); + //count = samples; + } + + int size=count*2; + om=allocb(size,0); + + if ((err=alsa_read(ad->handle,om->b_wptr,count))<=0) + { + ms_warning("nothing to read"); + //ms_warning("Fail to read samples %i", count); + continue; + } + //ms_warning(" read %i", err); + + size=err*2; + om->b_wptr+=size; + + ms_mutex_lock(&ad->mutex); + ms_bufferizer_put(ad->bufferizer,om); + ms_mutex_unlock(&ad->mutex); + + if (count==24) + { + timeout.tv_sec = 0; + timeout.tv_usec = 2000; + select(0, 0, NULL, NULL, &timeout ); + } + else + { + /* select will be less active than locking on "read" */ + timeout.tv_sec = 0; + timeout.tv_usec = 5000; + select(0, 0, NULL, NULL, &timeout ); + } + } + + if (ad->handle!=NULL) snd_pcm_close(ad->handle); + ad->handle=NULL; + return NULL; +} + +static void alsa_start_r(AlsaReadData *d){ + if (d->read_started==FALSE){ + d->read_started=TRUE; + ms_thread_create(&d->thread,NULL,alsa_write_thread,d); + }else d->read_started=TRUE; +} + +static void alsa_stop_r(AlsaReadData *d){ + d->read_started=FALSE; + if (d->thread!=0) + { + ms_thread_join(d->thread,NULL); + d->thread=0; + } +} +#endif + +#ifdef THREADED_VERSION +void alsa_read_preprocess(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + alsa_start_r(ad); +} +#endif + +void alsa_read_postprocess(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; +#ifdef THREADED_VERSION + alsa_stop_r(ad); +#endif + if (ad->handle!=NULL) snd_pcm_close(ad->handle); + ad->handle=NULL; +} + +void alsa_read_uninit(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; +#ifdef THREADED_VERSION + alsa_stop_r(ad); +#endif + if (ad->pcmdev!=NULL) ms_free(ad->pcmdev); + if (ad->handle!=NULL) snd_pcm_close(ad->handle); +#ifdef THREADED_VERSION + ms_bufferizer_destroy(ad->bufferizer); + ms_mutex_destroy(&ad->mutex); +#endif + ms_free(ad); +} + +#ifndef THREADED_VERSION +void alsa_read_process(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + int samples=(128*ad->rate)/8000; + int err; + mblk_t *om=NULL; + if (ad->handle==NULL && ad->pcmdev!=NULL){ + ad->handle=alsa_open_r(ad->pcmdev,16,ad->nchannels==2,ad->rate); + } + if (ad->handle==NULL) return; + while (alsa_can_read(ad->handle,samples)>=samples){ + + int size=samples*2; + om=allocb(size,0); + if ((err=alsa_read(ad->handle,om->b_wptr,samples))<=0) { + ms_warning("Fail to read samples"); + freemsg(om); + return; + } + size=err*2; + om->b_wptr+=size; + /*ms_message("alsa_read_process: Outputing %i bytes",size);*/ + ms_queue_put(obj->outputs[0],om); + } +} +#endif + +#ifdef THREADED_VERSION +void alsa_read_process(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + mblk_t *om=NULL; + int samples=(160*ad->rate)/8000; + + ms_mutex_lock(&ad->mutex); + while (ms_bufferizer_get_avail(ad->bufferizer)>=samples*2){ + + om=allocb(samples*2,0); + ms_bufferizer_read(ad->bufferizer,om->b_wptr,samples*2); + om->b_wptr+=samples*2; + /*ms_message("alsa_read_process: Outputing %i bytes",size);*/ + ms_queue_put(obj->outputs[0],om); + } + ms_mutex_unlock(&ad->mutex); +} +#endif + +static int alsa_read_set_sample_rate(MSFilter *obj, void *param){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + ad->rate=*((int*)param); + return 0; +} + +static int alsa_read_set_nchannels(MSFilter *obj, void *param){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + ad->nchannels=*((int*)param); + return 0; +} + +MSFilterMethod alsa_read_methods[]={ + {MS_FILTER_SET_SAMPLE_RATE, alsa_read_set_sample_rate}, + {MS_FILTER_SET_SAMPLE_RATE, alsa_read_set_nchannels}, + {0,NULL} +}; + +MSFilterDesc alsa_read_desc={ + .id=MS_ALSA_READ_ID, + .name="MSAlsaRead", + .text="Alsa sound source", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .init=alsa_read_init, +#ifdef THREADED_VERSION + .preprocess=alsa_read_preprocess, +#endif + .process=alsa_read_process, + .postprocess=alsa_read_postprocess, + .uninit=alsa_read_uninit, + .methods=alsa_read_methods +}; + +static MSFilter * ms_alsa_read_new(const char *dev){ + MSFilter *f=ms_filter_new_from_desc(&alsa_read_desc); + AlsaReadData *ad=(AlsaReadData*)f->data; + ad->pcmdev=ms_strdup(dev); + return f; +} + +typedef struct _AlsaReadData AlsaWriteData; + +void alsa_write_init(MSFilter *obj){ + AlsaWriteData *ad=ms_new(AlsaWriteData,1); + ad->pcmdev=NULL; + ad->handle=NULL; + ad->rate=8000; + ad->nchannels=1; + obj->data=ad; +} + +void alsa_write_postprocess(MSFilter *obj){ + AlsaReadData *ad=(AlsaReadData*)obj->data; + if (ad->handle!=NULL) snd_pcm_close(ad->handle); + ad->handle=NULL; +} + +void alsa_write_uninit(MSFilter *obj){ + AlsaWriteData *ad=(AlsaWriteData*)obj->data; + if (ad->pcmdev!=NULL) ms_free(ad->pcmdev); + if (ad->handle!=NULL) snd_pcm_close(ad->handle); + ms_free(ad); +} + +int alsa_write_set_sample_rate(MSFilter *obj, void *data){ + int *rate=(int*)data; + AlsaWriteData *ad=(AlsaWriteData*)obj->data; + ad->rate=*rate; + return 0; +} + +int alsa_write_set_nchannels(MSFilter *obj, void *data){ + int *n=(int*)data; + AlsaWriteData *ad=(AlsaWriteData*)obj->data; + ad->nchannels=*n; + return 0; +} + +void alsa_write_process(MSFilter *obj){ + AlsaWriteData *ad=(AlsaWriteData*)obj->data; + mblk_t *im=NULL; + int size; + int samples; + int err; + if (ad->handle==NULL && ad->pcmdev!=NULL){ + ad->handle=alsa_open_w(ad->pcmdev,16,ad->nchannels==2,ad->rate); +#ifdef EPIPE_BUGFIX + alsa_fill_w (ad->pcmdev); +#endif + } + if (ad->handle==NULL) { + ms_queue_flush(obj->inputs[0]); + return; + } + while ((im=ms_queue_get(obj->inputs[0]))!=NULL){ + while((size=im->b_wptr-im->b_rptr)>0){ + samples=size/(2*ad->nchannels); + err=alsa_write(ad->handle,im->b_rptr,samples); + if (err>0) { + im->b_rptr+=err*(2*ad->nchannels); + } + else break; + } + freemsg(im); + } +} + +MSFilterMethod alsa_write_methods[]={ + {MS_FILTER_SET_SAMPLE_RATE, alsa_write_set_sample_rate}, + {MS_FILTER_SET_NCHANNELS, alsa_write_set_nchannels}, + {0,NULL} +}; + +MSFilterDesc alsa_write_desc={ + .id=MS_ALSA_WRITE_ID, + .name="MSAlsaWrite", + .text="Alsa sound output", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .init=alsa_write_init, + .process=alsa_write_process, + .postprocess=alsa_write_postprocess, + .uninit=alsa_write_uninit, + .methods=alsa_write_methods +}; + + +static MSFilter * ms_alsa_write_new(const char *dev){ + MSFilter *f=ms_filter_new_from_desc(&alsa_write_desc); + AlsaWriteData *ad=(AlsaWriteData*)f->data; + ad->pcmdev=ms_strdup(dev); + return f; +} + + +MS_FILTER_DESC_EXPORT(alsa_write_desc) + +MS_FILTER_DESC_EXPORT(alsa_read_desc) + diff --git a/linphone/mediastreamer2/src/arts.c b/linphone/mediastreamer2/src/arts.c new file mode 100644 index 000000000..e20ca884a --- /dev/null +++ b/linphone/mediastreamer2/src/arts.c @@ -0,0 +1,205 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" + +extern MSSndCardDesc arts_card_desc; + +static int arts_users=0; +static void check_arts_init(){ + if (arts_users==0){ + arts_init(); + } + arts_users++; +} + +static void check_arts_uninit(){ + arts_users--; + if (arts_users==0){ + arts_free(); + } +} + + +typedef struct ArtsState{ + int rate; + int nchannels; + int bits; + int bsize; + arts_stream_t stream; + mblk_t *msg; +} ArtsState; + +static void reader_init(MSFilter *f){ + ArtsState *s=ms_new(ArtsState,1); + s->rate=8000; + s->nchannels=1; + s->bits=16; + s->bsize=512; + s->stream=NULL; + s->msg=NULL; + f->data=s; +} + +static void reader_uninit(MSFilter *f){ + ArtsState *s=(ArtsState *)f->data; + ms_free(s); +} + +static void configure(arts_stream_t stream){ + int ret; + int latency=50; + ret=arts_stream_set(stream,ARTS_P_BUFFER_TIME,latency); + if (ret!=latency) ms_message("Arts set latency to %i",ret); + arts_stream_set(stream,ARTS_P_BLOCKING,0); +} + +static void reader_preprocess(MSFilter *f){ + ArtsState *s=(ArtsState *)f->data; + check_arts_init(); + s->stream=arts_record_stream(s->rate,s->bits,s->nchannels, "linphone"); + s->bsize=512*s->rate/8000; + if (s->stream!=NULL) configure(s->stream); +} + +static void reader_process(MSFilter *f){ + int err; + ArtsState *s=(ArtsState *)f->data; + if (s->stream!=NULL){ + mblk_t *om=s->msg; + if (om==NULL) om=allocb(s->bsize,0); + err=arts_read(s->stream,om->b_wptr,s->bsize); + if (err>0){ + om->b_wptr+=err; + ms_queue_put(f->outputs[0],om); + om=NULL; + } + s->msg=om; + } +} + +static void reader_postprocess(MSFilter *f){ + ArtsState *s=(ArtsState *)f->data; + if (s->stream) arts_close_stream(s->stream); + s->stream=NULL; + check_arts_uninit(); +} + +static void writer_preprocess(MSFilter *f){ + ArtsState *s=(ArtsState *)f->data; + check_arts_init(); + s->stream=arts_play_stream(s->rate,s->bits,s->nchannels, "linphone"); + s->bsize=512*s->rate/8000; + if (s->stream!=NULL) configure(s->stream); +} + +static void writer_process(MSFilter *f){ + ArtsState *s=(ArtsState *)f->data; + int err; + mblk_t *im; + + if (s->stream==NULL){ + ms_queue_flush(f->inputs[0]); + return; + } + while ((im=ms_queue_get(f->inputs[0]))!=NULL){ + err=arts_write(s->stream,im->b_rptr,im->b_wptr-im->b_rptr); + if (err<0){ + ms_warning("arts_write error"); + } + freemsg(im); + } +} + +static int reader_set_sr(MSFilter *f, void *arg){ + ArtsState *s=(ArtsState *)f->data; + s->rate=*(int*)arg; + return 0; +} + +static int reader_set_nchannels(MSFilter *f, void *arg){ + ArtsState *s=(ArtsState *)f->data; + s->nchannels=*(int*)arg; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , reader_set_sr }, + { MS_FILTER_SET_NCHANNELS , reader_set_nchannels }, + { 0 , NULL } +}; + +MSFilterDesc ms_arts_read_desc={ + .id=MS_ARTS_READ_ID, + .name="MSArtsRead", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .init=reader_init, + .preprocess=reader_preprocess, + .process=reader_process, + .postprocess=reader_postprocess, + .uninit=reader_uninit, + .methods=methods +}; + +MSFilterDesc ms_arts_write_desc={ + .id=MS_ARTS_WRITE_ID, + .name="MSArtsWrite", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .init=reader_init, /*the read and the write method do the same*/ + .preprocess=writer_preprocess, + .process=writer_process, + .postprocess=reader_postprocess,/*the read and the write method do the same*/ + .uninit=reader_uninit,/*the read and the write method do the same*/ + .methods=methods /*the read and the write method do the same*/ +}; + +static void arts_card_detect(MSSndCardManager *m){ + if (arts_init()==0){ + MSSndCard *card=ms_snd_card_new(&arts_card_desc); + card->name=ms_strdup("arts driver"); + ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card); + arts_free(); + } +} + +static MSFilter * arts_card_create_reader(MSSndCard *card){ + return ms_filter_new(MS_ARTS_READ_ID); +} + +static MSFilter * arts_card_create_writer(MSSndCard *card){ + return ms_filter_new(MS_ARTS_WRITE_ID); +} + +MSSndCardDesc arts_card_desc={ + .driver_type="aRts", + .detect=arts_card_detect, + .create_reader=arts_card_create_reader, + .create_writer=arts_card_create_writer, + .duplicate=NULL +}; + +MS_FILTER_DESC_EXPORT(ms_arts_read_desc) +MS_FILTER_DESC_EXPORT(ms_arts_write_desc) diff --git a/linphone/mediastreamer2/src/audiostream.c b/linphone/mediastreamer2/src/audiostream.c new file mode 100644 index 000000000..d024657a0 --- /dev/null +++ b/linphone/mediastreamer2/src/audiostream.c @@ -0,0 +1,426 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mediastream.h" + +#include "mediastreamer2/dtmfgen.h" +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msrtp.h" +#include "mediastreamer2/msfileplayer.h" +#include "mediastreamer2/msfilerec.h" + +#ifdef INET6 + #include +#ifndef WIN32 + #include + #include +#endif +#endif + + +#define MAX_RTP_SIZE 1500 + + +/* this code is not part of the library itself, it is part of the mediastream program */ +void audio_stream_free(AudioStream *stream) +{ + if (stream->session!=NULL) rtp_session_destroy(stream->session); + if (stream->rtpsend!=NULL) ms_filter_destroy(stream->rtpsend); + if (stream->rtprecv!=NULL) ms_filter_destroy(stream->rtprecv); + if (stream->soundread!=NULL) ms_filter_destroy(stream->soundread); + if (stream->soundwrite!=NULL) ms_filter_destroy(stream->soundwrite); + if (stream->encoder!=NULL) ms_filter_destroy(stream->encoder); + if (stream->decoder!=NULL) ms_filter_destroy(stream->decoder); + if (stream->dtmfgen!=NULL) ms_filter_destroy(stream->dtmfgen); + if (stream->ec!=NULL) ms_filter_destroy(stream->ec); + if (stream->ticker!=NULL) ms_ticker_destroy(stream->ticker); + ms_free(stream); +} + +static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; + +static void on_dtmf_received(RtpSession *s, int dtmf, void * user_data) +{ + MSFilter *dtmfgen=(MSFilter*)user_data; + if (dtmf>15){ + ms_warning("Unsupported telephone-event type."); + return; + } + ms_message("Receiving dtmf %c.",dtmf_tab[dtmf]); + if (dtmfgen!=NULL){ + ms_filter_call_method(dtmfgen,MS_DTMF_GEN_PUT,&dtmf_tab[dtmf]); + } +} + +#if 0 + +static void on_timestamp_jump(RtpSession *s,uint32_t* ts, void * user_data) +{ + ms_warning("The remote sip-phone has send data with a future timestamp: %u," + "resynchronising session.",*ts); + rtp_session_reset(s); +} + +#endif + + +bool_t ms_is_ipv6(const char *remote){ + bool_t ret=FALSE; +#ifdef INET6 + struct addrinfo hints, *res0; + + int err; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + err = getaddrinfo(remote,"8000", &hints, &res0); + if (err!=0) { + ms_warning ("get_local_addr_for: %s", gai_strerror(err)); + return FALSE; + } + ret=(res0->ai_addr->sa_family==AF_INET6); + freeaddrinfo(res0); +#endif + return ret; +} + +RtpSession * create_duplex_rtpsession( int locport, bool_t ipv6){ + RtpSession *rtpr; + rtpr=rtp_session_new(RTP_SESSION_SENDRECV); + rtp_session_set_recv_buf_size(rtpr,MAX_RTP_SIZE); + rtp_session_set_scheduling_mode(rtpr,0); + rtp_session_set_blocking_mode(rtpr,0); + rtp_session_enable_adaptive_jitter_compensation(rtpr,TRUE); + rtp_session_set_symmetric_rtp(rtpr,TRUE); + rtp_session_set_local_addr(rtpr,ipv6 ? "::" : "0.0.0.0",locport); + rtp_session_signal_connect(rtpr,"timestamp_jump",(RtpCallback)rtp_session_resync,(long)NULL); + rtp_session_signal_connect(rtpr,"ssrc_changed",(RtpCallback)rtp_session_resync,(long)NULL); + return rtpr; +} + +bool_t audio_stream_alive(AudioStream * stream, int timeout){ + RtpSession *session=stream->session; + const rtp_stats_t *stats=rtp_session_get_stats(session); + if (stats->recv!=0){ + if (stats->recv!=stream->last_packet_count){ + stream->last_packet_count=stats->recv; + stream->last_packet_time=time(NULL); + }else{ + if (time(NULL)-stream->last_packet_time>timeout){ + /* more than timeout seconds of inactivity*/ + return FALSE; + } + } + } + return TRUE; +} + +/*this function must be called from the MSTicker thread: +it replaces one filter by another one. +This is a dirty hack that works anyway. +It would be interesting to have something that does the job +simplier within the MSTicker api +*/ +void audio_stream_change_decoder(AudioStream *stream, int payload){ + RtpSession *session=stream->session; + RtpProfile *prof=rtp_session_get_profile(session); + PayloadType *pt=rtp_profile_get_payload(prof,payload); + if (pt!=NULL){ + MSFilter *dec=ms_filter_create_decoder(pt->mime_type); + if (dec!=NULL){ + ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); + ms_filter_unlink(stream->decoder,0,stream->dtmfgen,0); + ms_filter_postprocess(stream->decoder); + ms_filter_destroy(stream->decoder); + stream->decoder=dec; + if (pt->recv_fmtp!=NULL) + ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); + ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); + ms_filter_link (stream->decoder,0 , stream->dtmfgen, 0); + ms_filter_preprocess(stream->decoder,stream->ticker); + + }else{ + ms_warning("No decoder found for %s",pt->mime_type); + } + }else{ + ms_warning("No payload defined with number %i",payload); + } +} + +static void payload_type_changed(RtpSession *session, unsigned long data){ + AudioStream *stream=(AudioStream*)data; + int pt=rtp_session_get_recv_payload_type(stream->session); + audio_stream_change_decoder(stream,pt); +} + + +int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *remip,int remport, + int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile, + MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) +{ + RtpSession *rtps=stream->session; + PayloadType *pt; + int tmp; + + rtp_session_set_profile(rtps,profile); + if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + if (remport>0) + ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,rtps); + stream->rtprecv=ms_filter_new(MS_RTP_RECV_ID); + ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps); + stream->session=rtps; + + stream->dtmfgen=ms_filter_new(MS_DTMF_GEN_ID); + rtp_session_signal_connect(rtps,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream->dtmfgen); + rtp_session_signal_connect(rtps,"payload_type_changed",(RtpCallback)payload_type_changed,(unsigned long)stream); + + /* creates the local part */ + if (captcard!=NULL) stream->soundread=ms_snd_card_create_reader(captcard); + else { + stream->soundread=ms_filter_new(MS_FILE_PLAYER_ID); + if (infile!=NULL) audio_stream_play(stream,infile); + } + if (playcard!=NULL) stream->soundwrite=ms_snd_card_create_writer(playcard); + else { + stream->soundwrite=ms_filter_new(MS_FILE_REC_ID); + if (outfile!=NULL) audio_stream_record(stream,outfile); + } + + /* creates the couple of encoder/decoder */ + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + ms_error("audiostream.c: undefined payload type."); + return -1; + } + stream->encoder=ms_filter_create_encoder(pt->mime_type); + stream->decoder=ms_filter_create_decoder(pt->mime_type); + if ((stream->encoder==NULL) || (stream->decoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + ms_error("mediastream.c: No decoder available for payload %i.",payload); + return -1; + } + + if (use_ec) { + stream->ec=ms_filter_new(MS_SPEEX_EC_ID); + ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); + } + + /* give the sound filters some properties */ + ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); + ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); + tmp=1; + ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_NCHANNELS, &tmp); + + /* give the encoder/decoder some parameters*/ + ms_filter_call_method(stream->encoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); + if (pt->normal_bitrate>0){ + ms_message("Setting audio encoder network bitrate to %i",pt->normal_bitrate); + ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate); + } + ms_filter_call_method(stream->decoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate); + + if (pt->send_fmtp!=NULL) ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp); + if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); + + /* and then connect all */ + /* tip: draw yourself the picture if you don't understand */ + if (stream->ec){ + ms_filter_link(stream->soundread,0,stream->ec,1); + ms_filter_link(stream->ec,1,stream->encoder,0); + ms_filter_link(stream->dtmfgen,0,stream->ec,0); + ms_filter_link(stream->ec,0,stream->soundwrite,0); + }else{ + ms_filter_link(stream->soundread,0,stream->encoder,0); + ms_filter_link(stream->dtmfgen,0,stream->soundwrite,0); + } + + ms_filter_link(stream->encoder,0,stream->rtpsend,0); + ms_filter_link(stream->rtprecv,0,stream->decoder,0); + ms_filter_link(stream->decoder,0,stream->dtmfgen,0); + + /* create ticker */ + stream->ticker=ms_ticker_new(); + + ms_ticker_attach(stream->ticker,stream->soundread); + ms_ticker_attach(stream->ticker,stream->rtprecv); + + return 0; +} + + +int audio_stream_start_with_files(AudioStream *stream, RtpProfile *prof,const char *remip, int remport, + int rem_rtcp_port, int pt,int jitt_comp, const char *infile, const char * outfile) +{ + return audio_stream_start_full(stream,prof,remip,remport,rem_rtcp_port,pt,jitt_comp,infile,outfile,NULL,NULL,FALSE); +} + +AudioStream * audio_stream_start(RtpProfile *prof,int locport,const char *remip,int remport,int profile,int jitt_comp,bool_t use_ec) +{ + MSSndCard *sndcard; + AudioStream *stream; + sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()); + if (sndcard==NULL) + return NULL; + stream=audio_stream_new(locport, ms_is_ipv6(remip)); + if (audio_stream_start_full(stream,prof,remip,remport,remport+1,profile,jitt_comp,NULL,NULL,sndcard,sndcard,use_ec)==0) return stream; + audio_stream_free(stream); + return NULL; +} + +AudioStream *audio_stream_start_with_sndcards(RtpProfile *prof,int locport,const char *remip,int remport,int profile,int jitt_comp,MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) +{ + AudioStream *stream; + if (playcard==NULL) { + ms_error("No playback card."); + return NULL; + } + if (captcard==NULL) { + ms_error("No capture card."); + return NULL; + } + stream=audio_stream_new(locport, ms_is_ipv6(remip)); + if (audio_stream_start_full(stream,prof,remip,remport,remport+1,profile,jitt_comp,NULL,NULL,playcard,captcard,use_ec)==0) return stream; + audio_stream_free(stream); + return NULL; +} + +void audio_stream_set_rtcp_information(AudioStream *st, const char *cname, const char *tool){ + if (st->session!=NULL){ + rtp_session_set_source_description(st->session,cname,NULL,NULL,NULL,NULL,tool , "This is free software (GPL) !"); + } +} + +void audio_stream_play(AudioStream *st, const char *name){ + if (ms_filter_get_id(st->soundread)==MS_FILE_PLAYER_ID){ + ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_CLOSE); + ms_filter_call_method(st->soundread,MS_FILE_PLAYER_OPEN,(void*)name); + ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_START); + }else{ + ms_error("Cannot play file: the stream hasn't been started with" + " audio_stream_start_with_files"); + } +} + +void audio_stream_record(AudioStream *st, const char *name){ + if (ms_filter_get_id(st->soundwrite)==MS_FILE_REC_ID){ + ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_CLOSE); + ms_filter_call_method(st->soundwrite,MS_FILE_REC_OPEN,(void*)name); + ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_START); + }else{ + ms_error("Cannot record file: the stream hasn't been started with" + " audio_stream_start_with_files"); + } +} + + +AudioStream *audio_stream_new(int locport, bool_t ipv6){ + AudioStream *stream=(AudioStream *)ms_new0(AudioStream,1); + stream->session=create_duplex_rtpsession(locport,ipv6); + stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID); + return stream; +} + +int audio_stream_start_now(AudioStream *stream, RtpProfile * prof, const char *remip, int remport, int rem_rtcp_port, int payload_type, int jitt_comp, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec){ + return audio_stream_start_full(stream,prof,remip,remport,rem_rtcp_port, + payload_type,jitt_comp,NULL,NULL,playcard,captcard,use_ec); +} + +void audio_stream_set_relay_session_id(AudioStream *stream, const char *id){ + ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id); +} + +void audio_stream_stop(AudioStream * stream) +{ + if (stream->ticker){ + ms_ticker_detach(stream->ticker,stream->soundread); + ms_ticker_detach(stream->ticker,stream->rtprecv); + + rtp_stats_display(rtp_session_get_stats(stream->session),"Audio session's RTP statistics"); + + if (stream->ec!=NULL){ + ms_filter_unlink(stream->soundread,0,stream->ec,1); + ms_filter_unlink(stream->ec,1,stream->encoder,0); + ms_filter_unlink(stream->dtmfgen,0,stream->ec,0); + ms_filter_unlink(stream->ec,0,stream->soundwrite,0); + }else{ + ms_filter_unlink(stream->soundread,0,stream->encoder,0); + ms_filter_unlink(stream->dtmfgen,0,stream->soundwrite,0); + } + + ms_filter_unlink(stream->encoder,0,stream->rtpsend,0); + ms_filter_unlink(stream->rtprecv,0,stream->decoder,0); + ms_filter_unlink(stream->decoder,0,stream->dtmfgen,0); + } + audio_stream_free(stream); +} + +RingStream * ring_start(const char *file, int interval, MSSndCard *sndcard){ + return ring_start_with_cb(file,interval,sndcard,NULL,NULL); +} + +RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard, MSFilterNotifyFunc func,void * user_data) +{ + RingStream *stream; + int tmp; + stream=(RingStream *)ms_new0(RingStream,1); + stream->source=ms_filter_new(MS_FILE_PLAYER_ID); + if (ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file)<0){ + ms_filter_destroy(stream->source); + ms_free(stream); + return NULL; + } + ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval); + ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START); + if (func!=NULL) + ms_filter_set_notify_callback(stream->source,func,user_data); + stream->sndwrite=ms_snd_card_create_writer(sndcard); + ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&tmp); + ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&tmp); + ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&tmp); + ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&tmp); + stream->ticker=ms_ticker_new(); + ms_filter_link(stream->source,0,stream->sndwrite,0); + ms_ticker_attach(stream->ticker,stream->source); + return stream; +} + +void ring_stop(RingStream *stream){ + ms_ticker_detach(stream->ticker,stream->source); + ms_filter_unlink(stream->source,0,stream->sndwrite,0); + ms_ticker_destroy(stream->ticker); + ms_filter_destroy(stream->source); + ms_filter_destroy(stream->sndwrite); + ms_free(stream); +} + + +int audio_stream_send_dtmf(AudioStream *stream, char dtmf) +{ + ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SEND_DTMF,&dtmf); + ms_filter_call_method(stream->dtmfgen,MS_DTMF_GEN_PUT,&dtmf); + return 0; +} diff --git a/linphone/mediastreamer2/src/dtmfgen.c b/linphone/mediastreamer2/src/dtmfgen.c new file mode 100644 index 000000000..0390986fd --- /dev/null +++ b/linphone/mediastreamer2/src/dtmfgen.c @@ -0,0 +1,204 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/dtmfgen.h" + + +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +struct DtmfGenState{ + int rate; + int dur; + int pos; + float highfreq; + float lowfreq; + char dtmf; +}; + +typedef struct DtmfGenState DtmfGenState; + +static void dtmfgen_init(MSFilter *f){ + DtmfGenState *s=(DtmfGenState *)ms_new(DtmfGenState,1); + s->rate=8000; + s->dur=s->rate/10; + s->pos=0; + s->dtmf=0; + f->data=s; +} + +static void dtmfgen_uninit(MSFilter *f){ + ms_free(f->data); +} + +static int dtmfgen_put(MSFilter *f, void *arg){ + DtmfGenState *s=(DtmfGenState*)f->data; + const char *dtmf=(char*)arg; + s->pos=0; + switch(dtmf[0]){ + case '0': + s->lowfreq=941; + s->highfreq=1336; + break; + case '1': + s->lowfreq=697; + s->highfreq=1209; + break; + case '2': + s->lowfreq=697; + s->highfreq=1336; + break; + case '3': + s->lowfreq=697; + s->highfreq=1477; + break; + case '4': + s->lowfreq=770; + s->highfreq=1209; + break; + case '5': + s->lowfreq=770; + s->highfreq=1336; + break; + case '6': + s->lowfreq=770; + s->highfreq=1477; + break; + case '7': + s->lowfreq=852; + s->highfreq=1209; + break; + case '8': + s->lowfreq=852; + s->highfreq=1336; + break; + case '9': + s->lowfreq=852; + s->highfreq=1477; + break; + case '*': + s->lowfreq=941; + s->highfreq=1209; + break; + case '#': + s->lowfreq=941; + s->highfreq=1477; + break; + case 'A': + s->lowfreq=697; + s->highfreq=1633; + break; + case 'B': + s->lowfreq=770; + s->highfreq=1633; + break; + case 'C': + s->lowfreq=852; + s->highfreq=1633; + break; + case 'D': + s->lowfreq=941; + s->highfreq=1633; + break; + default: + ms_warning("Not a dtmf key."); + return -1; + } + s->lowfreq=s->lowfreq/s->rate; + s->highfreq=s->highfreq/s->rate; + + s->dtmf=dtmf[0]; + return 0; +} + +static int dtmfgen_set_rate(MSFilter *f, void *arg){ + DtmfGenState *s=(DtmfGenState*)f->data; + s->rate=*((int*)arg); + s->dur=s->rate/10; + return 0; +} + +static void dtmfgen_process(MSFilter *f){ + mblk_t *m; + DtmfGenState *s=(DtmfGenState*)f->data; + + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + if (s->dtmf!=0){ + int nsamples=(m->b_wptr-m->b_rptr)/2; + int i; + int16_t *sample=(int16_t*)m->b_rptr; + for (i=0;iposdur;i++,s->pos++){ + sample[i]=(int16_t)(10000.0*sin(2*M_PI*(float)s->pos*s->lowfreq)); + sample[i]+=(int16_t)(10000.0*sin(2*M_PI*(float)s->pos*s->highfreq)); + } + if (s->pos==s->dur){ + s->pos=0; + s->dtmf=0; + } + } + ms_queue_put(f->outputs[0],m); + } +} + +MSFilterMethod dtmfgen_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , dtmfgen_set_rate }, + { MS_DTMF_GEN_PUT , dtmfgen_put }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_dtmf_gen_desc={ + MS_DTMF_GEN_ID, + "MSDtmfGen", + "DTMF generator", + MS_FILTER_OTHER, + NULL, + 1, + 1, + dtmfgen_init, + NULL, + dtmfgen_process, + NULL, + dtmfgen_uninit, + dtmfgen_methods +}; + +#else + +MSFilterDesc ms_dtmf_gen_desc={ + .id=MS_DTMF_GEN_ID, + .name="MSDtmfGen", + .text="DTMF generator", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=1, + .init=dtmfgen_init, + .process=dtmfgen_process, + .uninit=dtmfgen_uninit, + .methods=dtmfgen_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_dtmf_gen_desc) + diff --git a/linphone/mediastreamer2/src/dxfilter.cpp b/linphone/mediastreamer2/src/dxfilter.cpp new file mode 100644 index 000000000..db3627fc6 --- /dev/null +++ b/linphone/mediastreamer2/src/dxfilter.cpp @@ -0,0 +1,880 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#if !defined(_WIN32_WCE) //Allready defined for wince +#define UNICODE +#endif + +#include +#include + +#if !defined(_WIN32_WCE) +#include "qedit.h" +#endif +#include "dxfilter.h" + +#pragma warning(disable: 4800) + + +const AMOVIESETUP_PIN psudDXFilterPins[] = +{ { L"Input" // strName + , FALSE // bRendered + , FALSE // bOutput + , FALSE // bZero + , FALSE // bMany + , &CLSID_NULL // clsConnectsToFilter + , L"" // strConnectsToPin + , 0 // nTypes + , NULL // lpTypes + } +, { L"Output" // strName + , FALSE // bRendered + , TRUE // bOutput + , FALSE // bZero + , FALSE // bMany + , &CLSID_NULL // clsConnectsToFilter + , L"" // strConnectsToPin + , 0 // nTypes + , NULL // lpTypes + } +}; + +const AMOVIESETUP_FILTER sudDXFilter = +{ &CLSID_DXFilter // clsID +, L"DXFilter for mediastreamer2" // strName +, MERIT_DO_NOT_USE // dwMerit +, 2 // nPins +, psudDXFilterPins }; // lpPin + + +// Needed for the CreateInstance mechanism +CFactoryTemplate g_Templates[]= +{ + { L"DirectX Filter for mediastreamer2" + , &CLSID_DXFilter + , CDXFilter::CreateInstance + , NULL + , &sudDXFilter } + +}; + +int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]); + + +//////////////////////////////////////////////////////////////////////// +// +// Exported entry points for registration and unregistration +// (in this case they only call through to default implementations). +// +//////////////////////////////////////////////////////////////////////// + +STDAPI DllRegisterServer() +{ + return AMovieDllRegisterServer2(TRUE); +} + +STDAPI DllUnregisterServer() +{ + return AMovieDllRegisterServer2(FALSE); +} + +// +// DllEntryPoint +// +extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD dwReason, + LPVOID lpReserved) +{ + return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved); +} + +// +// CreateInstance +// +// Provide the way for COM to create a CDXFilter object +// +CUnknown * WINAPI CDXFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr) +{ + /* ASSERT(phr); */ + + // assuming we don't want to modify the data + CDXFilter *pNewObject = new CDXFilter(punk, phr, FALSE); + + if(pNewObject == NULL) { + if (phr) + *phr = E_OUTOFMEMORY; + } + + return pNewObject; + +} // CreateInstance + + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +CDXFilter::CDXFilter( IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData ) + : CTransInPlaceFilter( TEXT("DXFilter"), (IUnknown*) pOuter, + CLSID_DXFilter, phr +#if !defined(_WIN32_WCE) + ,(BOOL)ModifiesData +#endif + ) + , m_callback( NULL ) +{ + // this is used to override the input pin with our own + m_pInput = (CTransInPlaceInputPin*) new CDXFilterInPin( this, phr ); + if( !m_pInput ) + { + if (phr) + *phr = E_OUTOFMEMORY; + } + + // Ensure that the output pin gets created. This is necessary because our + // SetDeliveryBuffer() method assumes that the input/output pins are created, but + // the output pin isn't created until GetPin() is called. The + // CTransInPlaceFilter::GetPin() method will create the output pin, since we + // have not already created one. + IPin *pOutput = GetPin(1); + // The pointer is not AddRef'ed by GetPin(), so don't release it +} + +STDMETHODIMP CDXFilter::NonDelegatingQueryInterface( REFIID riid, void ** ppv) +{ + CheckPointer(ppv,E_POINTER); + + if(riid == IID_IDXFilter) { + return GetInterface((IDXFilter *) this, ppv); + } + else { + return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv); + } +} + + +//---------------------------------------------------------------------------- +// This is where you force the sample grabber to connect with one type +// or the other. What you do here is crucial to what type of data your +// app will be dealing with in the sample grabber's callback. For instance, +// if you don't enforce right-side-up video in this call, you may not get +// right-side-up video in your callback. It all depends on what you do here. +//---------------------------------------------------------------------------- + +HRESULT CDXFilter::CheckInputType( const CMediaType * pmt ) +{ + CheckPointer(pmt,E_POINTER); + CAutoLock lock( &m_Lock ); + + // if the major type is not set, then accept anything + + GUID g = *m_mtAccept.Type( ); + if( g == GUID_NULL ) + { + return NOERROR; + } + + // if the major type is set, don't accept anything else + + if( g != *pmt->Type( ) ) + { + return VFW_E_INVALID_MEDIA_TYPE; + } + + // subtypes must match, if set. if not set, accept anything + VIDEOINFO *pvi = (VIDEOINFO *)pmt->Format(); + + g = *m_mtAccept.Subtype( ); + if( g == GUID_NULL ) + { + return NOERROR; + } +#if 0 + if( MEDIASUBTYPE_RGB24 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_YVU9 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Y411 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Y41P == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_YUY2 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_YVYU == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_UYVY == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Y211 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_YV12 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_CLJR == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_IF09 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_CPLA == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MJPG == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_TVMJ == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_WAKE == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_CFCC == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_IJPG == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Plum == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB1 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB4 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB8 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB565 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB555 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB24 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_RGB32 == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Overlay == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1Packet == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1Payload == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1AudioPayload == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIATYPE_MPEG1SystemStream == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1System == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1VideoCD == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_MPEG1Video == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Avi == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_Asf == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_QTMovie == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_QTRpza == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_QTSmc == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_QTRle == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_QTJpeg == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_PCM == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_WAVE == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_AU == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_AIFF == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_DssVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVBI == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; + if( MEDIASUBTYPE_VPVideo == *pmt->Subtype( ) ) + return VFW_E_INVALID_MEDIA_TYPE; +#endif + + if( g != *pmt->Subtype( ) ) + { + return VFW_E_INVALID_MEDIA_TYPE; + } + + // format types must match, if one is set + + g = *m_mtAccept.FormatType( ); + if( g == GUID_NULL ) + { + return NOERROR; + } + if( g != *pmt->FormatType( ) ) + { + return VFW_E_INVALID_MEDIA_TYPE; + } + + // at this point, for this sample code, this is good enough, + // but you may want to make it more strict + + //compare sizes + //VIDEOINFO *pvi = (VIDEOINFO *)pmt->Format(); + VIDEOINFO *pvi2 = (VIDEOINFO *)m_mtAccept.Format(); + if (pvi2==NULL) + return NOERROR; + + if (pvi==NULL) + return VFW_E_INVALID_MEDIA_TYPE; +#if !defined(_WIN32_WCE) + if (pvi->bmiHeader.biCompression!=pvi2->bmiHeader.biCompression) + return VFW_E_INVALID_MEDIA_TYPE; +#endif + if (pvi->bmiHeader.biBitCount!=pvi2->bmiHeader.biBitCount) + return VFW_E_INVALID_MEDIA_TYPE; + if (pvi->bmiHeader.biWidth!=pvi2->bmiHeader.biWidth) + return VFW_E_INVALID_MEDIA_TYPE; + if (pvi->bmiHeader.biHeight!=pvi2->bmiHeader.biHeight) + return VFW_E_INVALID_MEDIA_TYPE; + if (pvi->bmiHeader.biSizeImage!=pvi2->bmiHeader.biSizeImage) + return VFW_E_INVALID_MEDIA_TYPE; + + return NOERROR; +} + + +//---------------------------------------------------------------------------- +// This bit is almost straight out of the base classes. +// We override this so we can handle Transform( )'s error +// result differently. +//---------------------------------------------------------------------------- + +HRESULT CDXFilter::Receive( IMediaSample * pms ) +{ + CheckPointer(pms,E_POINTER); + + HRESULT hr; + AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); + + if (pProps->dwStreamId != AM_STREAM_MEDIA) + { + if( m_pOutput->IsConnected() ) + return m_pOutput->Deliver(pms); + else + return NOERROR; + } + +#if !defined(_WIN32_WCE) + if (UsingDifferentAllocators()) + { + // We have to copy the data. + + pms = Copy(pms); + + if (pms == NULL) + { + return E_UNEXPECTED; + } + } +#endif + + // have the derived class transform the data + hr = Transform(pms); + + if (FAILED(hr)) + { + //DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace"))); +#if !defined(_WIN32_WCE) + if (UsingDifferentAllocators()) + { + pms->Release(); + } +#endif + return hr; + } + + if (hr == NOERROR) + { + hr = m_pOutput->Deliver(pms); + } + + // release the output buffer. If the connected pin still needs it, + // it will have addrefed it itself. +#if !defined(_WIN32_WCE) + if (UsingDifferentAllocators()) + { + pms->Release(); + } +#endif + return hr; +} + + +//---------------------------------------------------------------------------- +// Transform +//---------------------------------------------------------------------------- + +HRESULT CDXFilter::Transform ( IMediaSample * pms ) +{ + CheckPointer(pms,E_POINTER); + CAutoLock lock( &m_Lock ); + + if( m_callback ) + { + REFERENCE_TIME StartTime, StopTime; + pms->GetTime( &StartTime, &StopTime); + + StartTime += m_pInput->CurrentStartTime( ); + StopTime += m_pInput->CurrentStartTime( ); + + BOOL * pTypeChanged = &((CDXFilterInPin*) m_pInput)->m_bMediaTypeChanged; + + HRESULT hr = m_callback( pms, &StartTime, &StopTime, *pTypeChanged ); + + *pTypeChanged = FALSE; // now that we notified user, we can clear it + + return hr; + } + + return NOERROR; +} + + +//---------------------------------------------------------------------------- +// SetAcceptedMediaType +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilter::SetAcceptedMediaType( const CMediaType * pmt ) +{ + CAutoLock lock( &m_Lock ); + + if( !pmt ) + { + m_mtAccept = CMediaType( ); + return NOERROR; + } + + HRESULT hr; +#if !defined(_WIN32_WCE) + hr = CopyMediaType( &m_mtAccept, pmt ); +#else + hr=S_OK; + CopyMediaType( &m_mtAccept, pmt ); +#endif + return hr; +} + +//---------------------------------------------------------------------------- +// GetAcceptedMediaType +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilter::GetConnectedMediaType( CMediaType * pmt ) +{ + if( !m_pInput || !m_pInput->IsConnected( ) ) + { + return VFW_E_NOT_CONNECTED; + } + + return m_pInput->ConnectionMediaType( pmt ); +} + + +//---------------------------------------------------------------------------- +// SetCallback +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilter::SetCallback( SAMPLECALLBACK Callback ) +{ + CAutoLock lock( &m_Lock ); + + m_callback = Callback; + + return NOERROR; +} + + +//---------------------------------------------------------------------------- +// inform the input pin of the allocator buffer we wish to use. See the +// input pin's SetDeliverBuffer method for comments. +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilter::SetDeliveryBuffer( ALLOCATOR_PROPERTIES props, BYTE * m_pBuffer ) +{ + // have the input/output pins been created? + if( !InputPin( ) || !OutputPin( ) ) + { + return E_POINTER; + } + + // they can't be connected if we're going to be changing delivery buffers + // + if( InputPin( )->IsConnected( ) || OutputPin( )->IsConnected( ) ) + { + return E_INVALIDARG; + } + + return ((CDXFilterInPin*)m_pInput)->SetDeliveryBuffer( props, m_pBuffer ); +} + + +//---------------------------------------------------------------------------- +// used to help speed input pin connection times. We return a partially +// specified media type - only the main type is specified. If we return +// anything BUT a major type, some codecs written improperly will crash +//---------------------------------------------------------------------------- + +HRESULT CDXFilterInPin::GetMediaType( int iPosition, CMediaType * pMediaType ) +{ + CheckPointer(pMediaType,E_POINTER); + + if (iPosition < 0) { + return E_INVALIDARG; + } + if (iPosition > 0) { + return VFW_S_NO_MORE_ITEMS; + } + + *pMediaType = CMediaType( ); + pMediaType->SetType( ((CDXFilter*)m_pFilter)->m_mtAccept.Type( ) ); + + return S_OK; +} + + +//---------------------------------------------------------------------------- +// override the CTransInPlaceInputPin's method, and return a new enumerator +// if the input pin is disconnected. This will allow GetMediaType to be +// called. If we didn't do this, EnumMediaTypes returns a failure code +// and GetMediaType is never called. +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilterInPin::EnumMediaTypes( IEnumMediaTypes **ppEnum ) +{ + CheckPointer(ppEnum,E_POINTER); + ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *)); + + // if the output pin isn't connected yet, offer the possibly + // partially specified media type that has been set by the user + + if( !((CDXFilter*)m_pTIPFilter)->OutputPin( )->IsConnected() ) + { + // Create a new reference counted enumerator + + *ppEnum = new CEnumMediaTypes( this, NULL ); + + return (*ppEnum) ? NOERROR : E_OUTOFMEMORY; + } + + // if the output pin is connected, offer it's fully qualified media type + + return ((CDXFilter*)m_pTIPFilter)->OutputPin( )->GetConnected()->EnumMediaTypes( ppEnum ); +} + + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilterInPin::NotifyAllocator( IMemAllocator *pAllocator, BOOL bReadOnly ) +{ + if( m_pPrivateAllocator ) + { + if( pAllocator != m_pPrivateAllocator ) + { + return E_FAIL; + } + else + { +#if !defined(_WIN32_WCE) + // if the upstream guy wants to be read only and we don't, then that's bad + // if the upstream guy doesn't request read only, but we do, that's okay + if( bReadOnly && !DXFilter( )->IsReadOnly( ) ) + { + return E_FAIL; + } +#endif + } + } + + return CTransInPlaceInputPin::NotifyAllocator( pAllocator, bReadOnly ); +} + + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +STDMETHODIMP CDXFilterInPin::GetAllocator( IMemAllocator **ppAllocator ) +{ + if( m_pPrivateAllocator ) + { + CheckPointer(ppAllocator,E_POINTER); + + *ppAllocator = m_pPrivateAllocator; + m_pPrivateAllocator->AddRef( ); + return NOERROR; + } + else + { + return CTransInPlaceInputPin::GetAllocator( ppAllocator ); + } +} + +//---------------------------------------------------------------------------- +// GetAllocatorRequirements: The upstream filter calls this to get our +// filter's allocator requirements. If the app has set the buffer, then +// we return those props. Otherwise, we use the default TransInPlace behavior. +//---------------------------------------------------------------------------- + +HRESULT CDXFilterInPin::GetAllocatorRequirements( ALLOCATOR_PROPERTIES *pProps ) +{ + CheckPointer(pProps,E_POINTER); + + if (m_pPrivateAllocator) + { + *pProps = m_allocprops; + return S_OK; + } + else + { + return CTransInPlaceInputPin::GetAllocatorRequirements(pProps); + } +} + + + + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +HRESULT CDXFilterInPin::SetDeliveryBuffer( ALLOCATOR_PROPERTIES props, BYTE * pBuffer ) +{ + // don't allow more than one buffer + + if( props.cBuffers != 1 ) + { + return E_INVALIDARG; + } + if( !pBuffer ) + { + return E_POINTER; + } + + m_allocprops = props; + m_pBuffer = pBuffer; + + // If there is an existing allocator, make sure that it is released + // to prevent a memory leak + if (m_pPrivateAllocator) + { + m_pPrivateAllocator->Release(); + m_pPrivateAllocator = NULL; + } + + HRESULT hr = S_OK; + + m_pPrivateAllocator = new CDXFilterAllocator( this, &hr ); + if( !m_pPrivateAllocator ) + { + return E_OUTOFMEMORY; + } + + m_pPrivateAllocator->AddRef( ); + return hr; +} + + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +HRESULT CDXFilterInPin::SetMediaType( const CMediaType *pmt ) +{ + m_bMediaTypeChanged = TRUE; + + return CTransInPlaceInputPin::SetMediaType( pmt ); +} + + +//---------------------------------------------------------------------------- +// don't allocate the memory, just use the buffer the app provided +//---------------------------------------------------------------------------- + +HRESULT CDXFilterAllocator::Alloc( ) +{ + // look at the base class code to see where this came from! + + CAutoLock lck(this); + + // Check he has called SetProperties + HRESULT hr = CBaseAllocator::Alloc(); + if (FAILED(hr)) { + return hr; + } + + // If the requirements haven't changed then don't reallocate + if (hr == S_FALSE) { + /* ASSERT(m_pBuffer); */ + return NOERROR; + } + /* ASSERT(hr == S_OK); we use this fact in the loop below */ + + // Free the old resources + if (m_pBuffer) { + ReallyFree(); + } + + // Compute the aligned size + LONG lAlignedSize = m_lSize + m_lPrefix; + if (m_lAlignment > 1) + { + LONG lRemainder = lAlignedSize % m_lAlignment; + if (lRemainder != 0) + { + lAlignedSize += (m_lAlignment - lRemainder); + } + } + + // Create the contiguous memory block for the samples + // making sure it's properly aligned (64K should be enough!) + /* ASSERT(lAlignedSize % m_lAlignment == 0); */ + + // don't create the buffer - use what was passed to us + // + m_pBuffer = m_pPin->m_pBuffer; + + if (m_pBuffer == NULL) { + return E_OUTOFMEMORY; + } + + LPBYTE pNext = m_pBuffer; + CMediaSample *pSample; + + /* ASSERT(m_lAllocated == 0); */ + + // Create the new samples - we have allocated m_lSize bytes for each sample + // plus m_lPrefix bytes per sample as a prefix. We set the pointer to + // the memory after the prefix - so that GetPointer() will return a pointer + // to m_lSize bytes. + for (; m_lAllocated < m_lCount; m_lAllocated++, pNext += lAlignedSize) + { + pSample = new CMediaSample( + NAME("Sample Grabber memory media sample"), + this, + &hr, + pNext + m_lPrefix, // GetPointer() value + m_lSize); // not including prefix + + /* ASSERT(SUCCEEDED(hr)); */ + if (pSample == NULL) + return E_OUTOFMEMORY; + + // This CANNOT fail + m_lFree.Add(pSample); + } + + m_bChanged = FALSE; + return NOERROR; +} + + +//---------------------------------------------------------------------------- +// don't really free the memory +//---------------------------------------------------------------------------- + +void CDXFilterAllocator::ReallyFree() +{ + // look at the base class code to see where this came from! + + // Should never be deleting this unless all buffers are freed + + /* ASSERT(m_lAllocated == m_lFree.GetCount()); */ + + // Free up all the CMediaSamples + + CMediaSample *pSample; + for (;;) + { + pSample = m_lFree.RemoveHead(); + if (pSample != NULL) + { + delete pSample; + } + else + { + break; + } + } + + m_lAllocated = 0; + + // don't free the buffer - let the app do it +} + + +//---------------------------------------------------------------------------- +// SetProperties: Called by the upstream filter to set the allocator +// properties. The application has already allocated the buffer, so we reject +// anything that is not compatible with that, and return the actual props. +//---------------------------------------------------------------------------- + +HRESULT CDXFilterAllocator::SetProperties( + ALLOCATOR_PROPERTIES *pRequest, + ALLOCATOR_PROPERTIES *pActual +) +{ + HRESULT hr = CMemAllocator::SetProperties(pRequest, pActual); + + if (FAILED(hr)) + { + return hr; + } + + ALLOCATOR_PROPERTIES *pRequired = &(m_pPin->m_allocprops); + if (pRequest->cbAlign != pRequired->cbAlign) + { + return VFW_E_BADALIGN; + } + if (pRequest->cbPrefix != pRequired->cbPrefix) + { + return E_FAIL; + } + if (pRequest->cbBuffer > pRequired->cbBuffer) + { + return E_FAIL; + } + if (pRequest->cBuffers > pRequired->cBuffers) + { + return E_FAIL; + } + + *pActual = *pRequired; + + m_lCount = pRequired->cBuffers; + m_lSize = pRequired->cbBuffer; + m_lAlignment = pRequired->cbAlign; + m_lPrefix = pRequired->cbPrefix; + + return S_OK; +} diff --git a/linphone/mediastreamer2/src/dxfilter.h b/linphone/mediastreamer2/src/dxfilter.h new file mode 100644 index 000000000..cc63f0de9 --- /dev/null +++ b/linphone/mediastreamer2/src/dxfilter.h @@ -0,0 +1,231 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// {4D6410BE-7643-4f43-B55F-8821A6FFB50A} +DEFINE_GUID(CLSID_DXFilter, +0x4d6410be, 0x7643, 0x4f43, 0xb5, 0x5f, 0x88, 0x21, 0xa6, 0xff, 0xb5, 0xa); + +// {52A7F345-CD92-442c-89C1-632C16AD5003} +DEFINE_GUID(IID_IDXFilter, +0x52a7f345, 0xcd92, 0x442c, 0x89, 0xc1, 0x63, 0x2c, 0x16, 0xad, 0x50, 0x3); + + +// We define a callback typedef for this example. +// Normally, you would make the DXFilter support a COM interface, +// and in one of its methods you would pass in a pointer to a COM interface +// used for calling back. See the DirectX documentation for the DXFilter +// for more information. + +typedef HRESULT (*SAMPLECALLBACK) ( + IMediaSample * pSample, + REFERENCE_TIME * StartTime, + REFERENCE_TIME * StopTime, + BOOL TypeChanged ); + + +// We define the interface the app can use to program us +MIDL_INTERFACE("6B652FFF-11FE-4FCE-92AD-0266B5D7C78F") +IDXFilter : public IUnknown +{ + public: + + virtual HRESULT STDMETHODCALLTYPE SetAcceptedMediaType( + const CMediaType *pType) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( + CMediaType *pType) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCallback( + SAMPLECALLBACK Callback) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDeliveryBuffer( + ALLOCATOR_PROPERTIES props, + BYTE *pBuffer) = 0; +}; + + +class CDXFilterInPin; +class CDXFilter; + +//---------------------------------------------------------------------------- +// This is a special allocator that KNOWS that the person who is creating it +// will only create one of them. It allocates CMediaSamples that only +// reference the buffer location that is set in the pin's renderer's +// data variable +//---------------------------------------------------------------------------- + +class CDXFilterAllocator : public CMemAllocator +{ + friend class CDXFilterInPin; + friend class CDXFilter; + +protected: + + // our pin who created us + // + CDXFilterInPin * m_pPin; + +public: + + CDXFilterAllocator( CDXFilterInPin * pParent, HRESULT *phr ) + : CMemAllocator( TEXT("DXFilterAllocator\0"), NULL, phr ) + , m_pPin( pParent ) + { + }; + + ~CDXFilterAllocator( ) + { + // wipe out m_pBuffer before we try to delete it. It's not an allocated + // buffer, and the default destructor will try to free it! + m_pBuffer = NULL; + } + + HRESULT Alloc( ); + + void ReallyFree(); + + // Override this to reject anything that does not match the actual buffer + // that was created by the application + STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES *pRequest, ALLOCATOR_PROPERTIES *pActual); + +}; + +//---------------------------------------------------------------------------- +// we override the input pin class so we can provide a media type +// to speed up connection times. When you try to connect a filesourceasync +// to a transform filter, DirectShow will insert a splitter and then +// start trying codecs, both audio and video, video codecs first. If +// your sample grabber's set to connect to audio, unless we do this, it +// will try all the video codecs first. Connection times are sped up x10 +// for audio with just this minor modification! +//---------------------------------------------------------------------------- + +class CDXFilterInPin : public CTransInPlaceInputPin +{ + friend class CDXFilterAllocator; + friend class CDXFilter; + + CDXFilterAllocator * m_pPrivateAllocator; + ALLOCATOR_PROPERTIES m_allocprops; + BYTE * m_pBuffer; + BOOL m_bMediaTypeChanged; + +protected: + + CDXFilter * DXFilter( ) { return (CDXFilter*) m_pFilter; } + HRESULT SetDeliveryBuffer( ALLOCATOR_PROPERTIES props, BYTE * m_pBuffer ); + +public: + + CDXFilterInPin( CTransInPlaceFilter * pFilter, HRESULT * pHr ) + : CTransInPlaceInputPin( TEXT("DXFilterInputPin\0"), pFilter, pHr, L"Input\0" ) + , m_pPrivateAllocator( NULL ) + , m_pBuffer( NULL ) + , m_bMediaTypeChanged( FALSE ) + { + memset( &m_allocprops, 0, sizeof( m_allocprops ) ); + } + + ~CDXFilterInPin( ) + { + if( m_pPrivateAllocator ) delete m_pPrivateAllocator; + } + + // override to provide major media type for fast connects + + HRESULT GetMediaType( int iPosition, CMediaType *pMediaType ); + + // override this or GetMediaType is never called + + STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); + + // override this to refuse any allocators besides + // the one the user wants, if this is set + + STDMETHODIMP NotifyAllocator( IMemAllocator *pAllocator, BOOL bReadOnly ); + + // override this so we always return the special allocator, if necessary + + STDMETHODIMP GetAllocator( IMemAllocator **ppAllocator ); + + HRESULT SetMediaType( const CMediaType *pmt ); + + // we override this to tell whoever's upstream of us what kind of + // properties we're going to demand to have + // + STDMETHODIMP GetAllocatorRequirements( ALLOCATOR_PROPERTIES *pProps ); + + + +}; + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +class CDXFilter : public CTransInPlaceFilter, + public IDXFilter +{ + friend class CDXFilterInPin; + friend class CDXFilterAllocator; + +protected: + + CMediaType m_mtAccept; + SAMPLECALLBACK m_callback; + CCritSec m_Lock; // serialize access to our data + +#if !defined(_WIN32_WCE) + BOOL IsReadOnly( ) { return !m_bModifiesData; } +#endif + + // PURE, override this to ensure we get + // connected with the right media type + HRESULT CheckInputType( const CMediaType * pmt ); + + // PURE, override this to callback + // the user when a sample is received + HRESULT Transform( IMediaSample * pms ); + + // override this so we can return S_FALSE directly. + // The base class CTransInPlace + // Transform( ) method is called by it's + // Receive( ) method. There is no way + // to get Transform( ) to return an S_FALSE value + // (which means "stop giving me data"), + // to Receive( ) and get Receive( ) to return S_FALSE as well. + + HRESULT Receive( IMediaSample * pms ); + +public: + + static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr); + + // Expose IDXFilter + STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); + DECLARE_IUNKNOWN; + + CDXFilter( IUnknown * pOuter, HRESULT * pHr, BOOL ModifiesData ); + + // IDXFilter + STDMETHODIMP SetAcceptedMediaType( const CMediaType * pmt ); + STDMETHODIMP GetConnectedMediaType( CMediaType * pmt ); + STDMETHODIMP SetCallback( SAMPLECALLBACK Callback ); + STDMETHODIMP SetDeliveryBuffer( ALLOCATOR_PROPERTIES props, BYTE * m_pBuffer ); +}; diff --git a/linphone/mediastreamer2/src/ffmpeg-priv.h b/linphone/mediastreamer2/src/ffmpeg-priv.h new file mode 100644 index 000000000..eb5fcf471 --- /dev/null +++ b/linphone/mediastreamer2/src/ffmpeg-priv.h @@ -0,0 +1,48 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef FFMPEG_PRIV_H +#define FFMPEG_PRIV_H + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#if defined(HAVE_LIBAVCODEC_AVCODEC_H) +/* new layout */ +# include +# include +#else +/* old layout */ +# include +# include +#endif + +#if defined(HAVE_LIBSWSCALE_SWSCALE_H) +/* new layout */ +# include +# elif !defined(HAVE_LIBAVCODEC_AVCODEC_H) +/* old layout */ +# include +#else +/* swscale.h not delivered: use linphone private version */ +# include "swscale.h" +#endif + +#endif /* FFMPEG_PRIV_H */ diff --git a/linphone/mediastreamer2/src/g711common.h b/linphone/mediastreamer2/src/g711common.h new file mode 100644 index 000000000..3f2c9e330 --- /dev/null +++ b/linphone/mediastreamer2/src/g711common.h @@ -0,0 +1,171 @@ +/* + * PCM - A-Law conversion + * Copyright (c) 2000 by Abramo Bagnara + * + * Wrapper for linphone Codec class by Simon Morlat + */ + +static inline int val_seg(int val) +{ + int r = 0; + val >>= 7; + if (val & 0xf0) { + val >>= 4; + r += 4; + } + if (val & 0x0c) { + val >>= 2; + r += 2; + } + if (val & 0x02) + r += 1; + return r; +} + +/* + * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law + * + * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data. + * + * Linear Input Code Compressed Code + * ------------------------ --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +static inline unsigned char s16_to_alaw(int pcm_val) +{ + int mask; + int seg; + unsigned char aval; + + if (pcm_val >= 0) { + mask = 0xD5; + } else { + mask = 0x55; + pcm_val = -pcm_val; + if (pcm_val > 0x7fff) + pcm_val = 0x7fff; + } + + if (pcm_val < 256) + aval = pcm_val >> 4; + else { + /* Convert the scaled magnitude to segment number. */ + seg = val_seg(pcm_val); + aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f); + } + return aval ^ mask; +} + +/* + * alaw_to_s16() - Convert an A-law value to 16-bit linear PCM + * + */ +static inline int alaw_to_s16(unsigned char a_val) +{ + int t; + int seg; + + a_val ^= 0x55; + t = a_val & 0x7f; + if (t < 16) + t = (t << 4) + 8; + else { + seg = (t >> 4) & 0x07; + t = ((t & 0x0f) << 4) + 0x108; + t <<= seg -1; + } + return ((a_val & 0x80) ? t : -t); +} +/* + * s16_to_ulaw() - Convert a linear PCM value to u-law + * + * In order to simplify the encoding process, the original linear magnitude + * is biased by adding 33 which shifts the encoding range from (0 - 8158) to + * (33 - 8191). The result can be seen in the following encoding table: + * + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz + * + * Each biased linear code has a leading 1 which identifies the segment + * number. The value of the segment number is equal to 7 minus the number + * of leading 0's. The quantization interval is directly available as the + * four bits wxyz. * The trailing bits (a - h) are ignored. + * + * Ordinarily the complement of the resulting code word is used for + * transmission, and so the code word is complemented before it is returned. + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */ +{ + int mask; + int seg; + unsigned char uval; + + if (pcm_val < 0) { + pcm_val = 0x84 - pcm_val; + mask = 0x7f; + } else { + pcm_val += 0x84; + mask = 0xff; + } + if (pcm_val > 0x7fff) + pcm_val = 0x7fff; + + /* Convert the scaled magnitude to segment number. */ + seg = val_seg(pcm_val); + + /* + * Combine the sign, segment, quantization bits; + * and complement the code word. + */ + uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f); + return uval ^ mask; +} + +/* + * ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM + * + * First, a biased linear code is derived from the code word. An unbiased + * output can then be obtained by subtracting 33 from the biased code. + * + * Note that this function expects to be passed the complement of the + * original code word. This is in keeping with ISDN conventions. + */ +static inline int ulaw_to_s16(unsigned char u_val) +{ + int t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = ((u_val & 0x0f) << 3) + 0x84; + t <<= (u_val & 0x70) >> 4; + + return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84)); +} diff --git a/linphone/mediastreamer2/src/gsm.c b/linphone/mediastreamer2/src/gsm.c new file mode 100644 index 000000000..575a79bc0 --- /dev/null +++ b/linphone/mediastreamer2/src/gsm.c @@ -0,0 +1,165 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" + +#include + +typedef struct EncState{ + gsm state; + uint32_t ts; + MSBufferizer *bufferizer; +} EncState; + +static void enc_init(MSFilter *f){ + EncState *s=(EncState *)ms_new(EncState,1); + s->state=gsm_create(); + s->ts=0; + s->bufferizer=ms_bufferizer_new(); + f->data=s; +} + +static void enc_uninit(MSFilter *f){ + EncState *s=(EncState*)f->data; + gsm_destroy(s->state); + ms_bufferizer_destroy(s->bufferizer); + ms_free(s); +} + + + +static void enc_process(MSFilter *f){ + EncState *s=(EncState*)f->data; + mblk_t *im; + int16_t buf[160]; + + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + ms_bufferizer_put(s->bufferizer,im); + } + while(ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,sizeof(buf))==sizeof(buf)) { + mblk_t *om=allocb(33,0); + gsm_encode(s->state,(gsm_signal*)buf,(gsm_byte*)om->b_wptr); + om->b_wptr+=33; + mblk_set_timestamp_info(om,s->ts); + ms_queue_put(f->outputs[0],om); + s->ts+=sizeof(buf)/2; + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_gsm_enc_desc={ + MS_GSM_ENC_ID, + "MSGsmEnc", + "The GSM full-rate codec", + MS_FILTER_ENCODER, + "gsm", + 1, + 1, + enc_init, + NULL, + enc_process, + NULL, + enc_uninit, + NULL +}; + +#else + +MSFilterDesc ms_gsm_enc_desc={ + .id=MS_GSM_ENC_ID, + .name="MSGsmEnc", + .text="The GSM full-rate codec", + .category=MS_FILTER_ENCODER, + .enc_fmt="gsm", + .ninputs=1, + .noutputs=1, + .init=enc_init, + .process=enc_process, + .uninit=enc_uninit, +}; + +#endif + +static void dec_init(MSFilter *f){ + f->data=gsm_create(); +} + +static void dec_uninit(MSFilter *f){ + gsm s=(gsm)f->data; + gsm_destroy(s); +} + + +static void dec_process(MSFilter *f){ + gsm s=(gsm)f->data; + mblk_t *im; + mblk_t *om; + const int frsz=160*2; + + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + om=allocb(frsz,0); + if (gsm_decode(s,(gsm_byte*)im->b_rptr,(gsm_signal*)om->b_wptr)<0){ + ms_warning("gsm_decode error!"); + freemsg(om); + }else{ + om->b_wptr+=frsz; + ms_queue_put(f->outputs[0],om); + } + freemsg(im); + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_gsm_dec_desc={ + MS_GSM_DEC_ID, + "MSGsmDec", + "The GSM codec", + MS_FILTER_DECODER, + "gsm", + 1, + 1, + dec_init, + NULL, + dec_process, + NULL, + dec_uninit, + NULL +}; + +#else + +MSFilterDesc ms_gsm_dec_desc={ + .id=MS_GSM_DEC_ID, + .name="MSGsmDec", + .text="The GSM codec", + .category=MS_FILTER_DECODER, + .enc_fmt="gsm", + .ninputs=1, + .noutputs=1, + .init=dec_init, + .process=dec_process, + .uninit=dec_uninit +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_gsm_dec_desc) +MS_FILTER_DESC_EXPORT(ms_gsm_enc_desc) diff --git a/linphone/mediastreamer2/src/ice.c b/linphone/mediastreamer2/src/ice.c new file mode 100644 index 000000000..6259728bc --- /dev/null +++ b/linphone/mediastreamer2/src/ice.c @@ -0,0 +1,556 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#ifdef __APPLE__ +#include +#endif +#include +#include +#endif + +#include "mediastreamer2/ice.h" +#include "mediastreamer2/mscommon.h" + +static void +ice_sendtest( Socket myFd, StunAddress4 *dest, + const StunAtrString *username, const StunAtrString *password, + int testNum, bool_t verbose , UInt128 *tid); + +static void +ice_sendtest( Socket myFd, StunAddress4 *dest, + const StunAtrString *username, const StunAtrString *password, + int testNum, bool_t verbose , UInt128 *tid) +{ + bool_t changePort=FALSE; + bool_t changeIP=FALSE; + bool_t discard=FALSE; + + StunMessage req; + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = STUN_MAX_MESSAGE_SIZE; + + switch (testNum) + { + case 1: + case 10: + case 11: + break; + case 2: + /* changePort=TRUE; */ + changeIP=TRUE; + break; + case 3: + changePort=TRUE; + break; + case 4: + changeIP=TRUE; + break; + case 5: + discard=TRUE; + break; + default: + printf("Test %i is unkown\n", testNum); + return ; /* error */ + } + + memset(&req, 0, sizeof(StunMessage)); + + stunBuildReqSimple( &req, username, + changePort , changeIP , + testNum ); + + len = stunEncodeMessage( &req, buf, len, password,verbose ); + + memcpy(tid , &(req.msgHdr.id), sizeof(req.msgHdr.id)); + + sendMessage( myFd, buf, len, dest->addr, dest->port, verbose ); +} + +int ice_sound_send_stun_request(RtpSession *session, struct CandidatePair *remote_candidates, int round) +{ + int roll=250; +#if 0 + /* in "passive" mode (UA not behind a NATor behind a full cone NAT), + wait a few delay before sending the first STUN request: + this help to traverse */ + if (session->setup_passive>0) + { + return 0; + } +#endif + + if (remote_candidates==NULL) + return 0; + + if (round>500) + roll=2*roll; + + if (round%roll==50 || round==10) + { + int pos; + +#if 0 + /* do this only with application that support this */ + if (osip_strncasecmp(remote_useragent, "linphone/", 8)!=0) + { + /* use stun only with linphone to linphone softphone */ + return 0; + } +#endif + + for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++) + { + int media_socket = rtp_session_get_rtp_socket(session); + StunAddress4 stunServerAddr; + StunAtrString username; + StunAtrString password; + bool_t res; + int pad_size; + + struct CandidatePair *cand_pair = &remote_candidates[pos]; + username.sizeValue = 0; + password.sizeValue = 0; + + /* set username to L3:1:R2:1 */ + snprintf(username.value, sizeof(username.value), "%s:%i:%s:%i", + cand_pair->local_candidate.candidate_id, + 1, + cand_pair->remote_candidate.candidate_id, + 1); + username.sizeValue = (UInt16)strlen(username.value); + pad_size = username.sizeValue % 4; + + username.value[username.sizeValue]='\0'; + username.value[username.sizeValue+1]='\0'; + username.value[username.sizeValue+2]='\0'; + username.value[username.sizeValue+3]='\0'; + + username.sizeValue = username.sizeValue + 4 - pad_size; + + snprintf(password.value, sizeof(password.value), "%s", + cand_pair->remote_candidate.password); + password.sizeValue = (UInt16)strlen(password.value); + +#if 0 + pad_size = password.sizeValue%4; + password.value[password.sizeValue]='\0'; + password.value[password.sizeValue+1]='\0'; + password.value[password.sizeValue+2]='\0'; + password.value[password.sizeValue+3]='\0'; + password.sizeValue = password.sizeValue + pad_size; +#endif + + res = stunParseServerName(cand_pair->remote_candidate.ipaddr, + &stunServerAddr); + if ( res == TRUE ) + { + stunServerAddr.port = cand_pair->remote_candidate.port; + ice_sendtest(media_socket, &stunServerAddr, &username, &password, 1, 0/*FALSE*/, + &(cand_pair->tid)); + } + } + } + + return 0; +} + +static int +_ice_get_localip_for (struct sockaddr_storage *saddr, size_t saddr_len, char *loc, int size) +{ + int err, tmp; + int sock; + struct sockaddr_storage addr; + socklen_t addr_len; + + strcpy (loc, "127.0.0.1"); /* always fallback to local loopback */ + + sock = socket (saddr->ss_family, SOCK_DGRAM, 0); + tmp = 1; + err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &tmp, sizeof (int)); + if (err < 0) + { + ms_error("ice.c: Error in setsockopt"); + closesocket (sock); + return -1; + } + err = connect (sock, (struct sockaddr*)saddr, saddr_len); + if (err < 0) + { + ms_error("ice.c: Error in connect"); + closesocket (sock); + return -1; + } + addr_len = sizeof (addr); + err = getsockname (sock, (struct sockaddr *) &addr, (socklen_t*)&addr_len); + if (err != 0) + { + ms_error("ice.c: Error in getsockname"); + closesocket (sock); + return -1; + } + + err = getnameinfo ((struct sockaddr *) &addr, addr_len, loc, size, NULL, 0, NI_NUMERICHOST); + if (err != 0) + { + ms_error("ice.c: Error in getnameinfo"); + closesocket (sock); + return -1; + } + closesocket (sock); + /* ms_message("ice.c: Outgoing interface for sending STUN answer is %s", loc); */ + return 0; +} + +int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_candidates, OrtpEvent *evt) +{ + int switch_to_address = -1; + StunMessage msg; + bool_t res; + int already_worked_once=-1; + OrtpEventData *evt_data = ortp_event_get_data(evt); + mblk_t *mp = evt_data->packet; + struct sockaddr_in *udp_remote; + char src6host[NI_MAXHOST]; + int recvport = 0; + int i; + + udp_remote = (struct sockaddr_in*)&evt_data->ep->addr; + + memset( &msg, 0 , sizeof(msg) ); + res = stunParseMessage((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr, &msg, 0); + if (!res) + { + ms_error("ice.c: Malformed STUN packet."); + return -1; + } + + memset (src6host, 0, sizeof (src6host)); + + { + struct sockaddr_storage *aaddr = (struct sockaddr_storage *)&evt_data->ep->addr; + if (aaddr->ss_family==AF_INET) + recvport = ntohs (((struct sockaddr_in *) udp_remote)->sin_port); + else + recvport = ntohs (((struct sockaddr_in6 *) &evt_data->ep->addr)->sin6_port); + } + i = getnameinfo ((struct sockaddr*)&evt_data->ep->addr, evt_data->ep->addrlen, + src6host, NI_MAXHOST, + NULL, 0, NI_NUMERICHOST); + if (i != 0) + { + ms_error("ice.c: Error with getnameinfo"); + } else + { + if (msg.msgHdr.msgType == BindRequestMsg) + ms_message("ice.c: Request received from: %s:%i", + src6host, recvport); + else + ms_message("ice.c: Answer received from: %s:%i", + src6host, recvport); + } + + if (remote_candidates!=NULL) { + int pos; + for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++) + { + struct CandidatePair *cand_pair = &remote_candidates[pos]; +#ifdef RESTRICTIVE_ICE + if (cand_pair->connectivity_check == VALID + ||cand_pair->connectivity_check == RECV_VALID) + { + already_worked_once=pos; + break; + } +#else + if (cand_pair->connectivity_check == VALID + ||cand_pair->connectivity_check == RECV_VALID + ||cand_pair->connectivity_check == SEND_VALID) + { + already_worked_once=pos; + break; + } +#endif + } + } + + if (msg.msgHdr.msgType == BindRequestMsg) + { + StunMessage resp; + StunAddress4 dest; + StunAtrString hmacPassword; + StunAddress4 from; + StunAddress4 secondary; + StunAddress4 myAddr; + StunAddress4 myAltAddr; + bool_t changePort = FALSE; + bool_t changeIp = FALSE; + struct sockaddr_storage name; + socklen_t namelen; + char localip[128]; + int rtp_socket; + memset(&name, '\0', sizeof(struct sockaddr_storage)); + memset(localip, '\0', sizeof(localip)); + _ice_get_localip_for ((struct sockaddr_storage*)&evt_data->ep->addr, evt_data->ep->addrlen, localip, 128); + + from.addr = ntohl(udp_remote->sin_addr.s_addr); + from.port = ntohs(udp_remote->sin_port); + + secondary.addr = 0; + secondary.port = 0; + + namelen = sizeof(struct sockaddr_storage); + rtp_socket = rtp_session_get_rtp_socket(session); + i = getsockname(rtp_socket, (struct sockaddr*)&name, &namelen); + if (i!=0) + { + ms_error("ice.c: getsockname failed."); + return -1; + } + + myAddr.port = ntohs (((struct sockaddr_in*)&name)->sin_port); + i = stunParseHostName(localip, &myAddr.addr, &myAddr.port, myAddr.port); + if (!i) + { + ms_error("ice.c: stunParseHostName failed."); + return -1; + } + myAddr.port = ntohs (((struct sockaddr_in*)&name)->sin_port); + + /* changed-address set to local address/port */ + myAltAddr = myAddr; + dest.addr = 0; + dest.port = 0; + + res = stunServerProcessMsg((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr, + &from, + &secondary, + &myAddr, + &myAltAddr, + &resp, + &dest, + &hmacPassword, + &changePort, + &changeIp, + FALSE ); + + if (!res) + { + ms_error("ice.c: Failed to process STUN request."); + return -1; + } + + if (changePort == TRUE || changeIp == TRUE) + { + ms_error("ice.c: STUN request with changePort or changeIP refused."); + return -1; + } + + res=TRUE; + if ( dest.addr == 0 ) res=FALSE; + if ( dest.port == 0 ) res=FALSE; + if (!res) + { + ms_error("ice.c: Missing destination value for response."); + return -1; + } + + + if (msg.hasUsername!=TRUE || msg.username.sizeValue<=0) + { + /* reply 430 */ + ms_error("ice.c: Missing or bad username value."); + return -1; + } + + /* + USERNAME is considered valid if its topmost portion (the part up to, + but not including the second colon) corresponds to a transport address + ID known to the agent. + */ + if (remote_candidates!=NULL) { + int pos; + for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++) + { + char username[256]; + struct CandidatePair *cand_pair = &remote_candidates[pos]; + size_t len = strlen(cand_pair->remote_candidate.candidate_id); + + if (cand_pair->connectivity_check == VALID) + { + break; + } + + memset(username, '\0', sizeof(username)); + snprintf(username, sizeof(username), "%s:%i:%s:%i", + cand_pair->remote_candidate.candidate_id, + 1, + cand_pair->local_candidate.candidate_id, + 1); + + if (len+3remote_candidate.candidate_id, len)==0) + { + char tmp[10]; + int k; + snprintf(tmp, 10, "%s", msg.username.value + len +1); + for (k=0;k<10;k++) + { + if (tmp[k]=='\0') + break; + if (tmp[k]==':') + { + tmp[k]='\0'; + break; + } + } + k = atoi(tmp); + /* TODO support for 2 stream RTP+RTCP */ + if (k>0 && k<10 && k==1) + { + /* candidate-id found! */ +#if 0 + ms_message("ice.c: Find candidate id (index=%i) for incoming STUN request.", pos); +#endif + + if (strncmp(msg.username.value, username, strlen(username))==0) + { +#ifdef RESTRICTIVE_ICE + ms_message("ice.c: Valid STUN request received (to=%s:%i from=%s:%i).", + cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port, + src6host, recvport); + /* We can't be sure the remote end will receive our answer: + connection could be only one way... + */ + if (cand_pair->connectivity_check != VALID) + { + switch_to_address = pos; + } +#else + switch_to_address = pos; +#endif + if (cand_pair->connectivity_check == RECV_VALID + || cand_pair->connectivity_check == VALID) + { + if (cand_pair->connectivity_check != VALID) + { + switch_to_address = pos; + ms_message("ice.c: candidate id (index=%i) moved in VALID state (stunbindingrequest received).", pos); + cand_pair->connectivity_check = VALID; + } + } + else + cand_pair->connectivity_check = SEND_VALID; + + /* we have a VALID one */ + } + } + } + } + } + + /* + The password associated with that transport address ID is used to verify + the MESSAGE-INTEGRITY attribute, if one was present in the request. + */ + + + { + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = sizeof(buf); + len = stunEncodeMessage( &resp, buf, len, &hmacPassword,FALSE ); + if (len) + sendMessage( rtp_socket, buf, len, dest.addr, dest.port, FALSE ); + } + } + else + { + /* set state to RECV-VALID or VALID */ + StunMessage resp; + StunAddress4 mappedAddr; + memset(&resp, 0, sizeof(StunMessage)); + res = stunParseMessage((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr, + &resp, FALSE ); + if (!res) + { + ms_error("ice.c: Bad format for STUN answer."); + return -1; + } + + mappedAddr = resp.mappedAddress.ipv4; + + if (remote_candidates!=NULL) { + int pos; + for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++) + { + struct CandidatePair *cand_pair = &remote_candidates[pos]; + + if (memcmp(&(cand_pair->tid), &(resp.msgHdr.id), sizeof(resp.msgHdr.id))==0) + { + /* Youhouhouhou */ + if (cand_pair->connectivity_check != VALID) + { + switch_to_address = pos; + } +#if 0 + ms_message("ice.c: Valid STUN answer received (to=%s:%i from=%s:%i)", + cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port, + src6host, recvport); +#endif + if (cand_pair->connectivity_check == SEND_VALID + || cand_pair->connectivity_check == VALID) + { + if (cand_pair->connectivity_check != VALID) + { + ms_message("ice.c: Switch to VALID mode for (to=%s:%i from=%s:%i)", + cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port, + src6host, recvport); + cand_pair->connectivity_check = VALID; + } + } + else + cand_pair->connectivity_check = RECV_VALID; + } + } + } + } + + if (remote_candidates==NULL) { + ms_warning("ice.c: STUN connectivity check is disabled but we received a STUN message (%s:%i)\n", + src6host, recvport); + return 0; + } + if (switch_to_address == -1) + return 0; + + { + /* skip symmetric RTP if any previous connection is working */ + if (switch_to_addressrtp.rem_addr, &evt_data->ep->addr, evt_data->ep->addrlen); + session->rtp.rem_addrlen=evt_data->ep->addrlen; + } + } + return 0; +} + diff --git a/linphone/mediastreamer2/src/macsnd.c b/linphone/mediastreamer2/src/macsnd.c new file mode 100644 index 000000000..da44fc3f9 --- /dev/null +++ b/linphone/mediastreamer2/src/macsnd.c @@ -0,0 +1,702 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* this file is specifically distributed under a BSD license */ + +/** +* Copyright (C) 2007 Hiroki Mori (himori@users.sourceforge.net) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**/ +#include +#include +#include + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" + +MSFilter *ms_ca_read_new(MSSndCard *card); +MSFilter *ms_ca_write_new(MSSndCard *card); + +typedef struct CAData{ + char *pcmdev; + char *mixdev; + AudioUnit caOutAudioUnit; + AudioUnit caInAudioUnit; + AudioStreamBasicDescription caOutASBD; + AudioStreamBasicDescription caInASBD; + AURenderCallbackStruct caOutRenderCallback; + AURenderCallbackStruct caInRenderCallback; + AudioConverterRef caOutConverter; + AudioConverterRef caInConverter; + int pcmfd; + int rate; + int bits; + ms_mutex_t mutex; + queue_t rq; + MSBufferizer * bufferizer; + bool_t read_started; + bool_t write_started; + bool_t stereo; + void *caSourceBuffer; + AudioBufferList *fAudioBuffer, *fMSBuffer; +} CAData; + +// Convenience function to dispose of our audio buffers +void DestroyAudioBufferList(AudioBufferList* list) +{ + UInt32 i; + + if(list) { + for(i = 0; i < list->mNumberBuffers; i++) { + if(list->mBuffers[i].mData) + free(list->mBuffers[i].mData); + } + free(list); + } +} + +// Convenience function to allocate our audio buffers +AudioBufferList *AllocateAudioBufferList(UInt32 numChannels, UInt32 size) +{ + AudioBufferList* list; + UInt32 i; + + list = (AudioBufferList*)calloc(1, sizeof(AudioBufferList) + numChannels * sizeof(AudioBuffer)); + if(list == NULL) + return NULL; + + list->mNumberBuffers = numChannels; + for(i = 0; i < numChannels; ++i) { + list->mBuffers[i].mNumberChannels = 1; + list->mBuffers[i].mDataByteSize = size; + list->mBuffers[i].mData = malloc(size); + if(list->mBuffers[i].mData == NULL) { + DestroyAudioBufferList(list); + return NULL; + } + } + return list; +} + +OSStatus writeACInputProc ( + AudioConverterRef inAudioConverter, + UInt32 *ioNumberDataPackets, + AudioBufferList *ioData, + AudioStreamPacketDescription **outDataPacketDescription, + void* inUserData) +{ + OSStatus err = noErr; + CAData *d=(CAData*)inUserData; + UInt32 packetSize = (d->bits / 8) * (d->stereo ? 2 : 1); +// ms_error("writeACInputProc %d", *ioNumberDataPackets); + + if(*ioNumberDataPackets) { + if(d->caSourceBuffer != NULL) { + free(d->caSourceBuffer); + d->caSourceBuffer = NULL; + } + + d->caSourceBuffer = (void *) calloc (1, *ioNumberDataPackets * packetSize); + + ioData->mBuffers[0].mData = d->caSourceBuffer; // tell the Audio Converter where it's source data is + + ms_mutex_lock(&d->mutex); + int readsize = ms_bufferizer_read(d->bufferizer,d->caSourceBuffer,*ioNumberDataPackets * packetSize); + ms_mutex_unlock(&d->mutex); + if(readsize != *ioNumberDataPackets * packetSize) { + /* ms_error("ms_bufferizer_read error request = %d result = %d", *ioNumberDataPackets * packetSize, readsize); */ + memset(d->caSourceBuffer, 0, *ioNumberDataPackets * packetSize); + ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets * packetSize; // tell the Audio Converter how much source data there is + } else { + ioData->mBuffers[0].mDataByteSize = readsize; // tell the Audio Converter how much source data there is + } + } + + return err; +} + +OSStatus readACInputProc (AudioConverterRef inAudioConverter, + UInt32* ioNumberDataPackets, + AudioBufferList* ioData, + AudioStreamPacketDescription** ioASPD, + void* inUserData) +{ + CAData *d=(CAData*)inUserData; + AudioBufferList* l_inputABL = d->fAudioBuffer; + UInt32 totalInputBufferSizeBytes = ((*ioNumberDataPackets) * sizeof (float)); + int counter = d->caInASBD.mChannelsPerFrame; + ioData->mNumberBuffers = d->caInASBD.mChannelsPerFrame; + + while (--counter >= 0) { + AudioBuffer* l_ioD_AB = &(ioData->mBuffers[counter]); + l_ioD_AB->mNumberChannels = 1; + l_ioD_AB->mData = (float*)(l_inputABL->mBuffers[counter].mData); + l_ioD_AB->mDataByteSize = totalInputBufferSizeBytes; + } + + return (noErr); +} + +OSStatus readRenderProc(void *inRefCon, + AudioUnitRenderActionFlags *inActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumFrames, + AudioBufferList *ioData) +{ + CAData *d=(CAData*)inRefCon; + OSStatus err = noErr; + + // Render into audio buffer + err = AudioUnitRender(d->caInAudioUnit, inActionFlags, inTimeStamp, inBusNumber, + inNumFrames, d->fAudioBuffer); + if(err != noErr) + ms_error("AudioUnitRender %d size = %d", err, d->fAudioBuffer->mBuffers[0].mDataByteSize); + + UInt32 AvailableOutputBytes = inNumFrames * sizeof (float); + UInt32 propertySize = sizeof (AvailableOutputBytes); + err = AudioConverterGetProperty (d->caInConverter, + kAudioConverterPropertyCalculateOutputBufferSize, + &propertySize, + &AvailableOutputBytes); + + if(err != noErr) + ms_error("AudioConverterGetProperty %d", err); + + UInt32 ActualOutputFrames = AvailableOutputBytes / sizeof (short); + err = AudioConverterFillComplexBuffer (d->caInConverter, + (AudioConverterComplexInputDataProc)(readACInputProc), + inRefCon, + &ActualOutputFrames, + d->fMSBuffer, + NULL); + if(err != noErr) + ms_error("readRenderProc:AudioConverterFillComplexBuffer %08x mNumberBuffers = %d", err, ioData->mNumberBuffers); + + mblk_t *rm=NULL; + rm=allocb(d->fMSBuffer->mBuffers[0].mDataByteSize,0); + memcpy(rm->b_wptr, d->fMSBuffer->mBuffers[0].mData, d->fMSBuffer->mBuffers[0].mDataByteSize); +// memset(rm->b_wptr, 0, d->fMSBuffer->mBuffers[0].mDataByteSize); + rm->b_wptr+=d->fMSBuffer->mBuffers[0].mDataByteSize; + ms_mutex_lock(&d->mutex); + putq(&d->rq,rm); + ms_mutex_unlock(&d->mutex); + rm=NULL; + + return err; +} + +OSStatus writeRenderProc(void *inRefCon, + AudioUnitRenderActionFlags *inActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumFrames, + AudioBufferList *ioData) +{ + OSStatus err= noErr; + void *inInputDataProcUserData=NULL; + CAData *d=(CAData*)inRefCon; + if(d->write_started != FALSE) { + AudioStreamPacketDescription* outPacketDescription = NULL; + err = AudioConverterFillComplexBuffer(d->caOutConverter, writeACInputProc, inRefCon, + &inNumFrames, ioData, outPacketDescription); + if(err != noErr) + ms_error("writeRenderProc:AudioConverterFillComplexBuffer err %08x %d", err, ioData->mNumberBuffers); + } + return err; +} + +static void ca_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent) +{ + CAData *d=(CAData*)card->data; +} + +static int ca_get_level(MSSndCard *card, MSSndCardMixerElem e) +{ + CAData *d=(CAData*)card->data; + return 0; +} + +static void ca_set_source(MSSndCard *card, MSSndCardCapture source) +{ + CAData *d=(CAData*)card->data; +} + +static void ca_init(MSSndCard *card){ + ms_debug("ca_init"); + OSStatus err; + UInt32 param; + AudioDeviceID fInputDeviceID; + CAData *d=ms_new(CAData,1); + + ComponentDescription desc; + + // Get Default Output audio unit + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + Component comp = FindNextComponent(NULL, &desc); + if (comp == NULL) return; + + err = OpenAComponent(comp, &d->caOutAudioUnit); + if(err != noErr) return; + + // Get Default Input audio unit + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_HALOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + comp = FindNextComponent(NULL, &desc); + if (comp == NULL) return; + + err = OpenAComponent(comp, &d->caInAudioUnit); + if(err != noErr) return; + + AudioUnitInitialize(d->caOutAudioUnit); + AudioUnitInitialize(d->caInAudioUnit); + + UInt32 asbdsize = sizeof(AudioStreamBasicDescription); + memset((char *)&d->caOutASBD, 0, asbdsize); + memset((char *)&d->caInASBD, 0, asbdsize); + + // Setup Output audio unit + OSStatus result = AudioUnitGetProperty (d->caOutAudioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &d->caOutASBD, + &asbdsize); + + result = AudioUnitSetProperty (d->caOutAudioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &d->caOutASBD, + asbdsize); + + // Setup Input audio unit + // Enable input on the AUHAL + param = 1; + result = AudioUnitSetProperty(d->caInAudioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + 1, + ¶m, + sizeof(UInt32)); + +// Select the default input device + param = sizeof(AudioDeviceID); + result = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, + ¶m, + &fInputDeviceID); + + // Set the current device to the default input unit. + result = AudioUnitSetProperty(d->caInAudioUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &fInputDeviceID, + sizeof(AudioDeviceID)); + + AudioStreamBasicDescription tmpASBD; + result = AudioUnitGetProperty (d->caInAudioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &tmpASBD, + &asbdsize); + + int fAudioChannels = 1; + d->caInASBD.mChannelsPerFrame = fAudioChannels; + d->caInASBD.mSampleRate = tmpASBD.mSampleRate; + d->caInASBD.mFormatID = kAudioFormatLinearPCM; + d->caInASBD.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | + kAudioFormatFlagIsNonInterleaved; + if (d->caInASBD.mFormatID == kAudioFormatLinearPCM && fAudioChannels == 1) + d->caInASBD.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + d->caInASBD.mFormatFlags = kAudioFormatFlagIsFloat; + if (htonl(0x1234) == 0x1234) + d->caInASBD.mFormatFlags |= kAudioFormatFlagIsBigEndian; + d->caInASBD.mBitsPerChannel = sizeof(Float32) * 8; + d->caInASBD.mBytesPerFrame = d->caInASBD.mBitsPerChannel / 8; + d->caInASBD.mFramesPerPacket = 1; + d->caInASBD.mBytesPerPacket = d->caInASBD.mBytesPerFrame; + + err = AudioUnitSetProperty(d->caInAudioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &d->caInASBD, + sizeof(AudioStreamBasicDescription)); + + d->caSourceBuffer=NULL; + + // Get the number of frames in the IO buffer(s) + param = sizeof(UInt32); + UInt32 fAudioSamples; + result = AudioUnitGetProperty(d->caInAudioUnit, + kAudioDevicePropertyBufferFrameSize, + kAudioUnitScope_Global, + 0, + &fAudioSamples, + ¶m); + if(err != noErr) + { + fprintf(stderr, "failed to get audio sample size\n"); + return; + } + // Allocate our low device audio buffers + d->fAudioBuffer = AllocateAudioBufferList(d->caInASBD.mChannelsPerFrame, + fAudioSamples * d->caInASBD.mBytesPerFrame); + if(d->fAudioBuffer == NULL) + { + fprintf(stderr, "failed to allocate buffers\n"); + return; + } + // Allocate our low device audio buffers + d->fMSBuffer = AllocateAudioBufferList(d->caInASBD.mChannelsPerFrame, + fAudioSamples * d->caInASBD.mBytesPerFrame); + if(d->fMSBuffer == NULL) + { + fprintf(stderr, "failed to allocate buffers\n"); + return; + } + + d->pcmdev=NULL; + d->mixdev=NULL; + d->pcmfd=-1; + d->read_started=FALSE; + d->write_started=FALSE; + d->bits=16; + d->rate=8000; + d->stereo=FALSE; + qinit(&d->rq); + d->bufferizer=ms_bufferizer_new(); + ms_mutex_init(&d->mutex,NULL); + card->data=d; +} + +static void ca_uninit(MSSndCard *card){ + CAData *d=(CAData*)card->data; + if (d->pcmdev!=NULL) ms_free(d->pcmdev); + if (d->mixdev!=NULL) ms_free(d->mixdev); + ms_bufferizer_destroy(d->bufferizer); + flushq(&d->rq,0); + ms_mutex_destroy(&d->mutex); + ms_free(d); +} + +static void ca_detect(MSSndCardManager *m); +static MSSndCard *ca_duplicate(MSSndCard *obj); + +MSSndCardDesc ca_card_desc={ + .driver_type="CA", + .detect=ca_detect, + .init=ca_init, + .set_level=ca_set_level, + .get_level=ca_get_level, + .set_capture=ca_set_source, + .create_reader=ms_ca_read_new, + .create_writer=ms_ca_write_new, + .uninit=ca_uninit, + .duplicate=ca_duplicate +}; + +static MSSndCard *ca_duplicate(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&ca_card_desc); + CAData *dcard=(CAData*)card->data; + CAData *dobj=(CAData*)obj->data; + dcard->pcmdev=ms_strdup(dobj->pcmdev); + dcard->mixdev=ms_strdup(dobj->mixdev); + card->name=ms_strdup(obj->name); + return card; +} + +static MSSndCard *ca_card_new(){ + MSSndCard *card=ms_snd_card_new(&ca_card_desc); + card->name=ms_strdup("Core Audio"); + return card; +} + +static void ca_detect(MSSndCardManager *m){ + ms_debug("ca_detect"); + MSSndCard *card=ca_card_new(); + ms_snd_card_manager_add_card(m,card); +} + +static void ca_start_r(MSSndCard *card){ + OSStatus err= noErr; + CAData *d=(CAData*)card->data; + ms_debug("ca_start_r"); + + if (d->read_started==FALSE){ + AudioStreamBasicDescription outASBD; + outASBD = d->caInASBD; + outASBD.mSampleRate = d->rate; + outASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + if (htonl(0x1234) == 0x1234) + outASBD.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; + outASBD.mBytesPerPacket = (d->bits / 8) * outASBD.mChannelsPerFrame; + outASBD.mBytesPerFrame = (d->bits / 8) * outASBD.mChannelsPerFrame; + outASBD.mFramesPerPacket = 1; + outASBD.mBitsPerChannel = d->bits; + + err = AudioConverterNew( &d->caInASBD, &outASBD, &d->caInConverter); + if(err != noErr) + ms_error("AudioConverterNew %x %d", err, outASBD.mBytesPerFrame); + else + CAShow(d->caInConverter); + + d->caInRenderCallback.inputProc = readRenderProc; + d->caInRenderCallback.inputProcRefCon = d; + err = AudioUnitSetProperty(d->caInAudioUnit, + kAudioOutputUnitProperty_SetInputCallback, + kAudioUnitScope_Global, + 0, + &d->caInRenderCallback, + sizeof(AURenderCallbackStruct)); + + if(AudioOutputUnitStart(d->caInAudioUnit) == noErr) + d->read_started = TRUE; + } +} + +static void ca_stop_r(MSSndCard *card){ + CAData *d=(CAData*)card->data; + OSErr err; + if(d->read_started == TRUE) { + if(AudioOutputUnitStop(d->caInAudioUnit) == noErr) + d->read_started=FALSE; + } +} + +static void ca_start_w(MSSndCard *card){ + OSStatus err= noErr; + ms_debug("ca_start_w"); + CAData *d=(CAData*)card->data; + if (d->write_started==FALSE){ + AudioStreamBasicDescription inASBD; + inASBD = d->caOutASBD; + inASBD.mSampleRate = d->rate; + inASBD.mFormatID = kAudioFormatLinearPCM; + // http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html + inASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + if (htonl(0x1234) == 0x1234) + inASBD.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; + inASBD.mChannelsPerFrame = d->stereo ? 2 : 1; + inASBD.mBytesPerPacket = (d->bits / 8) * inASBD.mChannelsPerFrame; + inASBD.mBytesPerFrame = (d->bits / 8) * inASBD.mChannelsPerFrame; + inASBD.mFramesPerPacket = 1; + inASBD.mBitsPerChannel = d->bits; + + + err = AudioConverterNew( &inASBD, &d->caOutASBD, &d->caOutConverter); + if(err != noErr) + ms_error("AudioConverterNew %x %d", err, inASBD.mBytesPerFrame); + else + CAShow(d->caOutConverter); + + if (inASBD.mChannelsPerFrame == 1 && d->caOutASBD.mChannelsPerFrame == 2) + { + if (d->caOutConverter) + { + // This should be as large as the number of output channels, + // each element specifies which input channel's data is routed to that output channel + SInt32 channelMap[] = { 0, 0 }; + err = AudioConverterSetProperty(d->caOutConverter, kAudioConverterChannelMap, 2*sizeof(SInt32), channelMap); + } + } + + memset((char*)&d->caOutRenderCallback, 0, sizeof(AURenderCallbackStruct)); + d->caOutRenderCallback.inputProc = writeRenderProc; + d->caOutRenderCallback.inputProcRefCon = d; + err = AudioUnitSetProperty (d->caOutAudioUnit, + kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Input, + 0, + &d->caOutRenderCallback, + sizeof(AURenderCallbackStruct)); + if(err != noErr) + ms_error("AudioUnitSetProperty %x", err); + + if(err == noErr) { + if(AudioOutputUnitStart(d->caOutAudioUnit) == noErr) + d->write_started=TRUE; + } + } +} + +static void ca_stop_w(MSSndCard *card){ + CAData *d=(CAData*)card->data; + OSErr err; + if(d->write_started == TRUE) { + if(AudioOutputUnitStop(d->caOutAudioUnit) == noErr) + d->write_started=FALSE; + } +} + +static mblk_t *ca_get(MSSndCard *card){ + CAData *d=(CAData*)card->data; + mblk_t *m; + ms_mutex_lock(&d->mutex); + m=getq(&d->rq); + ms_mutex_unlock(&d->mutex); + return m; +} + +static void ca_put(MSSndCard *card, mblk_t *m){ + CAData *d=(CAData*)card->data; + ms_mutex_lock(&d->mutex); + ms_bufferizer_put(d->bufferizer,m); + ms_mutex_unlock(&d->mutex); +} + + +static void ca_read_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + ca_start_r(card); +} + +static void ca_read_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + ca_stop_r(card); +} + +static void ca_read_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=ca_get(card))!=NULL){ + ms_queue_put(f->outputs[0],m); + } +} + +static void ca_write_preprocess(MSFilter *f){ + ms_debug("ca_write_preprocess"); + MSSndCard *card=(MSSndCard*)f->data; + ca_start_w(card); +} + +static void ca_write_postprocess(MSFilter *f){ + ms_debug("ca_write_postprocess"); + MSSndCard *card=(MSSndCard*)f->data; + ca_stop_w(card); +} + +static void ca_write_process(MSFilter *f){ +// ms_debug("ca_write_process"); + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + ca_put(card,m); + } +} + +static int set_rate(MSFilter *f, void *arg){ + ms_debug("set_rate %d", *((int*)arg)); + MSSndCard *card=(MSSndCard*)f->data; + CAData *d=(CAData*)card->data; + d->rate=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + ms_debug("set_nchannels %d", *((int*)arg)); + MSSndCard *card=(MSSndCard*)f->data; + CAData *d=(CAData*)card->data; + d->stereo=(*((int*)arg)==2); + return 0; +} + +static MSFilterMethod ca_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { 0 , NULL } +}; + +MSFilterDesc ca_read_desc={ + .id=MS_CA_READ_ID, + .name="MSCARead", + .text="Sound capture filter for MacOS X Core Audio drivers", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .preprocess=ca_read_preprocess, + .process=ca_read_process, + .postprocess=ca_read_postprocess, + .methods=ca_methods +}; + + +MSFilterDesc ca_write_desc={ + .id=MS_CA_WRITE_ID, + .name="MSCAWrite", + .text="Sound playback filter for MacOS X Core Audio drivers", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .preprocess=ca_write_preprocess, + .process=ca_write_process, + .postprocess=ca_write_postprocess, + .methods=ca_methods +}; + +MSFilter *ms_ca_read_new(MSSndCard *card){ + ms_debug("ms_ca_read_new"); + MSFilter *f=ms_filter_new_from_desc(&ca_read_desc); + f->data=card; + return f; +} + + +MSFilter *ms_ca_write_new(MSSndCard *card){ + ms_debug("ms_ca_write_new"); + MSFilter *f=ms_filter_new_from_desc(&ca_write_desc); + f->data=card; + return f; +} + +MS_FILTER_DESC_EXPORT(ca_read_desc) +MS_FILTER_DESC_EXPORT(ca_write_desc) diff --git a/linphone/mediastreamer2/src/mire.c b/linphone/mediastreamer2/src/mire.c new file mode 100644 index 000000000..eda05eb28 --- /dev/null +++ b/linphone/mediastreamer2/src/mire.c @@ -0,0 +1,164 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/mswebcam.h" + + +typedef struct _MireData{ + MSVideoSize vsize; + MSPicture pict; + int index; + uint64_t starttime; + float fps; + mblk_t *pic; +}MireData; + +void mire_init(MSFilter *f){ + MireData *d=(MireData*)ms_new(MireData,1); + d->vsize.width=MS_VIDEO_SIZE_CIF_W; + d->vsize.height=MS_VIDEO_SIZE_CIF_H; + d->fps=15; + d->index=0; + d->starttime=0; + d->pic=NULL; + f->data=d; +} + +void mire_uninit(MSFilter *f){ + ms_free(f->data); +} + +void mire_preprocess(MSFilter *f){ + MireData *d=(MireData*)f->data; + d->pic=yuv_buf_alloc(&d->pict,d->vsize.width,d->vsize.height); + memset(d->pic->b_rptr,0,d->pic->b_wptr-d->pic->b_rptr); + d->starttime=f->ticker->time; +} + +void plane_draw(uint8_t *p, int w, int h, int lsz, int index){ + int i,j; + for(i=0;ipict.planes[0],d->pict.w,d->pict.h,d->pict.strides[0],d->index*2); + plane_draw(d->pict.planes[1],d->pict.w/2,d->pict.h/2,d->pict.strides[1],d->index); + plane_draw(d->pict.planes[2],d->pict.w/2,d->pict.h/2,d->pict.strides[2],d->index); +} + +void mire_process(MSFilter *f){ + MireData *d=(MireData*)f->data; + float elapsed=f->ticker->time-d->starttime; + if ((elapsed*d->fps/1000.0)>d->index){ + mire_draw(d); + ms_queue_put(f->outputs[0],dupb(d->pic)); + d->index++; + } +} + +void mire_postprocess(MSFilter *f){ + MireData *d=(MireData*)f->data; + if (d->pic) { + freemsg(d->pic); + d->pic=NULL; + } +} + +int mire_set_vsize(MSFilter *f, void* data){ + MireData *d=(MireData*)f->data; + d->vsize=*(MSVideoSize*)data; + return 0; +} + +int mire_set_fps(MSFilter *f, void* data){ + MireData *d=(MireData*)f->data; + d->fps=*(float*)data; + return 0; +} + +int mire_get_fmt(MSFilter *f, void* data){ + *(MSPixFmt*)data=MS_YUV420P; + return 0; +} + +MSFilterMethod mire_methods[]={ + { MS_FILTER_SET_VIDEO_SIZE, mire_set_vsize }, + { MS_FILTER_SET_FPS , mire_set_fps }, + { MS_FILTER_GET_PIX_FMT , mire_get_fmt }, + { 0,0 } +}; + +MSFilterDesc ms_mire_desc={ + MS_MIRE_ID, + "MSMire", + "A filter that outputs synthetic moving picture", + MS_FILTER_OTHER, + NULL, + 0, + 1, + mire_init, + mire_preprocess, + mire_process, + mire_postprocess, + mire_uninit, + mire_methods +}; + +MS_FILTER_DESC_EXPORT(ms_mire_desc) + +static void mire_detect(MSWebCamManager *obj); + +static void mire_cam_init(MSWebCam *cam){ + cam->name=ms_strdup("Mire (synthetic moving picture)"); +} + + +static MSFilter *mire_create_reader(MSWebCam *obj){ + return ms_filter_new_from_desc(&ms_mire_desc); +} + +MSWebCamDesc mire_desc={ + "Mire", + &mire_detect, + &mire_cam_init, + &mire_create_reader, + NULL +}; + +static void mire_detect(MSWebCamManager *obj){ + char *debug=getenv("DEBUG"); + if (debug && atoi(debug)==1){ + MSWebCam *cam=ms_web_cam_new(&mire_desc); + ms_web_cam_manager_add_cam(obj,cam); + } +} + diff --git a/linphone/mediastreamer2/src/mscommon.c b/linphone/mediastreamer2/src/mscommon.c new file mode 100644 index 000000000..46d21055e --- /dev/null +++ b/linphone/mediastreamer2/src/mscommon.c @@ -0,0 +1,593 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msfilter.h" + +#include "alldescs.h" +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/mswebcam.h" + +#if !defined(_WIN32_WCE) +#include +#endif +#ifndef WIN32 +#include +#else +#ifndef PACKAGE_PLUGINS_DIR +#if defined(WIN32) || defined(_WIN32_WCE) +#define PACKAGE_PLUGINS_DIR "plugins\\" +#else +#define PACKAGE_PLUGINS_DIR "." +#endif +#endif +#endif +#ifdef HAVE_DLOPEN +#include +#endif + +#ifdef __APPLE__ +#import +#include +#endif + +MSList *ms_list_new(void *data){ + MSList *new_elem=(MSList *)ms_new(MSList,1); + new_elem->prev=new_elem->next=NULL; + new_elem->data=data; + return new_elem; +} + +MSList * ms_list_append(MSList *elem, void * data){ + MSList *new_elem=ms_list_new(data); + MSList *it=elem; + if (elem==NULL) return new_elem; + while (it->next!=NULL) it=ms_list_next(it); + it->next=new_elem; + new_elem->prev=it; + return elem; +} + +MSList * ms_list_prepend(MSList *elem, void *data){ + MSList *new_elem=ms_list_new(data); + if (elem!=NULL) { + new_elem->next=elem; + elem->prev=new_elem; + } + return new_elem; +} + + +MSList * ms_list_concat(MSList *first, MSList *second){ + MSList *it=first; + if (it==NULL) return second; + while(it->next!=NULL) it=ms_list_next(it); + it->next=second; + second->prev=it; + return first; +} + +MSList * ms_list_free(MSList *list){ + MSList *elem = list; + MSList *tmp; + if (list==NULL) return NULL; + while(elem->next!=NULL) { + tmp = elem; + elem = elem->next; + ms_free(tmp); + } + ms_free(elem); + return NULL; +} + +MSList * ms_list_remove(MSList *first, void *data){ + MSList *it; + it=ms_list_find(first,data); + if (it) return ms_list_remove_link(first,it); + else { + ms_warning("ms_list_remove: no element with %p data was in the list", data); + return first; + } +} + +int ms_list_size(const MSList *first){ + int n=0; + while(first!=NULL){ + ++n; + first=first->next; + } + return n; +} + +void ms_list_for_each(const MSList *list, void (*func)(void *)){ + for(;list!=NULL;list=list->next){ + func(list->data); + } +} + +void ms_list_for_each2(const MSList *list, void (*func)(void *, void *), void *user_data){ + for(;list!=NULL;list=list->next){ + func(list->data,user_data); + } +} + +MSList *ms_list_remove_link(MSList *list, MSList *elem){ + MSList *ret; + if (elem==list){ + ret=elem->next; + elem->prev=NULL; + elem->next=NULL; + if (ret!=NULL) ret->prev=NULL; + ms_free(elem); + return ret; + } + elem->prev->next=elem->next; + if (elem->next!=NULL) elem->next->prev=elem->prev; + elem->next=NULL; + elem->prev=NULL; + ms_free(elem); + return list; +} + +MSList *ms_list_find(MSList *list, void *data){ + for(;list!=NULL;list=list->next){ + if (list->data==data) return list; + } + return NULL; +} + +MSList *ms_list_find_custom(MSList *list, int (*compare_func)(const void *, const void*), void *user_data){ + for(;list!=NULL;list=list->next){ + if (compare_func(list->data,user_data)==0) return list; + } + return NULL; +} + +void * ms_list_nth_data(const MSList *list, int index){ + int i; + for(i=0;list!=NULL;list=list->next,++i){ + if (i==index) return list->data; + } + ms_error("ms_list_nth_data: no such index in list."); + return NULL; +} + +int ms_list_position(const MSList *list, MSList *elem){ + int i; + for(i=0;list!=NULL;list=list->next,++i){ + if (elem==list) return i; + } + ms_error("ms_list_position: no such element in list."); + return -1; +} + +int ms_list_index(const MSList *list, void *data){ + int i; + for(i=0;list!=NULL;list=list->next,++i){ + if (data==list->data) return i; + } + ms_error("ms_list_index: no such element in list."); + return -1; +} + +MSList *ms_list_insert_sorted(MSList *list, void *data, int (*compare_func)(const void *, const void*)){ + MSList *it,*previt=NULL; + MSList *nelem; + MSList *ret=list; + if (list==NULL) return ms_list_append(list,data); + else{ + nelem=ms_list_new(data); + for(it=list;it!=NULL;it=it->next){ + previt=it; + if (compare_func(data,it->data)<=0){ + nelem->prev=it->prev; + nelem->next=it; + if (it->prev!=NULL) + it->prev->next=nelem; + else{ + ret=nelem; + } + it->prev=nelem; + return ret; + } + } + previt->next=nelem; + nelem->prev=previt; + } + return ret; +} + +MSList *ms_list_insert(MSList *list, MSList *before, void *data){ + MSList *elem; + if (list==NULL || before==NULL) return ms_list_append(list,data); + for(elem=list;elem!=NULL;elem=ms_list_next(elem)){ + if (elem==before){ + if (elem->prev==NULL) + return ms_list_prepend(list,data); + else{ + MSList *nelem=ms_list_new(data); + nelem->prev=elem->prev; + nelem->next=elem; + elem->prev->next=nelem; + elem->prev=nelem; + } + } + } + return list; +} + +MSList *ms_list_copy(const MSList *list){ + MSList *copy=NULL; + const MSList *iter; + for(iter=list;iter!=NULL;iter=ms_list_next(iter)){ + copy=ms_list_append(copy,iter->data); + } + return copy; +} + + +#ifdef __APPLE__ +#define PLUGINS_EXT ".dylib" +#else +#define PLUGINS_EXT ".so" +#endif + +typedef void (*init_func_t)(void); + +int ms_load_plugins(const char *dir){ + int num=0; +#if defined(WIN32) && !defined(_WIN32_WCE) + WIN32_FIND_DATA FileData; + HANDLE hSearch; + char szDirPath[1024]; + char szPluginFile[1024]; + BOOL fFinished = FALSE; + + snprintf(szDirPath, sizeof(szDirPath), "%s", dir); + // Create a new directory. +#if 0 + if (!CreateDirectory(szDirPath, NULL)) + { + ms_message("plugins directory already exist (%s).", szDirPath); + } +#endif + + // Start searching for .TXT files in the current directory. + + snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir); + hSearch = FindFirstFile(szDirPath, &FileData); + if (hSearch == INVALID_HANDLE_VALUE) + { + ms_message("no plugin (*.dll) found in %s.", szDirPath); + return 0; + } + snprintf(szDirPath, sizeof(szDirPath), "%s", dir); + + while (!fFinished) + { + /* load library */ + HINSTANCE os_handle; + UINT em; + em = SetErrorMode (SEM_FAILCRITICALERRORS); + + snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName); + os_handle = LoadLibraryEx (szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (os_handle==NULL) + { + os_handle = LoadLibraryEx (szPluginFile, NULL, 0); + } + SetErrorMode (em); + if (os_handle==NULL) + ms_warning("Fail to load plugin %s :", szPluginFile); + else + { + init_func_t initroutine; + char szPluginName[256]; + char szMethodName[256]; + snprintf(szPluginName, 256, "%s", FileData.cFileName); + szPluginName[strlen(szPluginName)-4]='\0'; + snprintf(szMethodName, 256, "%s_init", szPluginName); + initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName); + if (initroutine!=NULL){ + initroutine(); + ms_message("Plugin loaded."); + num++; + }else{ + ms_warning("Could not locate init routine of plugin %s", szPluginFile); + } + } + + + if (!FindNextFile(hSearch, &FileData)) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + { + fFinished = TRUE; + } + else + { + ms_error("couldn't find next plugin dll."); + fFinished = TRUE; + } + } + } + + // Close the search handle. + + FindClose(hSearch); + +#elif HAVE_DLOPEN + DIR *ds; + struct dirent *de; + char *fullpath; + ds=opendir(dir); + if (ds==NULL){ + ms_message("Cannot open directory %s: %s",dir,strerror(errno)); + return -1; + } + while( (de=readdir(ds))!=NULL){ + if (de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL){ + void *handle; + fullpath=ms_strdup_printf("%s/%s",dir,de->d_name); + ms_message("Loading plugin %s...",fullpath); + + if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ + ms_warning("Fail to load plugin %s : %s",fullpath,dlerror()); + }else { + char *initroutine_name=ms_malloc0(strlen(de->d_name)+10); + char *p; + void *initroutine=NULL; + strcpy(initroutine_name,de->d_name); + p=strstr(initroutine_name,PLUGINS_EXT); + if (p!=NULL) + { + strcpy(p,"_init"); + initroutine=dlsym(handle,initroutine_name); + } + +#ifdef __APPLE__ + if (initroutine==NULL){ + /* on macosx: library name are libxxxx.1.2.3.dylib */ + /* -> MUST remove the .1.2.3 */ + p=strstr(initroutine_name,"."); + if (p!=NULL) + { + strcpy(p,"_init"); + initroutine=dlsym(handle,initroutine_name); + } + } +#endif + + if (initroutine!=NULL){ + init_func_t func=(init_func_t)initroutine; + func(); + ms_message("Plugin loaded."); + num++; + }else{ + ms_warning("Could not locate init routine of plugin %s",de->d_name); + } + ms_free(initroutine_name); + } + ms_free(fullpath); + } + } + closedir(ds); +#else + ms_warning("no loadable plugin support: plugins cannot be loaded."); + num=-1; +#endif + return num; +} + + +#ifdef __ALSA_ENABLED__ +extern MSSndCardDesc alsa_card_desc; +#endif + +#ifdef HAVE_SYS_SOUNDCARD_H +extern MSSndCardDesc oss_card_desc; +#endif + +#ifdef __ARTS_ENABLED__ +extern MSSndCardDesc arts_card_desc; +#endif + +#ifdef WIN32 +extern MSSndCardDesc winsnd_card_desc; +#endif + +#ifdef __DIRECTSOUND_ENABLED__ +extern MSSndCardDesc winsndds_card_desc; +#endif + +#ifdef __MACSND_ENABLED__ +extern MSSndCardDesc ca_card_desc; +#endif + +#ifdef __PORTAUDIO_ENABLED__ +extern MSSndCardDesc pasnd_card_desc; +#endif + +#ifdef __MAC_AQ_ENABLED__ +extern MSSndCardDesc aq_card_desc; +#endif + +static MSSndCardDesc * ms_snd_card_descs[]={ +#ifdef __ALSA_ENABLED__ + &alsa_card_desc, +#endif +#ifdef HAVE_SYS_SOUNDCARD_H + &oss_card_desc, +#endif +#ifdef __ARTS_ENABLED__ + &arts_card_desc, +#endif +#ifdef WIN32 + &winsnd_card_desc, +#endif +#ifdef __DIRECTSOUND_ENABLED__ + &winsndds_card_desc, +#endif +#ifdef __PORTAUDIO_ENABLED__ + &pasnd_card_desc, +#endif +#ifdef __MACSND_ENABLED__ + &ca_card_desc, +#endif +#ifdef __MAC_AQ_ENABLED__ + &aq_card_desc, +#endif + NULL +}; + +#ifdef VIDEO_ENABLED + +#ifdef __linux +extern MSWebCamDesc v4l_desc; +#endif + +#ifdef HAVE_LINUX_VIDEODEV2_H +extern MSWebCamDesc v4l2_desc; +#endif + +#ifdef WIN32 +extern MSWebCamDesc ms_v4w_cam_desc; +#endif + +extern MSWebCamDesc static_image_desc; +extern MSWebCamDesc mire_desc; + +static MSWebCamDesc * ms_web_cam_descs[]={ +#ifdef HAVE_LINUX_VIDEODEV2_H + &v4l2_desc, +#endif +#ifdef __linux + &v4l_desc, +#endif +#ifdef WIN32 + &ms_v4w_cam_desc, +#endif + &mire_desc, + &static_image_desc, + NULL +}; + +#endif + +void ms_init(){ + int i; + MSSndCardManager *cm; +#ifdef __APPLE__ + NSApplicationLoad(); +#endif + +#if !defined(_WIN32_WCE) + if (getenv("MEDIASTREAMER_DEBUG")!=NULL){ + ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + } +#endif + ms_message("Registering all filters..."); + /* register builtin MSFilter's */ + for (i=0;ms_filter_descs[i]!=NULL;i++){ + ms_filter_register(ms_filter_descs[i]); + } + ms_message("Registering all soundcard handlers"); + cm=ms_snd_card_manager_get(); + for (i=0;ms_snd_card_descs[i]!=NULL;i++){ + ms_snd_card_manager_register_desc(cm,ms_snd_card_descs[i]); + } + +#ifdef VIDEO_ENABLED + ms_message("Registering all webcam handlers"); + { + MSWebCamManager *wm; + wm=ms_web_cam_manager_get(); + for (i=0;ms_web_cam_descs[i]!=NULL;i++){ + ms_web_cam_manager_register_desc(wm,ms_web_cam_descs[i]); + } + } +#endif + ms_message("Loading plugins"); + ms_load_plugins(PACKAGE_PLUGINS_DIR); + ms_message("ms_init() done"); +} + +void ms_exit(){ + ms_filter_unregister_all(); + ms_snd_card_manager_destroy(); +#ifdef VIDEO_ENABLED + ms_web_cam_manager_destroy(); +#endif +} + +void ms_reload_snd_card(MSSndCardDesc *snd_desc){ + MSSndCardManager *cm; + int i; + + ms_snd_card_manager_destroy(); + + ms_message("Registering all soundcard handlers"); + if (snd_desc!=NULL) + { + cm=ms_snd_card_manager_get(); + if (cm!=NULL) + ms_snd_card_manager_register_desc(cm,snd_desc); + return; + } + + /*register SndCardDesc */ + cm=ms_snd_card_manager_get(); + for (i=0;ms_snd_card_descs[i]!=NULL;i++){ + ms_snd_card_manager_register_desc(cm,ms_snd_card_descs[i]); + } + + return; +} + +void ms_sleep(int seconds){ +#ifdef WIN32 + Sleep(seconds*1000); +#else + struct timespec ts,rem; + int err; + ts.tv_sec=seconds; + ts.tv_nsec=0; + do { + err=nanosleep(&ts,&rem); + ts=rem; + }while(err==-1 && errno==EINTR); +#endif +} + +#define DEFAULT_MAX_PAYLOAD_SIZE 1440 + +static int max_payload_size=DEFAULT_MAX_PAYLOAD_SIZE; + +int ms_get_payload_max_size(){ + return max_payload_size; +} + +void ms_set_payload_max_size(int size){ + if (size<=0) size=DEFAULT_MAX_PAYLOAD_SIZE; + max_payload_size=size; +} diff --git a/linphone/mediastreamer2/src/msconf.c b/linphone/mediastreamer2/src/msconf.c new file mode 100644 index 000000000..80113ae78 --- /dev/null +++ b/linphone/mediastreamer2/src/msconf.c @@ -0,0 +1,590 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" + +#if defined(_WIN32_WCE) +#define DISABLE_SPEEX +#endif + +#ifndef DISABLE_SPEEX +#include +#endif + +#ifndef CONF_GRAN_MAX +#define CONF_GRAN_MAX 12 /* limit for 'too much data' */ +#endif + +//#ifndef CONF_GRAN +//#define CONF_GRAN (160*4) +//#endif +#define CONF_NSAMPLES 160*4*4 /* (CONF_GRAN/2) */ +#ifndef CONF_MAX_PINS +#define CONF_MAX_PINS 32 +#endif + +typedef struct Channel{ + MSBufferizer buff; + int16_t input[CONF_NSAMPLES]; + bool_t has_contributed; + bool_t is_used; + int count; + int missed; + + int stat_discarded; + int stat_missed; + int stat_processed; + +#ifndef DISABLE_SPEEX + SpeexPreprocessState *speex_pp; +#endif + +} Channel; + +typedef struct ConfState{ + Channel channels[CONF_MAX_PINS]; + int sum[CONF_NSAMPLES]; + int enable_directmode; + int enable_vad; + int agc_level; + int mix_mode; + int samplerate; + + int adaptative_msconf_buf; + int conf_gran; + int conf_nsamples; +} ConfState; + + +static void channel_init(ConfState *s, Channel *chan, int pos){ + ms_bufferizer_init(&chan->buff); +#ifndef DISABLE_SPEEX + //chan->speex_pp = speex_preprocess_state_init((s->conf_gran/2) *(s->samplerate/8000), s->samplerate); + chan->speex_pp = speex_preprocess_state_init(s->conf_gran/2, s->samplerate); + if (chan->speex_pp!=NULL) { + float f; + int val; + val=1; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DENOISE, &val); + /* enable VAD only on incoming RTP stream */ + if (pos%2==1) + { + val=1; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_VAD, &val); + } + /* enable AGC only on local soundcard */ + if (s->agc_level>0 && pos==0) + { + val=1; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_AGC, &val); + f=s->agc_level; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); +#if 0 + val=40; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &val); +#endif + } + else + { + val=0; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_AGC, &val); + f=8000; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); + } + val=0; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB, &val); + f=.4; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=.3; + speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + } +#endif +} + +static void channel_uninit(Channel *chan){ + ms_bufferizer_uninit(&chan->buff); +#ifndef DISABLE_SPEEX + if (chan->speex_pp!=NULL) + speex_preprocess_state_destroy(chan->speex_pp); + chan->speex_pp=NULL; +#endif +} + +static void conf_init(MSFilter *f){ + ConfState *s=(ConfState *)ms_new0(ConfState,1); + int i; + s->samplerate=8000; + s->conf_gran=((16 * s->samplerate) / 800) *2; + s->conf_nsamples=s->conf_gran/2; + for (i=0;ichannels[i], i); + s->enable_directmode=FALSE; + s->enable_vad=TRUE; + s->agc_level=0; + s->mix_mode=TRUE; + s->adaptative_msconf_buf=2; + f->data=s; +} + +static void conf_uninit(MSFilter *f){ + ConfState *s=(ConfState*)f->data; + int i; + for (i=0;ichannels[i]); + ms_free(f->data); +} + +static void conf_preprocess(MSFilter *f){ + ConfState *s=(ConfState*)f->data; + int i; + for (i=0;ichannels[i].is_used=FALSE; + s->channels[i].missed=0; + s->channels[i].stat_discarded=0; + s->channels[i].stat_missed=0; + s->channels[i].stat_processed=0; + } +} + +static bool_t should_process(MSFilter *f, ConfState *s){ + Channel *chan; + int active_channel=0; + int i; + + if (ms_bufferizer_get_avail(&(&s->channels[0])->buff)>s->conf_gran + && s->channels[0].is_used==FALSE) + { + /* soundread has just started */ + s->channels[0].is_used=TRUE; + } + else if (s->channels[0].is_used==FALSE) + { + return FALSE; + } + + /* count active channel */ + for (i=1;ichannels[i]; + if (chan->is_used == TRUE) + { + active_channel++; + } + } + + if (active_channel<=1) /* disable mix mode when it's not needed */ + s->mix_mode = FALSE; + else + s->mix_mode = TRUE; + + if (s->enable_directmode==FALSE) + { + s->mix_mode = TRUE; + } + + if (s->mix_mode == FALSE) + return FALSE; + + if (ms_bufferizer_get_avail(&(&s->channels[0])->buff)>=s->conf_gran) + { + return TRUE; + } + return FALSE; +} + +static void conf_sum(ConfState *s){ + int i,j; + Channel *chan; + memset(s->sum,0,s->conf_nsamples*sizeof(int)); + + chan=&s->channels[0]; + if (s->adaptative_msconf_buf*s->conf_granbuff)) + { + i = ms_bufferizer_get_avail(&chan->buff)/s->conf_gran; + if (i>5) + ms_message("Increasing buffer because sound card is late. (nb_buf=%i /old=%i)", i, s->adaptative_msconf_buf); + s->adaptative_msconf_buf=i; + if (s->adaptative_msconf_buf>10) + { + while (ms_bufferizer_get_avail(&chan->buff)> s->conf_gran*6) + { + ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran); + ms_message("Deleting extra sound card data %i", ms_bufferizer_get_avail(&chan->buff)); + } + } + } + else if (s->adaptative_msconf_buf*s->conf_gran>ms_bufferizer_get_avail(&chan->buff)) + { + if (s->adaptative_msconf_buf>3) + { + s->adaptative_msconf_buf--; + s->adaptative_msconf_buf=ms_bufferizer_get_avail(&chan->buff)/s->conf_gran; + //ms_message("decreasing buffer because sound card is in advance. (nb_buf=%i)", s->adaptative_msconf_buf); + } + } + + if (s->adaptative_msconf_buf>6) + s->adaptative_msconf_buf=6; + + for (i=0;ichannels[i]; + + /* skip soundread and short buffer entry */ +#if 0 + if (i>0 + && ms_bufferizer_get_avail(&chan->buff)>=s->conf_gran*s->adaptative_msconf_buf) + { + while (ms_bufferizer_get_avail(&chan->buff)>=s->conf_gran*2) +#endif + if (i>0 + && ms_bufferizer_get_avail(&chan->buff)> s->conf_gran + && ms_bufferizer_get_avail(&chan->buff)> (ms_bufferizer_get_avail(&s->channels[0].buff)+s->conf_gran*6) ) + { + while (ms_bufferizer_get_avail(&chan->buff)> (ms_bufferizer_get_avail(&s->channels[0].buff)) ) + { + ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran); + /* we want to remove 4 packets (40ms) in a near future: */ +#ifndef DISABLE_SPEEX + if (chan->speex_pp!=NULL && s->enable_vad==TRUE) + { + int vad; + vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); + if (vad==1) + break; /* voice detected: process as usual */ + if (ms_bufferizer_get_avail(&chan->buff)conf_gran) + break; /* no more data to remove */ + ms_message("No voice detected: discarding sample. (idx=%i - bufsize=%i sncardbufsize=%i)", + i, ms_bufferizer_get_avail(&chan->buff), ms_bufferizer_get_avail(&s->channels[0].buff)); + } + if (ms_bufferizer_get_avail(&chan->buff) == (ms_bufferizer_get_avail(&s->channels[0].buff))) + ms_message("same data in soundcard and incoming rtp. (idx=%i - bufsize=%i sncardbufsize=%i)", + i, ms_bufferizer_get_avail(&chan->buff), ms_bufferizer_get_avail(&s->channels[0].buff)); +#endif + chan->stat_discarded++; + } + + for(j=0;jconf_nsamples;++j){ + s->sum[j]+=chan->input[j]; + } + chan->has_contributed=TRUE; + chan->stat_processed++; + } + else if (ms_bufferizer_get_avail(&chan->buff)>=s->conf_gran) + { + ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran); +#ifndef DISABLE_SPEEX + if (chan->speex_pp!=NULL && s->enable_vad==TRUE) + { + int vad; + vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); + } +#endif + + for(j=0;jconf_nsamples;++j){ + s->sum[j]+=chan->input[j]; + } + chan->has_contributed=TRUE; + chan->stat_processed++; + } else { + chan->stat_missed++; + if (i>0 && chan->is_used == TRUE) + { + chan->missed++; + /* delete stream if data is missing since a long time */ + if (chan->missed>15) + { + chan->is_used=FALSE; + ms_message("msconf: deleted contributing stream (pin=%i)", i); + } + /* couldn't we add confort noise for those outputs? */ + } + chan->has_contributed=FALSE; + } + } + return; +} + +static inline int16_t saturate(int sample){ + if (sample>32000) + sample=32000; + else if (sample<-32000) + sample=-32000; + return (int16_t)sample; +} + +static mblk_t * conf_output(ConfState *s, Channel *chan){ + mblk_t *m=allocb(s->conf_gran,0); + int i; + int tmp; + if (chan->has_contributed==TRUE){ + for (i=0;iconf_nsamples;++i){ + tmp=s->sum[i]-(int)chan->input[i]; + *((int16_t*)m->b_wptr)=saturate(tmp); + m->b_wptr+=2; + } + }else{ + for (i=0;iconf_nsamples;++i){ + tmp=s->sum[i]; + *((int16_t*)m->b_wptr)=saturate(tmp); + m->b_wptr+=2; + } + } + return m; +} + +static void conf_dispatch(MSFilter *f, ConfState *s){ + int i; + Channel *chan; + mblk_t *m; + //memset(s->sum,0,s->conf_nsamples*sizeof(int)); + for (i=0;ioutputs[i]!=NULL){ + chan=&s->channels[i]; + m=conf_output(s,chan); + ms_queue_put(f->outputs[i],m); + } + } +} + +static void conf_process(MSFilter *f){ + int i; + ConfState *s=(ConfState*)f->data; + Channel *chan; + Channel *chan0; + /*read from all inputs and put into bufferizers*/ + for (i=0;iinputs[i]!=NULL){ + chan=&s->channels[i]; + ms_bufferizer_put_from_queue(&chan->buff,f->inputs[i]); + if (ms_bufferizer_get_avail(&chan->buff)>0) + { + chan->missed=0; /* reset counter of missed packet */ + if (i>0 && chan->is_used==FALSE) + { + chan->is_used=TRUE; + ms_message("msconf: new contributing stream", ms_bufferizer_get_avail(&chan->buff)); + } + } + } + } + + /*do the job */ + while(should_process(f,s)==TRUE){ + conf_sum(s); + conf_dispatch(f,s); + } + + /* mixer is disabled! -> copy A->B and B->A*/ + if (s->mix_mode == FALSE) + { + /* get the soundread data and copy it to pinX */ + for (i=1;iinputs[i]!=NULL){ + chan0=&s->channels[0]; + chan=&s->channels[i]; + if (chan->is_used==TRUE) + { + while (ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran)==s->conf_gran) + { + if (f->outputs[0]!=NULL) + { + /* send in pin0 */ + mblk_t *m=allocb(s->conf_gran,0); + memcpy(m->b_wptr, chan->input, s->conf_gran); + m->b_wptr+=s->conf_gran; + ms_queue_put(f->outputs[0],m); + } + } + } + + if (chan0->is_used==TRUE) + { + while (ms_bufferizer_read(&chan0->buff,(uint8_t*)chan0->input,s->conf_gran)==s->conf_gran) + { + if (f->outputs[i]!=NULL) + { + /* send in pinI */ + mblk_t *m=allocb(s->conf_gran,0); + memcpy(m->b_wptr, chan0->input, s->conf_gran); + m->b_wptr+=s->conf_gran; + ms_queue_put(f->outputs[i],m); + } + } + } + break; + } + } + } + +} + +static void conf_postprocess(MSFilter *f){ + int i; + ConfState *s=(ConfState*)f->data; + Channel *chan; + /*read from all inputs and put into bufferizers*/ + for (i=0;iinputs[i]!=NULL){ + chan=&s->channels[i]; + ms_bufferizer_uninit(&chan->buff); + ms_bufferizer_init(&chan->buff); + } + } +} +static int msconf_set_sr(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + int i; + + s->samplerate = *(int*)arg; + s->conf_gran = ((16 * s->samplerate) / 800) *2; + s->conf_nsamples=s->conf_gran/2; + for (i=0;ichannels[i]); + for (i=0;ichannels[i], i); + return 0; +} + +static int msconf_enable_directmode(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + s->enable_directmode = *(int*)arg; + return 0; +} + +static int msconf_enable_agc(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + int i; + s->agc_level = *(int*)arg; + + for (i=0;ichannels[i]); + for (i=0;ichannels[i], i); + return 0; +} + +static int msconf_enable_vad(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + int i; + s->enable_vad = *(int*)arg; + + for (i=0;ichannels[i]); + for (i=0;ichannels[i], i); + return 0; +} + +static int msconf_get_stat_discarded(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + Channel *chan; + int i; + i = *(int*)arg; + /*read from all inputs and put into bufferizers*/ + if (i<0 || i>CONF_MAX_PINS) + return -1; + + if (f->inputs[i]!=NULL){ + chan=&s->channels[i]; + return chan->stat_discarded; + } + return -1; +} + +static int msconf_get_stat_missed(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + Channel *chan; + int i; + i = *(int*)arg; + /*read from all inputs and put into bufferizers*/ + if (i<0 || i>CONF_MAX_PINS) + return -1; + + if (f->inputs[i]!=NULL){ + chan=&s->channels[i]; + return chan->stat_missed; + } + return -1; +} + +static int msconf_get_stat_processed(MSFilter *f, void *arg){ + ConfState *s=(ConfState*)f->data; + Channel *chan; + int i; + i = *(int*)arg; + /*read from all inputs and put into bufferizers*/ + if (i<0 || i>CONF_MAX_PINS) + return -1; + + if (f->inputs[i]!=NULL){ + chan=&s->channels[i]; + return chan->stat_processed; + } + return -1; +} + +static MSFilterMethod msconf_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE, msconf_set_sr }, + { MS_FILTER_ENABLE_DIRECTMODE, msconf_enable_directmode }, + { MS_FILTER_ENABLE_VAD, msconf_enable_vad }, + { MS_FILTER_ENABLE_AGC, msconf_enable_agc }, + { MS_FILTER_GET_STAT_DISCARDED, msconf_get_stat_discarded }, + { MS_FILTER_GET_STAT_MISSED, msconf_get_stat_missed }, + { MS_FILTER_GET_STAT_OUTPUT, msconf_get_stat_processed }, + { 0 , NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_conf_desc={ + MS_CONF_ID, + "MSConf", + "A filter to make conferencing", + MS_FILTER_OTHER, + NULL, + CONF_MAX_PINS, + CONF_MAX_PINS, + conf_init, + conf_preprocess, + conf_process, + conf_postprocess, + conf_uninit, + msconf_methods +}; + +#else + +MSFilterDesc ms_conf_desc={ + .id=MS_CONF_ID, + .name="MSConf", + .text="A filter to make conferencing", + .category=MS_FILTER_OTHER, + .ninputs=CONF_MAX_PINS, + .noutputs=CONF_MAX_PINS, + .init=conf_init, + .preprocess=conf_preprocess, + .process=conf_process, + .postprocess=conf_postprocess, + .uninit=conf_uninit, + .methods=msconf_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_conf_desc) diff --git a/linphone/mediastreamer2/src/msfileplayer.c b/linphone/mediastreamer2/src/msfileplayer.c new file mode 100644 index 000000000..c166e5db4 --- /dev/null +++ b/linphone/mediastreamer2/src/msfileplayer.c @@ -0,0 +1,304 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfileplayer.h" +#include "mediastreamer2/waveheader.h" +#include "mediastreamer2/msticker.h" + + +static int player_close(MSFilter *f, void *arg); + +typedef enum { + CLOSED, + STARTED, + STOPPED +} PlayerState; + +struct _PlayerData{ + int fd; + PlayerState state; + int rate; + int nchannels; + int hsize; + int loop_after; + int pause_time; + bool_t swap; +}; + +typedef struct _PlayerData PlayerData; + +static void player_init(MSFilter *f){ + PlayerData *d=ms_new(PlayerData,1); + d->fd=-1; + d->state=CLOSED; + d->swap=FALSE; + d->rate=8000; + d->nchannels=1; + d->hsize=0; + d->loop_after=-1; /*by default, don't loop*/ + d->pause_time=0; + f->data=d; +} + +static int read_wav_header(PlayerData *d){ + + char header1[sizeof(riff_t)]; + char header2[sizeof(format_t)]; + char header3[sizeof(data_t)]; + int count; + + riff_t *riff_chunk=(riff_t*)header1; + format_t *format_chunk=(format_t*)header2; + data_t *data_chunk=(data_t*)header3; + + unsigned long len=0; + + len = read(d->fd, header1, sizeof(header1)) ; + if (len != sizeof(header1)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + + if (0!=strncmp(riff_chunk->riff, "RIFF", 4) || 0!=strncmp(riff_chunk->wave, "WAVE", 4)){ + ms_warning("Wrong wav header (not RIFF/WAV)"); + return -1; + } + + len = read(d->fd, header2, sizeof(header2)) ; + if (len != sizeof(header2)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + + d->rate=le_uint32(format_chunk->rate); + d->nchannels=le_uint16(format_chunk->channel); + + if (format_chunk->len-0x10>0) + { + lseek(d->fd,(format_chunk->len-0x10),SEEK_CUR); + } + + d->hsize=sizeof(wave_header_t)-0x10+format_chunk->len; + + len = read(d->fd, header3, sizeof(header3)) ; + if (len != sizeof(header3)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + count=0; + while (strncmp(data_chunk->data, "data", 4)!=0 && count<30) + { + ms_warning("skipping chunk=%s len=%i", data_chunk->data, data_chunk->len); + lseek(d->fd,data_chunk->len,SEEK_CUR); + count++; + d->hsize=d->hsize+len+data_chunk->len; + + len = read(d->fd, header3, sizeof(header3)) ; + if (len != sizeof(header3)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + } +#ifdef WORDS_BIGENDIAN + if (le_uint16(format_chunk->blockalign)==le_uint16(format_chunk->channel) * 2) + d->swap=TRUE; +#endif + return 0; +} + +static int player_open(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + int fd; + const char *file=(const char*)arg; + + if (d->fd>=0){ + player_close(f,NULL); + } + if ((fd=open(file,O_RDONLY))==-1){ + ms_warning("Failed to open %s",file); + return -1; + } + d->state=STOPPED; + d->fd=fd; + if (strstr(file,".wav")!=NULL) read_wav_header(d); + ms_message("%s opened: rate=%i,channel=%i",file,d->rate,d->nchannels); + return 0; +} + +static int player_start(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->state==STOPPED) + d->state=STARTED; + return 0; +} + +static int player_stop(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + ms_filter_lock(f); + if (d->state==STARTED){ + d->state=STOPPED; + lseek(d->fd,d->hsize,SEEK_SET); + } + ms_filter_unlock(f); + return 0; +} + +static int player_close(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + player_stop(f,NULL); + if (d->fd>=0) close(d->fd); + d->fd=-1; + d->state=CLOSED; + return 0; +} + +static void player_uninit(MSFilter *f){ + PlayerData *d=(PlayerData*)f->data; + if (d->fd>=0) player_close(f,NULL); + ms_free(d); +} + +static void swap_bytes(unsigned char *bytes, int len){ + int i; + unsigned char tmp; + for(i=0;idata; + int bytes=2*(f->ticker->interval*d->rate*d->nchannels)/1000; + ms_filter_lock(f); + if (d->state==STARTED){ + int err; + mblk_t *om=allocb(bytes,0); + if (d->pause_time>0){ + err=bytes; + memset(om->b_wptr,0,bytes); + d->pause_time-=f->ticker->interval; + }else{ + err=read(d->fd,om->b_wptr,bytes); + if (d->swap) swap_bytes(om->b_wptr,bytes); + } + if (err>=0){ + if (err!=0){ + om->b_wptr+=bytes; + ms_queue_put(f->outputs[0],om); + }else freemsg(om); + if (errfd,d->hsize,SEEK_SET); + + /* special value for playing file only once */ + if (d->loop_after==-2) + { + d->state=STOPPED; + ms_filter_unlock(f); + return; + } + + if (d->loop_after>=0){ + d->pause_time=d->loop_after; + } + } + }else{ + ms_warning("Fail to read %i bytes: %s",bytes,strerror(errno)); + } + } + ms_filter_unlock(f); +} + +static int player_get_sr(MSFilter *f, void*arg){ + PlayerData *d=(PlayerData*)f->data; + *((int*)arg)=d->rate; + return 0; +} + +static int player_loop(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + d->loop_after=*((int*)arg); + return 0; +} + +static int player_eof(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->fd<0 && d->state==CLOSED) + *((int*)arg) = TRUE; /* 1 */ + else + *((int*)arg) = FALSE; /* 0 */ + return 0; +} + +static int player_get_nch(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + *((int*)arg)=d->nchannels; + return 0; +} + +static MSFilterMethod player_methods[]={ + { MS_FILE_PLAYER_OPEN, player_open }, + { MS_FILE_PLAYER_START, player_start }, + { MS_FILE_PLAYER_STOP, player_stop }, + { MS_FILE_PLAYER_CLOSE, player_close }, + { MS_FILTER_GET_SAMPLE_RATE, player_get_sr}, + { MS_FILTER_GET_NCHANNELS, player_get_nch }, + { MS_FILE_PLAYER_LOOP, player_loop }, + { MS_FILE_PLAYER_DONE, player_eof }, + { 0, NULL } +}; + +#ifdef WIN32 + +MSFilterDesc ms_file_player_desc={ + MS_FILE_PLAYER_ID, + "MSFilePlayer", + "Raw files and wav reader", + MS_FILTER_OTHER, + NULL, + 0, + 1, + player_init, + NULL, + player_process, + NULL, + player_uninit, + player_methods +}; + +#else + +MSFilterDesc ms_file_player_desc={ + .id=MS_FILE_PLAYER_ID, + .name="MSFilePlayer", + .text="Raw files and wav reader", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .init=player_init, + .process=player_process, + .uninit=player_uninit, + .methods=player_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_file_player_desc) diff --git a/linphone/mediastreamer2/src/msfileplayer_win.c b/linphone/mediastreamer2/src/msfileplayer_win.c new file mode 100644 index 000000000..5331802a9 --- /dev/null +++ b/linphone/mediastreamer2/src/msfileplayer_win.c @@ -0,0 +1,369 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfileplayer.h" +#include "mediastreamer2/waveheader.h" +#include "mediastreamer2/msticker.h" + + +typedef enum { + CLOSED, + STARTED, + STOPPED +} PlayerState; + +struct _PlayerData{ + HANDLE fd; + PlayerState state; + int rate; + int nchannels; + int hsize; + int loop_after; + int pause_time; + bool_t swap; + + int stat; + int big_buffer; /* ouput less & bigger buffer. (default => no change) */ +}; + +typedef struct _PlayerData PlayerData; + +static void player_init(MSFilter *f){ + PlayerData *d=(PlayerData *)ms_new(PlayerData,1); + d->fd=INVALID_HANDLE_VALUE; + d->state=CLOSED; + d->swap=FALSE; + d->rate=8000; + d->nchannels=1; + d->hsize=0; + d->loop_after=-1; + d->pause_time=0; + d->stat=-1; + d->big_buffer=1; + f->data=d; +} + +static int read_wav_header(PlayerData *d){ + + char header1[sizeof(riff_t)]; + char header2[sizeof(format_t)]; + char header3[sizeof(data_t)]; + int count; + + riff_t *riff_chunk=(riff_t*)header1; + format_t *format_chunk=(format_t*)header2; + data_t *data_chunk=(data_t*)header3; + + unsigned long len=0; + BOOL res; + + res = ReadFile(d->fd, header1, sizeof(header1), &len, NULL) ; + if (!res || len != sizeof(header1)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + + if (0!=strncmp(riff_chunk->riff, "RIFF", 4) || 0!=strncmp(riff_chunk->wave, "WAVE", 4)){ + ms_warning("Wrong wav header (not RIFF/WAV)"); + return -1; + } + + res = ReadFile(d->fd, header2, sizeof(header2), &len, NULL) ; + if (!res || len != sizeof(header2)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + + d->rate=le_uint32(format_chunk->rate); + d->nchannels=le_uint16(format_chunk->channel); + + if (format_chunk->len-0x10>0) + { + SetFilePointer(d->fd, (format_chunk->len-0x10), NULL, FILE_CURRENT); + } + + d->hsize=sizeof(wave_header_t)-0x10+format_chunk->len; + + res = ReadFile(d->fd, header3, sizeof(header3), &len, NULL) ; + if (!res || len != sizeof(header3)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + count=0; + while (strncmp(data_chunk->data, "data", 4)!=0 && count<30) + { + SetFilePointer(d->fd, data_chunk->len, NULL, FILE_CURRENT); + count++; + d->hsize=d->hsize+len+data_chunk->len; + + res = ReadFile(d->fd, header3, sizeof(header3), &len, NULL) ; + if (!res || len != sizeof(header3)){ + ms_warning("Wrong wav header: cannot read file"); + return -1; + } + } +#ifdef WORDS_BIGENDIAN + d->swap=TRUE; +#endif + return 0; +} + +static int player_open(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + HANDLE fd; + const char *file=(const char*)arg; +#if defined(_WIN32_WCE) + fd = CreateFile((LPCWSTR)file, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); +#else + fd = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); +#endif + if (fd==INVALID_HANDLE_VALUE){ + ms_warning("Failed to open %s",file); + return -1; + } + d->state=STOPPED; + d->fd=fd; + if (strstr(file,".wav")!=NULL) read_wav_header(d); + return 0; +} + +static int player_close(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->fd!=INVALID_HANDLE_VALUE) CloseHandle(d->fd); + d->fd=NULL; + d->state=CLOSED; + d->stat=-1; + return 0; +} + +static int player_start(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->state==STOPPED) + d->state=STARTED; + return 0; +} + +static int player_stop(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->state==STARTED){ + d->state=STOPPED; + d->stat=-1; + SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN); + //read_wav_header(d); + } + return 0; +} + +static void player_uninit(MSFilter *f){ + PlayerData *d=(PlayerData*)f->data; + if (d->fd!=INVALID_HANDLE_VALUE) player_close(f,NULL); + ms_free(d); +} + +static void player_process(MSFilter *f){ + PlayerData *d=(PlayerData*)f->data; + int bytes =d->big_buffer * 2*(f->ticker->interval*d->rate*d->nchannels)/1000;; + + if (d->big_buffer>1) + { + /* when starting reading a file: prepare more data + so that sound card buffer will never remain empty. + */ + d->stat++; + if (d->stat>3) + { + if (d->stat%(d->big_buffer)!=0) + return; + } + } + + if (d->state==STARTED){ + unsigned long err; + mblk_t *om=allocb(bytes,0); + if (d->pause_time>0){ + err=bytes; + memset(om->b_wptr,0,bytes); + d->pause_time-=f->ticker->interval; + }else{ + BOOL res; + err=0; + res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL) ; + } + if (err>=0){ + if (err==bytes){ + om->b_wptr+=err; + ms_queue_put(f->outputs[0],om); + } + else if (err>0){ + BOOL res; + + om->b_wptr+=err; + + ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF); + SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN); + //read_wav_header(d); + + /* special value for playing file only once */ + if (d->loop_after==-2) + { + player_close(f,NULL); + return; + } + + if (d->loop_after>0) + { + d->stat=-1; + d->pause_time=d->loop_after; + } + else + { + bytes=bytes-err; + err=0; + res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL); + if (err>0){ + om->b_wptr+=err; + } + } + + ms_queue_put(f->outputs[0],om); + } + else if (err==0){ + BOOL res; + ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF); + SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN); + + if (d->loop_after==-2) + { + player_close(f,NULL); + return; + } + + if (d->loop_after>0) + { + d->stat=-1; + d->pause_time=d->loop_after; + } + else + { + bytes=bytes-err; + err=0; + res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL); + if (err>0){ + om->b_wptr+=err; + ms_queue_put(f->outputs[0],om); + return; + } + } + freemsg(om); + + }else freemsg(om); + }else{ +#if !defined(_WIN32_WCE) + ms_warning("Fail to read %i bytes: %s",bytes,strerror(errno)); +#else + ms_warning("Fail to read %i bytes: %i",bytes,WSAGetLastError()); +#endif + } + } +} + +static int player_get_sr(MSFilter *f, void*arg){ + PlayerData *d=(PlayerData*)f->data; + *((int*)arg)=d->rate; + return 0; +} + +static int player_loop(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + d->loop_after=*((int*)arg); + return 0; +} + +static int player_set_big_buffer(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + d->big_buffer=*((int*)arg); + return 0; +} + +static int player_eof(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + if (d->fd==NULL && d->state==CLOSED) + *((int*)arg) = TRUE; /* 1 */ + else + *((int*)arg) = FALSE; /* 0 */ + return 0; +} + +static int player_get_nch(MSFilter *f, void *arg){ + PlayerData *d=(PlayerData*)f->data; + *((int*)arg)=d->nchannels; + return 0; +} + +static MSFilterMethod player_methods[]={ + { MS_FILE_PLAYER_OPEN, player_open }, + { MS_FILE_PLAYER_START, player_start }, + { MS_FILE_PLAYER_STOP, player_stop }, + { MS_FILE_PLAYER_CLOSE, player_close }, + { MS_FILTER_GET_SAMPLE_RATE, player_get_sr}, + { MS_FILTER_GET_NCHANNELS, player_get_nch }, + { MS_FILE_PLAYER_LOOP, player_loop }, + { MS_FILE_PLAYER_DONE, player_eof }, + { MS_FILE_PLAYER_BIG_BUFFER, player_set_big_buffer }, + { 0, NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_file_player_desc={ + MS_FILE_PLAYER_ID, + "MSFilePlayer", + "Raw files and wav reader", + MS_FILTER_OTHER, + NULL, + 0, + 1, + player_init, + NULL, + player_process, + NULL, + player_uninit, + player_methods +}; + +#else + +MSFilterDesc ms_file_player_desc={ + .id=MS_FILE_PLAYER_ID, + .name="MSFilePlayer", + .text="Raw files and wav reader", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .init=player_init, + .process=player_process, + .uninit=player_uninit, + .methods=player_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_file_player_desc) diff --git a/linphone/mediastreamer2/src/msfilerec.c b/linphone/mediastreamer2/src/msfilerec.c new file mode 100644 index 000000000..fc548ed49 --- /dev/null +++ b/linphone/mediastreamer2/src/msfilerec.c @@ -0,0 +1,200 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilerec.h" +#include "mediastreamer2/waveheader.h" + +#include +#include +#include + +static int rec_close(MSFilter *f, void *arg); + +typedef enum{ + Closed, + Stopped, + Started +} State; + +typedef struct RecState{ + int fd; + int rate; + int size; + State state; +} RecState; + +static void rec_init(MSFilter *f){ + RecState *s=ms_new(RecState,1); + s->fd=-1; + s->rate=8000; + s->size=0; + s->state=Closed; + f->data=s; +} + +static void rec_process(MSFilter *f){ + RecState *s=(RecState*)f->data; + mblk_t *m; + int err; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + mblk_t *it=m; + ms_mutex_lock(&f->lock); + if (s->state==Started){ + while(it!=NULL){ + int len=it->b_wptr-it->b_rptr; + if ((err=write(s->fd,it->b_rptr,len))!=len){ + if (err<0) + ms_warning("MSFileRec: fail to write %i bytes: %s",len,strerror(errno)); + } + it=it->b_cont; + s->size+=len; + } + } + ms_mutex_unlock(&f->lock); + freemsg(m); + } +} + +static int rec_open(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + const char *filename=(const char*)arg; + if (s->fd>=0) rec_close(f,NULL); + ms_mutex_lock(&f->lock); + s->fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); + if (s->fd<0){ + ms_warning("Cannot open %s: %s",filename,strerror(errno)); + ms_mutex_unlock(&f->lock); + return -1; + } + s->state=Stopped; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_start(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Started; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_stop(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Stopped; + ms_mutex_unlock(&f->lock); + return 0; +} + +static void write_wav_header(int fd, int rate,int size){ + wave_header_t header; + memcpy(&header.riff_chunk.riff,"RIFF",4); + header.riff_chunk.len=le_uint32(size+32); + memcpy(&header.riff_chunk.wave,"WAVE",4); + + memcpy(&header.format_chunk.fmt,"fmt ",4); + header.format_chunk.len=le_uint32(0x10); + header.format_chunk.type=le_uint16(0x1); + header.format_chunk.channel=le_uint16(0x1); + header.format_chunk.rate=le_uint32(rate); + header.format_chunk.bps=le_uint32(rate*2); + header.format_chunk.blockalign=le_uint16(2); + header.format_chunk.bitpspl=le_uint16(16); + + memcpy(&header.data_chunk.data,"data",4); + header.data_chunk.len=le_uint32(size); + lseek(fd,0,SEEK_SET); + if (write(fd,&header,sizeof(header))!=sizeof(header)){ + ms_warning("Fail to write wav header."); + } +} + +static int rec_close(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Closed; + if (s->fd>=0) { + write_wav_header(s->fd,s->rate, s->size); + close(s->fd); + s->fd=-1; + } + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_set_sr(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->rate=*((int*)arg); + ms_mutex_unlock(&f->lock); + return 0; +} + +static void rec_uninit(MSFilter *f){ + RecState *s=(RecState*)f->data; + if (s->fd>=0) rec_close(f,NULL); + ms_free(s); +} + +static MSFilterMethod rec_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE, rec_set_sr }, + { MS_FILE_REC_OPEN , rec_open }, + { MS_FILE_REC_START , rec_start }, + { MS_FILE_REC_STOP , rec_stop }, + { MS_FILE_REC_CLOSE , rec_close }, + { 0 , NULL } +}; + +#ifdef WIN32 + +MSFilterDesc ms_file_rec_desc={ + MS_FILE_REC_ID, + "MSFileRec", + "Wav file recorder", + MS_FILTER_OTHER, + NULL, + 1, + 0, + rec_init, + NULL, + rec_process, + NULL, + rec_uninit, + rec_methods +}; + +#else + +MSFilterDesc ms_file_rec_desc={ + .id=MS_FILE_REC_ID, + .name="MSFileRec", + .text="Wav file recorder", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .init=rec_init, + .process=rec_process, + .uninit=rec_uninit, + .methods=rec_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_file_rec_desc) diff --git a/linphone/mediastreamer2/src/msfilerec_win.c b/linphone/mediastreamer2/src/msfilerec_win.c new file mode 100644 index 000000000..07b069351 --- /dev/null +++ b/linphone/mediastreamer2/src/msfilerec_win.c @@ -0,0 +1,237 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilerec.h" +#include "mediastreamer2/waveheader.h" + +#if !defined(_WIN32_WCE) +#include +#include +#include +#endif + + +typedef enum{ + Closed, + Stopped, + Started +} State; + +typedef struct RecState{ + HANDLE fd; + int rate; + int size; + State state; + char filename[256]; +} RecState; + +static void rec_init(MSFilter *f){ + RecState *s=(RecState *)ms_new(RecState,1); + s->fd=INVALID_HANDLE_VALUE; + s->rate=8000; + s->size=0; + s->state=Closed; + f->data=s; +} + +static void rec_process(MSFilter *f){ + RecState *s=(RecState*)f->data; + mblk_t *m; + int err; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + mblk_t *it=m; + ms_mutex_lock(&f->lock); + if (s->state==Started){ + while(it!=NULL){ + int len=it->b_wptr-it->b_rptr; + DWORD byte_written=0; + if ((err=WriteFile(s->fd,it->b_rptr,len, &byte_written, NULL))!=len){ + if (err<0) + { +#if !defined(_WIN32_WCE) + ms_warning("MSFileRec: fail to write %i bytes: %s",len,strerror(errno)); +#else + ms_warning("MSFileRec: fail to write %i bytes: %i",len,WSAGetLastError()); +#endif + } + } + it=it->b_cont; + s->size+=len; + } + } + ms_mutex_unlock(&f->lock); + freemsg(m); + } +} + +static void write_wav_header(int rate,int size, char *filename){ + wave_header_t header; + DWORD bytes_written=0; + HANDLE fd; + memcpy(&header.riff_chunk.riff,"RIFF",4); + header.riff_chunk.len=le_uint32(size+32); + memcpy(&header.riff_chunk.wave,"WAVE",4); + + memcpy(&header.format_chunk.fmt,"fmt ",4); + header.format_chunk.len=le_uint32(0x10); + header.format_chunk.type=le_uint16(0x1); + header.format_chunk.channel=le_uint16(0x1); + header.format_chunk.rate=le_uint32(rate); + header.format_chunk.bps=le_uint32(rate*2); + header.format_chunk.blockalign=le_uint16(2); + header.format_chunk.bitpspl=le_uint16(16); + + memcpy(&header.data_chunk.data,"data",4); + header.data_chunk.len=le_uint32(size); + + /* TODO: replace with "lseek" equivalent for windows */ +#if defined(_WIN32_WCE) + fd=CreateFile((LPCWSTR)filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); +#else + fd=CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); +#endif + if (fd==INVALID_HANDLE_VALUE){ +#if !defined(_WIN32_WCE) + ms_warning("Cannot open %s: %s",filename,strerror(errno)); +#else + ms_warning("Cannot open %s: %i",filename,WSAGetLastError()); +#endif + return; + } + WriteFile(fd,&header,sizeof(header), &bytes_written, NULL); + if (bytes_written!=sizeof(header)){ + ms_warning("Fail to write wav header."); + } + CloseHandle(fd); +} + +static int rec_open(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + const char *filename=(const char*)arg; + ms_mutex_lock(&f->lock); + snprintf(s->filename, sizeof(s->filename), "%s", filename); +#if defined(_WIN32_WCE) + s->fd=CreateFile((LPCWSTR)filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); +#else + s->fd=CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); +#endif + if (s->fd==INVALID_HANDLE_VALUE){ +#if !defined(_WIN32_WCE) + ms_warning("Cannot open %s: %s",filename,strerror(errno)); +#else + ms_warning("Cannot open %s: %i",filename,WSAGetLastError()); +#endif + ms_mutex_unlock(&f->lock); + return -1; + } + + s->state=Stopped; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_start(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Started; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_stop(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Stopped; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_close(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->state=Closed; + if (s->fd!=INVALID_HANDLE_VALUE) { + CloseHandle(s->fd); + write_wav_header(s->rate, s->size, s->filename); + s->fd=INVALID_HANDLE_VALUE; + s->size=0; + } + ms_mutex_unlock(&f->lock); + return 0; +} + +static int rec_set_sr(MSFilter *f, void *arg){ + RecState *s=(RecState*)f->data; + ms_mutex_lock(&f->lock); + s->rate=*((int*)arg); + ms_mutex_unlock(&f->lock); + return 0; +} + +static void rec_uninit(MSFilter *f){ + RecState *s=(RecState*)f->data; + if (s->fd!=INVALID_HANDLE_VALUE) rec_close(f,NULL); + ms_free(s); +} + +static MSFilterMethod rec_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE, rec_set_sr }, + { MS_FILE_REC_OPEN , rec_open }, + { MS_FILE_REC_START , rec_start }, + { MS_FILE_REC_STOP , rec_stop }, + { MS_FILE_REC_CLOSE , rec_close }, + { 0 , NULL } +}; + +#ifdef WIN32 + +MSFilterDesc ms_file_rec_desc={ + MS_FILE_REC_ID, + "MSFileRec", + "Wav file recorder", + MS_FILTER_OTHER, + NULL, + 1, + 0, + rec_init, + NULL, + rec_process, + NULL, + rec_uninit, + rec_methods +}; + +#else + +MSFilterDesc ms_file_rec_desc={ + .id=MS_FILE_REC_ID, + .name="MSFileRec", + .text="Wav file recorder", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .init=rec_init, + .process=rec_process, + .uninit=rec_uninit, + .methods=rec_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_file_rec_desc) diff --git a/linphone/mediastreamer2/src/msfilter.c b/linphone/mediastreamer2/src/msfilter.c new file mode 100644 index 000000000..5358156d6 --- /dev/null +++ b/linphone/mediastreamer2/src/msfilter.c @@ -0,0 +1,235 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/mscommon.h" + +static MSList *desc_list=NULL; + +void ms_filter_register(MSFilterDesc *desc){ + if (desc->id==MS_FILTER_NOT_SET_ID){ + ms_fatal("MSFilterId for %s not set !",desc->name); + } + /*lastly registered encoder/decoders may replace older ones*/ + desc_list=ms_list_prepend(desc_list,desc); +} + +void ms_filter_unregister_all(){ + if (desc_list!=NULL) ms_list_free(desc_list); +} + +bool_t ms_filter_codec_supported(const char *mime){ + if (ms_filter_get_encoder(mime)!=NULL + && ms_filter_get_decoder(mime)!=NULL) return TRUE; + return FALSE; +} + +MSFilterDesc * ms_filter_get_encoder(const char *mime){ + MSList *elem; + for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ + MSFilterDesc *desc=(MSFilterDesc*)elem->data; + if (desc->category==MS_FILTER_ENCODER && + strcasecmp(desc->enc_fmt,mime)==0){ + return desc; + } + } + return NULL; +} + +MSFilterDesc * ms_filter_get_decoder(const char *mime){ + MSList *elem; + for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ + MSFilterDesc *desc=(MSFilterDesc*)elem->data; + if (desc->category==MS_FILTER_DECODER && + strcasecmp(desc->enc_fmt,mime)==0){ + return desc; + } + } + return NULL; +} + +MSFilter * ms_filter_create_encoder(const char *mime){ + MSFilterDesc *desc=ms_filter_get_encoder(mime); + if (desc!=NULL) return ms_filter_new_from_desc(desc); + return NULL; +} + +MSFilter * ms_filter_create_decoder(const char *mime){ + MSFilterDesc *desc=ms_filter_get_decoder(mime); + if (desc!=NULL) return ms_filter_new_from_desc(desc); + return NULL; +} + +MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc){ + MSFilter *obj; + obj=(MSFilter *)ms_new0(MSFilter,1); + ms_mutex_init(&obj->lock,NULL); + obj->desc=desc; + if (desc->ninputs>0) obj->inputs=(MSQueue**)ms_new0(MSQueue*,desc->ninputs); + if (desc->noutputs>0) obj->outputs=(MSQueue**)ms_new0(MSQueue*,desc->noutputs); + if (desc->ninputs==0 && desc->noutputs==0) + ms_fatal("A filter cannot have no inputs and outputs"); + if (obj->desc->init!=NULL) + obj->desc->init(obj); + return obj; +} + +MSFilter *ms_filter_new(MSFilterId id){ + MSList *elem; + if (id==MS_FILTER_PLUGIN_ID){ + ms_warning("cannot create plugin filters with ms_filter_new_from_id()"); + return NULL; + } + for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ + MSFilterDesc *desc=(MSFilterDesc*)elem->data; + if (desc->id==id){ + return ms_filter_new_from_desc(desc); + } + } + ms_error("No such filter with id %i",id); + return NULL; +} + +MSFilter *ms_filter_new_from_name(const char *filter_name){ + MSList *elem; + for (elem=desc_list;elem!=NULL;elem=ms_list_next(elem)){ + MSFilterDesc *desc=(MSFilterDesc*)elem->data; + if (strcmp(desc->name,filter_name)==0){ + return ms_filter_new_from_desc(desc); + } + } + ms_error("No such filter with name %s",filter_name); + return NULL; +} + + +MSFilterId ms_filter_get_id(MSFilter *f){ + return f->desc->id; +} + +int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2){ + MSQueue *q; + ms_return_val_if_fail(pin1desc->noutputs, -1); + ms_return_val_if_fail(pin2desc->ninputs, -1); + ms_return_val_if_fail(f1->outputs[pin1]==NULL,-1); + ms_return_val_if_fail(f2->inputs[pin2]==NULL,-1); + q=ms_queue_new(f1,pin1,f2,pin2); + f1->outputs[pin1]=q; + f2->inputs[pin2]=q; + ms_message("ms_filter_link: %s:%p,%i-->%s:%p,%i",f1->desc->name,f1,pin1,f2->desc->name,f2,pin2); + return 0; +} + +int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2){ + MSQueue *q; + ms_return_val_if_fail(f1, -1); + ms_return_val_if_fail(f2, -1); + ms_return_val_if_fail(pin1desc->noutputs, -1); + ms_return_val_if_fail(pin2desc->ninputs, -1); + ms_return_val_if_fail(f1->outputs[pin1]!=NULL,-1); + ms_return_val_if_fail(f2->inputs[pin2]!=NULL,-1); + ms_return_val_if_fail(f1->outputs[pin1]==f2->inputs[pin2],-1); + q=f1->outputs[pin1]; + f1->outputs[pin1]=f2->inputs[pin2]=0; + ms_queue_destroy(q); + ms_message("ms_filter_unlink: %s:%p,%i-->%s:%p,%i",f1->desc->name,f1,pin1,f2->desc->name,f2,pin2); + return 0; +} + +#define MS_FILTER_METHOD_GET_FID(id) (((id)>>16) & 0xFFFF) + +int ms_filter_call_method(MSFilter *f, unsigned int id, void *arg){ + MSFilterMethod *methods=f->desc->methods; + int i; + unsigned int magic=MS_FILTER_METHOD_GET_FID(id); + if (magic!=MS_FILTER_BASE_ID && magic!=f->desc->id) { + ms_fatal("Bad method definition in filter %s",f->desc->name); + return -1; + } + for(i=0;methods!=NULL && methods[i].method!=NULL; i++){ + unsigned int mm=MS_FILTER_METHOD_GET_FID(methods[i].id); + if (mm!=f->desc->id && mm!=MS_FILTER_BASE_ID) { + ms_fatal("MSFilter method mismatch: bad call."); + return -1; + } + if (methods[i].id==id){ + return methods[i].method(f,arg); + } + } + if (magic!=MS_FILTER_BASE_ID) ms_error("no such method on filter %s",f->desc->name); + return -1; +} + +int ms_filter_call_method_noarg(MSFilter *f, unsigned int id){ + return ms_filter_call_method(f,id,NULL); +} + +void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *ud){ + f->notify=fn; + f->notify_ud=ud; +} + +void ms_filter_destroy(MSFilter *f){ + if (f->desc->uninit!=NULL) + f->desc->uninit(f); + if (f->inputs!=NULL) ms_free(f->inputs); + if (f->outputs!=NULL) ms_free(f->outputs); + ms_mutex_destroy(&f->lock); + ms_free(f); +} + + +void ms_filter_process(MSFilter *f){ + ms_debug("Executing process of filter %s:%p",f->desc->name,f); + f->desc->process(f); +} + +void ms_filter_preprocess(MSFilter *f, struct _MSTicker *t){ + f->seen=FALSE; + f->last_tick=0; + f->ticker=t; + if (f->desc->preprocess!=NULL) + f->desc->preprocess(f); +} + +void ms_filter_postprocess(MSFilter *f){ + if (f->desc->postprocess!=NULL) + f->desc->postprocess(f); + f->seen=FALSE; + f->ticker=NULL; +} + +bool_t ms_filter_inputs_have_data(MSFilter *f){ + int i; + for(i=0;idesc->ninputs;i++){ + MSQueue *q=f->inputs[i]; + if (q!=NULL && q->q.q_mcount>0) return TRUE; + } + return FALSE; +} + +void ms_filter_notify(MSFilter *f, unsigned int id, void *arg){ + if (f->notify!=NULL) + f->notify(f->notify_ud,id,arg); +} + +void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){ + if (f->notify!=NULL) + f->notify(f->notify_ud,id,NULL); +} diff --git a/linphone/mediastreamer2/src/msjoin.c b/linphone/mediastreamer2/src/msjoin.c new file mode 100644 index 000000000..3e5e4ab60 --- /dev/null +++ b/linphone/mediastreamer2/src/msjoin.c @@ -0,0 +1,72 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" + +static void join_process(MSFilter *f){ + mblk_t *im; + if (f->inputs[0]!=NULL) + { + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + ms_queue_put(f->outputs[0],im); + } + } + if (f->inputs[1]!=NULL) + { + while((im=ms_queue_get(f->inputs[1]))!=NULL){ + int payload; + payload=mblk_set_payload_type(im, 123); + ms_queue_put(f->outputs[0],im); + } + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_join_desc={ + MS_JOIN_ID, + "MSJoin", + "A filter that send several inputs to one output.", + MS_FILTER_OTHER, + NULL, + 2, + 1, + NULL, + NULL, + join_process, + NULL, + NULL, + NULL +}; + +#else + +MSFilterDesc ms_join_desc={ + .id=MS_JOIN_ID, + .name="MSJoin", + .text="A filter that send several inputs to one output.", + .category=MS_FILTER_OTHER, + .ninputs=2, + .noutputs=1, + .process=join_process +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_join_desc) diff --git a/linphone/mediastreamer2/src/msqueue.c b/linphone/mediastreamer2/src/msqueue.c new file mode 100644 index 000000000..f9b7b6a1b --- /dev/null +++ b/linphone/mediastreamer2/src/msqueue.c @@ -0,0 +1,112 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msqueue.h" +#include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msvideo.h" +#include + +MSQueue * ms_queue_new(struct _MSFilter *f1, int pin1, struct _MSFilter *f2, int pin2 ){ + MSQueue *q=(MSQueue*)ms_new(MSQueue,1); + qinit(&q->q); + q->prev.filter=f1; + q->prev.pin=pin1; + q->next.filter=f2; + q->next.pin=pin2; + return q; +} + +void ms_queue_init(MSQueue *q){ + q->prev.filter=0; + q->prev.pin=0; + q->next.filter=0; + q->next.pin=0; + qinit(&q->q); +} + +void ms_queue_destroy(MSQueue *q){ + flushq(&q->q,0); + ms_free(q); +} + +void ms_queue_flush(MSQueue *q){ + flushq(&q->q,0); +} + + +void ms_bufferizer_init(MSBufferizer *obj){ + qinit(&obj->q); + obj->size=0; +} + +MSBufferizer * ms_bufferizer_new(){ + MSBufferizer *obj=(MSBufferizer *)ms_new(MSBufferizer,1); + ms_bufferizer_init(obj); + return obj; +} + +void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m){ + obj->size+=msgdsize(m); + putq(&obj->q,m); +} + +void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q){ + mblk_t *m; + while((m=ms_queue_get(q))!=NULL){ + ms_bufferizer_put(obj,m); + } +} + +int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen){ + if (obj->size>=datalen){ + int sz=0; + int cplen; + mblk_t *m=peekq(&obj->q); + /*we can return something */ + while(szb_wptr-m->b_rptr,datalen-sz); + memcpy(data+sz,m->b_rptr,cplen); + sz+=cplen; + m->b_rptr+=cplen; + if (m->b_rptr==m->b_wptr){ + /* check cont */ + if (m->b_cont!=NULL) { + m=m->b_cont; + } + else{ + mblk_t *remove=getq(&obj->q); + freemsg(remove); + m=peekq(&obj->q); + } + } + } + obj->size-=datalen; + return datalen; + } + return 0; +} + +void ms_bufferizer_uninit(MSBufferizer *obj){ + flushq(&obj->q,0); +} + +void ms_bufferizer_destroy(MSBufferizer *obj){ + ms_bufferizer_uninit(obj); + ms_free(obj); +} diff --git a/linphone/mediastreamer2/src/msresample.c b/linphone/mediastreamer2/src/msresample.c new file mode 100644 index 000000000..4fb710083 --- /dev/null +++ b/linphone/mediastreamer2/src/msresample.c @@ -0,0 +1,245 @@ + +#include "mediastreamer2/msfilter.h" + +#include + +typedef struct _ResampleData{ + MSBufferizer *bz; + uint32_t ts; + uint32_t input_rate; + uint32_t output_rate; + + void *handle; + float factor; + int nb_unprocessed; +} ResampleData; + +static ResampleData * resample_data_new(){ + ResampleData *obj=(ResampleData *)ms_new(ResampleData,1); + obj->bz=ms_bufferizer_new(); + obj->ts=0; + obj->input_rate=8000; + obj->output_rate=16000; + + obj->nb_unprocessed=0; + obj->factor=obj->output_rate/obj->input_rate; + return obj; +} + +static void resample_data_destroy(ResampleData *obj){ + ms_bufferizer_destroy(obj->bz); + ms_free(obj); +} + +static void resample_init(MSFilter *obj){ + obj->data=resample_data_new(); +} + +static void resample_uninit(MSFilter *obj){ + resample_data_destroy((ResampleData*)obj->data); +} + +static void resample_preprocess(MSFilter *obj){ + ResampleData *dt=(ResampleData*)obj->data; + + dt->handle = resample_open(1, dt->factor, dt->factor); +} + +static void resample_postprocess(MSFilter *obj){ + ResampleData *dt=(ResampleData*)obj->data; + resample_close(dt->handle); +} + +static void resample_process_ms2(MSFilter *obj){ + ResampleData *dt=(ResampleData*)obj->data; + MSBufferizer *bz=dt->bz; + uint8_t buffer[2240]; + int size_of_input; + int size_of_output; + + mblk_t *m; + + if (dt->output_rate==dt->input_rate) + { + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + ms_queue_put(obj->outputs[0],m); + } + return; + } + + if (dt->input_rateoutput_rate) + size_of_input=320; + else + size_of_input=320; + size_of_output = (size_of_input * dt->output_rate)/dt->input_rate; + + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + ms_bufferizer_put(bz,m); + } + while (ms_bufferizer_read(bz,buffer,size_of_input)==size_of_input){ +#if 0 + mblk_t *obl=allocb(size_of_output,0); + + int outpos, o, srcused; + int srcpos; + int fwidth; + + int expectedlen = (int)(size_of_input * dt->factor); + int dstlen = expectedlen + 1000; + float in[1280]; + float out[2560]; + + short *data = (short*)buffer; + int i; + /* Convert the samples to floats */ + for (i = dt->nb_unprocessed; i < size_of_input; i++) + in[i] = (float) data[i-dt->nb_unprocessed]; + dt->nb_unprocessed=0; + + outpos = 0; + srcpos = 0; + for(;;) { + int srcBlock = MIN(size_of_input-srcpos, size_of_input); + int lastFlag = (srcBlock == size_of_input-srcpos); + + o = resample_process(dt->handle, dt->factor, + &in[srcpos], srcBlock, + lastFlag, &srcused, + &out[outpos], MIN(dstlen-outpos, size_of_input * dt->factor + 10)); + srcpos += srcused; + if (o >= 0) + outpos += o; + if (o < 0 || (o == 0 && srcpos == size_of_input)) + break; + } + + if (outpos>0 && outpos<=size_of_output) + { + //resample + data = (short*)obl->b_wptr; + for (i = 0; i < outpos/2; i++) + { + /* bound checks! */ + int bc=(short) out[i]; + if (bc < -32768) + bc = -32768; + else if (bc > 32767) + bc = 32767; + *data = bc; + data++; + } + + obl->b_wptr=obl->b_wptr+outpos; + dt->ts+=160; + ms_queue_put(obj->outputs[0],obl); + } + else + { + ms_warning("resample failed!"); + freeb(obl); + } +#else + mblk_t *obl=allocb(size_of_output,0); + + int srcused; + int o; + + float in[1280]; + float out[2560]; + + short *data = (short*)buffer; + int i; + /* Convert the samples to floats */ + for (i = 0; i < size_of_input/2; i++) + in[i] = (float) data[i-dt->nb_unprocessed]; + + o = resample_process(dt->handle, dt->factor, + &in[0], size_of_input/2, + 0, &srcused, + &out[0], size_of_output/2); + + if (o>0 && o<=size_of_output/2) + { + data = (short*)obl->b_wptr; + for (i = 0; i < o; i++) + { + /* bound checks! */ + int bc=(short) out[i]; + if (bc < -32768) + bc = -32768; + else if (bc > 32767) + bc = 32767; + data[i] = bc; + } + obl->b_wptr=obl->b_wptr+(o*2); /* size_of_output; */ + mblk_set_timestamp_info(obl,dt->ts); + dt->ts+=160; + ms_queue_put(obj->outputs[0],obl); + } + else + { + ms_warning("resample failed!"); + freeb(obl); + } +#endif + } +} + +int ms_resample_set_sr(MSFilter *obj, void *arg){ + ResampleData *dt=(ResampleData*)obj->data; + dt->input_rate=((int*)arg)[0]; + dt->factor=((float)dt->output_rate/(float)dt->input_rate); + return 0; +} + +int ms_resample_set_output_sr(MSFilter *obj, void *arg){ + ResampleData *dt=(ResampleData*)obj->data; + dt->output_rate=((int*)arg)[0]; + dt->factor=((float)dt->output_rate/(float)dt->input_rate); + return 0; +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , ms_resample_set_sr }, + { MS_FILTER_SET_OUTPUT_SAMPLE_RATE , ms_resample_set_output_sr }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_resample_desc={ + MS_RESAMPLE_ID, + "MSResample", + "frequency resampler", + MS_FILTER_OTHER, + NULL, + 1, + 1, + resample_init, + resample_preprocess, + resample_process_ms2, + resample_postprocess, + resample_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_resample_desc={ + .id=MS_RESAMPLE_ID, + .name="MSResample", + .text="frequency resampler", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=1, + .init=resample_init, + .preprocess=resample_preprocess, + .process=resample_process_ms2, + .postprocess=resample_postprocess, + .uninit=resample_uninit, + .methods=enc_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_resample_desc) diff --git a/linphone/mediastreamer2/src/msrtp.c b/linphone/mediastreamer2/src/msrtp.c new file mode 100644 index 000000000..58f5353a6 --- /dev/null +++ b/linphone/mediastreamer2/src/msrtp.c @@ -0,0 +1,441 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msrtp.h" +#include "mediastreamer2/msticker.h" + +#include "ortp/telephonyevents.h" +#include "ortp/b64.h" + +struct SenderData { + RtpSession *session; + struct CandidatePair *cpair; /* table of 10 cpair */ + int round; + uint32_t tsoff; + uint32_t skip_until; + int rate; + char dtmf; + char relay_session_id[64]; + int relay_session_id_size; + unsigned int last_rsi_time; + bool_t skip; + bool_t mute_mic; +}; + +typedef struct SenderData SenderData; + +static void sender_init(MSFilter * f) +{ + SenderData *d = (SenderData *)ms_new(SenderData, 1); + + d->session = NULL; + d->cpair = NULL; + d->round = 0; + d->tsoff = 0; + d->skip_until = 0; + d->skip = FALSE; + d->rate = 8000; + d->dtmf = 0; + d->mute_mic=FALSE; + d->relay_session_id_size=0; + d->last_rsi_time=0; + f->data = d; +} + +static void sender_uninit(MSFilter * f) +{ + SenderData *d = (SenderData *) f->data; + + ms_free(d); +} + +static int sender_send_dtmf(MSFilter * f, void *arg) +{ + const char *dtmf = (const char *) arg; + SenderData *d = (SenderData *) f->data; + + ms_mutex_lock(&f->lock); + d->dtmf = dtmf[0]; + ms_mutex_unlock(&f->lock); + return 0; +} + +static int sender_set_sdpcandidates(MSFilter * f, void *arg) +{ + SenderData *d = (SenderData *) f->data; + struct CandidatePair *scs = NULL; + + if (d == NULL) + return -1; + + scs = (struct CandidatePair *) arg; + d->cpair = scs; + return 0; +} + +static int sender_set_session(MSFilter * f, void *arg) +{ + SenderData *d = (SenderData *) f->data; + RtpSession *s = (RtpSession *) arg; + PayloadType *pt = + rtp_profile_get_payload(rtp_session_get_profile(s), + rtp_session_get_send_payload_type(s)); + if (pt != NULL) { + d->rate = pt->clock_rate; + } else { + ms_warning("Sending undefined payload type ?"); + } + d->session = s; + return 0; +} + +static int sender_mute_mic(MSFilter * f, void *arg) +{ + SenderData *d = (SenderData *) f->data; + ms_filter_lock(f); + d->mute_mic=TRUE; + ms_filter_unlock(f); + return 0; +} + +static int sender_unmute_mic(MSFilter * f, void *arg) +{ + SenderData *d = (SenderData *) f->data; + ms_filter_lock(f); + d->mute_mic=FALSE; + ms_filter_unlock(f); + return 0; +} + +static int sender_set_relay_session_id(MSFilter *f, void*arg){ + SenderData *d = (SenderData *) f->data; + const char *tmp=(const char *)arg; + d->relay_session_id_size=b64_decode(tmp, strlen(tmp), d->relay_session_id, sizeof(d->relay_session_id)); + return 0; +} + +/* the goal of that function is to return a absolute timestamp closest to real time, with respect of given packet_ts, which is a relative to an undefined origin*/ +static uint32_t get_cur_timestamp(MSFilter * f, uint32_t packet_ts) +{ + SenderData *d = (SenderData *) f->data; +#if !defined(_WIN32_WCE) + uint32_t curts = (f->ticker->time * d->rate) / 1000LL; +#else + uint32_t curts = (f->ticker->time * d->rate) / ((uint64_t)1000); +#endif + int diff; + int delta = d->rate / 50; /*20 ms at 8000Hz */ + uint32_t netts; + + netts = packet_ts + d->tsoff; + diff = curts - netts; + +#ifdef AMD_HACK + if (diff > delta) { + d->tsoff = curts - packet_ts; + netts = packet_ts + d->tsoff; + ms_message("synchronizing timestamp, diff=%i", diff); + } + else if (diff < -delta) { + /* d->tsoff = curts - packet_ts; */ + /* hardware clock is going slower than sound card on my PDA... */ + } +#else + if ((diff > delta) || (diff < -(delta * 5))) { + d->tsoff = curts - packet_ts; + netts = packet_ts + d->tsoff; + ms_message("synchronizing timestamp, diff=%i", diff); + } +#endif + + /*ms_message("returned ts=%u, orig_ts=%u",netts,packet_ts); */ + return netts; +} + +static void sender_process(MSFilter * f) +{ + SenderData *d = (SenderData *) f->data; + RtpSession *s = d->session; + + struct CandidatePair *cp = d->cpair; + mblk_t *im; + uint32_t timestamp; + + if (s == NULL){ + ms_queue_flush(f->inputs[0]); + return; + } + + if (d->relay_session_id_size>0 && + ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { + ms_message("relay session id sent in RTCP APP"); + rtp_session_send_rtcp_APP(s,0,"RSID",d->relay_session_id,d->relay_session_id_size); + d->last_rsi_time=f->ticker->time; + } + + while ((im = ms_queue_get(f->inputs[0])) != NULL) { + mblk_t *header; + + timestamp = get_cur_timestamp(f, mblk_get_timestamp_info(im)); + ms_filter_lock(f); + if (d->dtmf != 0) { + rtp_session_send_dtmf(s, d->dtmf, timestamp); + ms_debug("RFC2833 dtmf sent."); + d->dtmf = 0; + d->skip_until = timestamp + (3 * 160); + d->skip = TRUE; + freemsg(im); + }else if (d->skip) { + ms_debug("skipping.."); + if (RTP_TIMESTAMP_IS_NEWER_THAN(timestamp, d->skip_until)) { + d->skip = FALSE; + } + freemsg(im); + }else{ + if (d->mute_mic==FALSE) + { + int pt = mblk_get_payload_type(im); + header = rtp_session_create_packet(s, 12, NULL, 0); + if (pt>0) + rtp_set_payload_type(header, pt); + rtp_set_markbit(header, mblk_get_marker_info(im)); + header->b_cont = im; + rtp_session_sendm_with_ts(s, header, timestamp); + } + else + { + freemsg(im); + } + } + ms_filter_unlock(f); + } + + /* regularly send STUN request */ + ice_sound_send_stun_request(s, cp, d->round); + d->round++; +} + +static MSFilterMethod sender_methods[] = { + {MS_RTP_SEND_MUTE_MIC, sender_mute_mic}, + {MS_RTP_SEND_UNMUTE_MIC, sender_unmute_mic}, + {MS_RTP_SEND_SET_SESSION, sender_set_session}, + {MS_RTP_SEND_SEND_DTMF, sender_send_dtmf}, + {MS_RTP_SEND_SET_CANDIDATEPAIRS, sender_set_sdpcandidates}, + {MS_RTP_SEND_SET_RELAY_SESSION_ID, sender_set_relay_session_id}, + {0, NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_rtp_send_desc = { + MS_RTP_SEND_ID, + "MSRtpSend", + "RTP output filter", + MS_FILTER_OTHER, + NULL, + 1, + 0, + sender_init, + NULL, + sender_process, + NULL, + sender_uninit, + sender_methods +}; + +#else + +MSFilterDesc ms_rtp_send_desc = { + .id = MS_RTP_SEND_ID, + .name = "MSRtpSend", + .text = "RTP output filter", + .category = MS_FILTER_OTHER, + .ninputs = 1, + .noutputs = 0, + .init = sender_init, + .process = sender_process, + .uninit = sender_uninit, + .methods = sender_methods +}; + +#endif + +struct ReceiverData { + RtpSession *session; + OrtpEvQueue *ortp_event; + struct CandidatePair *cpair; /* table of 10 cpair */ + int rate; +}; + +typedef struct ReceiverData ReceiverData; + +static void receiver_init(MSFilter * f) +{ + ReceiverData *d = (ReceiverData *)ms_new(ReceiverData, 1); + + d->ortp_event = ortp_ev_queue_new(); + d->session = NULL; + d->cpair = NULL; + d->rate = 8000; + f->data = d; +} + +static void receiver_postprocess(MSFilter * f) +{ + ReceiverData *d = (ReceiverData *) f->data; + if (d->session!=NULL && d->ortp_event!=NULL) + rtp_session_unregister_event_queue(d->session, d->ortp_event); +} + +static void receiver_uninit(MSFilter * f) +{ + ReceiverData *d = (ReceiverData *) f->data; + if (d->ortp_event!=NULL) + ortp_ev_queue_destroy(d->ortp_event); + ms_free(f->data); +} + +static int receiver_set_session(MSFilter * f, void *arg) +{ + ReceiverData *d = (ReceiverData *) f->data; + RtpSession *s = (RtpSession *) arg; + PayloadType *pt = rtp_profile_get_payload(rtp_session_get_profile(s), + rtp_session_get_recv_payload_type + (s)); + if (pt != NULL) { + d->rate = pt->clock_rate; + } else { + ms_warning("Receiving undefined payload type ?"); + } + d->session = s; + + return 0; +} + +static int receiver_set_sdpcandidates(MSFilter * f, void *arg) +{ + ReceiverData *d = (ReceiverData *) f->data; + struct CandidatePair *scs = NULL; + + if (d == NULL) + return -1; + + scs = (struct CandidatePair *) arg; + d->cpair = scs; + return 0; +} + +static void receiver_preprocess(MSFilter * f){ + ReceiverData *d = (ReceiverData *) f->data; + if (d->session){ + PayloadType *pt=rtp_profile_get_payload( + rtp_session_get_profile(d->session), + rtp_session_get_recv_payload_type(d->session)); + if (pt){ + if (pt->type!=PAYLOAD_VIDEO) + rtp_session_flush_sockets(d->session); + } + } + if (d->session!=NULL && d->ortp_event!=NULL) + rtp_session_register_event_queue(d->session, d->ortp_event); +} + +static void receiver_process(MSFilter * f) +{ + ReceiverData *d = (ReceiverData *) f->data; + mblk_t *m; + uint32_t timestamp; + + if (d->session == NULL) + return; + + timestamp = (f->ticker->time * d->rate) / ((uint64_t)1000); + while ((m = rtp_session_recvm_with_ts(d->session, timestamp)) != NULL) { + mblk_set_timestamp_info(m, rtp_get_timestamp(m)); + mblk_set_marker_info(m, rtp_get_markbit(m)); + mblk_set_payload_type(m, rtp_get_payload_type(m)); + rtp_get_payload(m,&m->b_rptr); + ms_queue_put(f->outputs[0], m); + } + + /* check received STUN request */ + if (d->ortp_event!=NULL) + { + OrtpEvent *evt = ortp_ev_queue_get(d->ortp_event); + + while (evt != NULL) { + if (ortp_event_get_type(evt) == + ORTP_EVENT_STUN_PACKET_RECEIVED) { + ice_process_stun_message(d->session, d->cpair, evt); + } + if (ortp_event_get_type(evt) == + ORTP_EVENT_TELEPHONE_EVENT) { + } + + ortp_event_destroy(evt); + evt = ortp_ev_queue_get(d->ortp_event); + } + } +} + +static MSFilterMethod receiver_methods[] = { + {MS_RTP_RECV_SET_SESSION, receiver_set_session}, + {MS_RTP_RECV_SET_CANDIDATEPAIRS, receiver_set_sdpcandidates}, + {0, NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_rtp_recv_desc = { + MS_RTP_RECV_ID, + "MSRtpRecv", + "RTP input filter", + MS_FILTER_OTHER, + NULL, + 0, + 1, + receiver_init, + receiver_preprocess, + receiver_process, + receiver_postprocess, + receiver_uninit, + receiver_methods +}; + +#else + +MSFilterDesc ms_rtp_recv_desc = { + .id = MS_RTP_RECV_ID, + .name = "MSRtpRecv", + .text = "RTP input filter", + .category = MS_FILTER_OTHER, + .ninputs = 0, + .noutputs = 1, + .init = receiver_init, + .preprocess = receiver_preprocess, + .process = receiver_process, + .postprocess=receiver_postprocess, + .uninit = receiver_uninit, + .methods = receiver_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_rtp_send_desc) +MS_FILTER_DESC_EXPORT(ms_rtp_recv_desc) diff --git a/linphone/mediastreamer2/src/mssndcard.c b/linphone/mediastreamer2/src/mssndcard.c new file mode 100644 index 000000000..caba4c99f --- /dev/null +++ b/linphone/mediastreamer2/src/mssndcard.c @@ -0,0 +1,168 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mssndcard.h" +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +static MSSndCardManager *scm=NULL; + +static MSSndCardManager * create_manager(){ + MSSndCardManager *obj=(MSSndCardManager *)ms_new(MSSndCardManager,1); + obj->cards=NULL; + return obj; +} + +void ms_snd_card_manager_destroy(void){ + if (scm!=NULL){ + ms_list_for_each(scm->cards,(void (*)(void*))ms_snd_card_destroy); + ms_list_free(scm->cards); + } + ms_free(scm); + scm=NULL; +} + +MSSndCardManager * ms_snd_card_manager_get(void){ + if (scm==NULL) scm=create_manager(); + return scm; +} + +MSSndCard * ms_snd_card_manager_get_card(MSSndCardManager *m, const char *id){ + MSList *elem; + for (elem=m->cards;elem!=NULL;elem=elem->next){ + MSSndCard *card=(MSSndCard*)elem->data; + if (id==NULL) return card; + if (strcmp(ms_snd_card_get_string_id(card),id)==0) return card; + } + if (id!=NULL) ms_warning("no card with id %s",id); + return NULL; +} + +MSSndCard * ms_snd_card_manager_get_default_card(MSSndCardManager *m){ + /*return the first card that has the capture+playback capability */ + MSList *elem; + for (elem=m->cards;elem!=NULL;elem=elem->next){ + MSSndCard *card=(MSSndCard*)elem->data; + if (card->capabilities==(MS_SND_CARD_CAP_CAPTURE|MS_SND_CARD_CAP_PLAYBACK)) + return card; + } + return NULL; +} + +const MSList * ms_snd_card_manager_get_list(MSSndCardManager *m){ + return m->cards; +} + +void ms_snd_card_manager_add_card(MSSndCardManager *m, MSSndCard *c){ + ms_message("Card %s added",ms_snd_card_get_string_id(c)); + m->cards=ms_list_append(m->cards,c); +} + +void ms_snd_card_manager_register_desc(MSSndCardManager *m, MSSndCardDesc *desc){ + if (desc->detect!=NULL) + desc->detect(m); +} + +MSSndCard * ms_snd_card_dup(MSSndCard *card){ + MSSndCard *obj=NULL; + if (card->desc->duplicate!=NULL) + obj=card->desc->duplicate(card); + return obj; +} + +MSSndCard * ms_snd_card_new(MSSndCardDesc *desc){ + MSSndCard *obj=(MSSndCard *)ms_new(MSSndCard,1); + obj->desc=desc; + obj->name=NULL; + obj->data=NULL; + obj->id=NULL; + obj->capabilities=MS_SND_CARD_CAP_CAPTURE|MS_SND_CARD_CAP_PLAYBACK; + if (desc->init!=NULL) + desc->init(obj); + return obj; +} + +const char *ms_snd_card_get_driver_type(const MSSndCard *obj){ + return obj->desc->driver_type; +} + +const char *ms_snd_card_get_name(const MSSndCard *obj){ + return obj->name; +} + +unsigned int ms_snd_card_get_capabilities(const MSSndCard *obj){ + return obj->capabilities; +} + +const char *ms_snd_card_get_string_id(MSSndCard *obj){ + if (obj->id==NULL) obj->id=ms_strdup_printf("%s: %s",obj->desc->driver_type,obj->name); + return obj->id; +} + +void ms_snd_card_set_level(MSSndCard *obj, MSSndCardMixerElem e, int percent){ + if (obj->desc->set_level!=NULL) + obj->desc->set_level(obj,e,percent); + else ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); +} + +int ms_snd_card_get_level(MSSndCard *obj, MSSndCardMixerElem e){ + if (obj->desc->get_level!=NULL) + return obj->desc->get_level(obj,e); + else { + ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); + return -1; + } +} + +void ms_snd_card_set_capture(MSSndCard *obj, MSSndCardCapture c){ + if (obj->desc->set_capture!=NULL) + obj->desc->set_capture(obj,c); + else ms_warning("ms_snd_card_set_capture: unimplemented by %s wrapper",obj->desc->driver_type); +} + +struct _MSFilter * ms_snd_card_create_reader(MSSndCard *obj){ + if (obj->desc->create_reader!=NULL) + return obj->desc->create_reader(obj); + else ms_warning("ms_snd_card_create_reader: unimplemented by %s wrapper",obj->desc->driver_type); + return NULL; +} + +struct _MSFilter * ms_snd_card_create_writer(MSSndCard *obj){ + if (obj->desc->create_writer!=NULL) + return obj->desc->create_writer(obj); + else ms_warning("ms_snd_card_create_writer: unimplemented by %s wrapper",obj->desc->driver_type); + return NULL; +} + +void ms_snd_card_destroy(MSSndCard *obj){ + if (obj->desc->uninit!=NULL) obj->desc->uninit(obj); + if (obj->name!=NULL) ms_free(obj->name); + if (obj->id!=NULL) ms_free(obj->id); + ms_free(obj); +} + +#ifdef __linux +#ifndef __ALSA_ENABLED__ +MSSndCard * ms_alsa_card_new_custom(const char *pcmdev, const char *mixdev){ + ms_warning("Alsa support not available in this build of mediastreamer2"); + return NULL; +} +#endif +#endif diff --git a/linphone/mediastreamer2/src/msspeex.c b/linphone/mediastreamer2/src/msspeex.c new file mode 100644 index 000000000..10eb58d83 --- /dev/null +++ b/linphone/mediastreamer2/src/msspeex.c @@ -0,0 +1,565 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" + +#include + +#ifdef WIN32 +#include /* for alloca */ +#endif + +typedef struct EncState{ + int rate; + int bitrate; + int maxbitrate; + int ptime; + int vbr; + int cng; + int mode; + int frame_size; + void *state; + uint32_t ts; + MSBufferizer *bufferizer; +} EncState; + +static void enc_init(MSFilter *f){ + EncState *s=(EncState *)ms_new(EncState,1); + s->rate=8000; + s->bitrate=-1; + s->maxbitrate=-1; + s->ptime=0; + s->mode=0; + s->vbr=1; + s->cng=0; + s->frame_size=0; + s->state=0; + s->ts=0; + s->bufferizer=ms_bufferizer_new(); + f->data=s; +} + +static void enc_uninit(MSFilter *f){ + EncState *s=(EncState*)f->data; + if (s==NULL) + return; + ms_bufferizer_destroy(s->bufferizer); + if (s->state!=NULL) + speex_encoder_destroy(s->state); + ms_free(s); +} + +static void enc_preprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + const SpeexMode *mode=NULL; + int _mode=0; + + switch(s->rate){ + case 8000: + _mode = SPEEX_MODEID_NB; /* rate = 8000Hz */ + break; + case 16000: + _mode = SPEEX_MODEID_WB; /* rate = 16000Hz */ + break; + /* should be supported in the future */ + case 32000: + _mode = SPEEX_MODEID_UWB; /* rate = 32000Hz */ + break; + default: + ms_error("Unsupported rate for speex encoder (back to default rate=8000)."); + s->rate=8000; + } + /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */ + mode = speex_lib_get_mode(_mode); + + if (mode==NULL) + return; + s->state=speex_encoder_init(mode); + + if (s->vbr==1) + { + if (speex_encoder_ctl(s->state,SPEEX_SET_VBR,&s->vbr)!=0){ + ms_error("Could not set vbr mode to speex encoder."); + } + /* implicit VAD */ + speex_encoder_ctl (s->state, SPEEX_SET_DTX, &s->vbr); + } + else if (s->vbr==2) + { + int vad=1; + /* VAD */ + speex_encoder_ctl (s->state, SPEEX_SET_VAD, &vad); + speex_encoder_ctl (s->state, SPEEX_SET_DTX, &vad); + } + else if (s->cng==1) + { + speex_encoder_ctl (s->state, SPEEX_SET_VAD, &s->cng); + } + + if (s->rate==8000){ + if (s->mode!=0){/* mode is set*/ + if (s->mode<=0 || s->mode>=9) + s->mode = 3; /* default mode */ + + if (s->mode==1) + s->bitrate = 2150; + else if (s->mode==2) + s->bitrate = 5950; + else if (s->mode==3) + s->bitrate = 8000; + else if (s->mode==4) + s->bitrate = 11000; + else if (s->mode==5) + s->bitrate = 15000; + else if (s->mode==6) + s->bitrate = 18200; + else if (s->mode==7) + s->bitrate = 24600; + else if (s->mode==8) + s->bitrate = 3950; + + if (s->bitrate!=-1){ + if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&s->bitrate)!=0){ + ms_error("Could not set bitrate %i to speex encoder.",s->bitrate); + } + } + } + } + else if (s->rate==16000){ + if (s->mode!=0){ + int q=0; + s->bitrate = -1; /* 28000; */ + if (s->mode<=0 || s->mode>=8) + s->mode = 6; /* default mode */ + /* no table exist for wide and ultra: + From libspeex/mode.c, those values seems to make sense... */ + if (s->mode<=5) + q=5; + else if (s->mode==5) + q=6; + else if (s->mode==6) + q=8; + else if (s->mode>=7) + q=10; + + if (speex_encoder_ctl(s->state,SPEEX_SET_QUALITY,&q)!=0){ + ms_error("Could not set quality %i to speex encoder.",q); + } + } + } + else + { + if (s->mode!=0){ + int q=0; + s->bitrate = -1; /* 28000; */ + if (s->mode<=0 || s->mode>=8) + s->mode = 6; /* default mode */ + /* no table exist for wide and ultra: + From libspeex/mode.c, those values seems to make sense... */ + if (s->mode<=5) + q=5; + else if (s->mode==5) + q=6; + else if (s->mode==6) + q=8; + else if (s->mode>=7) + q=10; + + if (speex_encoder_ctl(s->state,SPEEX_SET_QUALITY,&q)!=0){ + ms_error("Could not set quality %i to speex encoder.",q); + } + } + } + + if (s->maxbitrate>0){ + /* convert from network bitrate to codec bitrate:*/ + /* ((nbr/(50*8)) -20-12-8)*50*8*/ + int cbr=(((float)s->maxbitrate/(50.0*8))-20-12-8)*50*8; + if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&cbr)!=0){ + ms_error("Could not set maxbitrate %i to speex encoder.",s->bitrate); + } + } + if (speex_encoder_ctl(s->state,SPEEX_GET_BITRATE,&s->bitrate)!=0){ + ms_error("Could not get bitrate %i to speex encoder.",s->bitrate); + } + else ms_message("Using bitrate %i for speex encoder.",s->bitrate); + + speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frame_size); +} + +static void enc_process(MSFilter *f){ + EncState *s=(EncState*)f->data; + mblk_t *im; + int nbytes; + uint8_t *buf; + int frame_per_packet=1; + + if (s->frame_size<=0) + return; + + if (s->ptime>=20) + { + frame_per_packet = s->ptime/20; + } + + if (frame_per_packet<=0) + frame_per_packet=1; + if (frame_per_packet>7) /* 7*20 == 140 ms max */ + frame_per_packet=7; + + nbytes=s->frame_size*2; + buf=(uint8_t*)alloca(nbytes*frame_per_packet); + + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + ms_bufferizer_put(s->bufferizer,im); + } + while(ms_bufferizer_read(s->bufferizer,buf,nbytes*frame_per_packet)==nbytes*frame_per_packet){ + mblk_t *om=allocb(nbytes*frame_per_packet,0);//too large... + int k; + SpeexBits bits; + speex_bits_init(&bits); + for (k=0;kstate,(int16_t*)(buf + (k*s->frame_size*2)),&bits); + s->ts+=s->frame_size; + } + speex_bits_insert_terminator(&bits); + k=speex_bits_write(&bits, (char*)om->b_wptr, nbytes*frame_per_packet); + om->b_wptr+=k; + + mblk_set_timestamp_info(om,s->ts-s->frame_size); + ms_queue_put(f->outputs[0],om); + speex_bits_destroy(&bits); + } +} + +static void enc_postprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + speex_encoder_destroy(s->state); + s->state=NULL; +} + +static int enc_set_sr(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + /* TODO: should be done with fmtp parameter */ + s->rate=((int*)arg)[0]; + return 0; +} + +static int enc_set_br(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + s->maxbitrate=((int*)arg)[0]; + return 0; +} + +static int enc_add_fmtp(MSFilter *f, void *arg){ + char buf[64]; + const char *fmtp=(const char *)arg; + EncState *s=(EncState*)f->data; + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "sr", buf, sizeof(buf)); + if (buf[0]=='\0'){ + } + else { + s->rate = atoi(buf); + } + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "ebw", buf, sizeof(buf)); + if (buf[0]=='\0'){ + } + else if (strstr(buf,"narrow")!=NULL){ + s->rate = 8000; + } + else if (strstr(buf,"wide")!=NULL){ + s->rate = 16000; + } + else if (strstr(buf,"ultra")!=NULL){ + s->rate = 32000; + } + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "vbr", buf, sizeof(buf)); + if (buf[0]=='\0'){ + } + else if (strstr(buf,"off")!=NULL){ + s->vbr=0; + } + else if (strstr(buf,"on")!=NULL){ + s->vbr=1; + } + else if (strstr(buf,"vad")!=NULL){ + s->vbr=2; + } + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "cng", buf, sizeof(buf)); + if (buf[0]=='\0'){ + } + else if (strstr(buf,"off")!=NULL){ + s->cng=0; + } + else if (strstr(buf,"on")!=NULL){ + s->vbr=1; + } + + memset(buf, '\0', sizeof(buf)); + fmtp_get_value(fmtp, "mode", buf, sizeof(buf)); + if (buf[0]=='\0'){ + } + else if (strstr(buf,"any")!=NULL){ + s->mode=10; + } + else { + s->mode = atoi(buf); + if (s->mode<=0 || s->mode>=8) + s->mode = 3; + } + return 0; +} + +static int enc_add_attr(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + EncState *s=(EncState*)f->data; + if (strstr(fmtp,"ptime:10")!=NULL){ + s->ptime=20; + }else if (strstr(fmtp,"ptime:20")!=NULL){ + s->ptime=20; + }else if (strstr(fmtp,"ptime:30")!=NULL){ + s->ptime=40; /* not allowed */ + }else if (strstr(fmtp,"ptime:40")!=NULL){ + s->ptime=40; + }else if (strstr(fmtp,"ptime:50")!=NULL){ + s->ptime=60; + }else if (strstr(fmtp,"ptime:60")!=NULL){ + s->ptime=60; + }else if (strstr(fmtp,"ptime:70")!=NULL){ + s->ptime=80; + }else if (strstr(fmtp,"ptime:80")!=NULL){ + s->ptime=80; + }else if (strstr(fmtp,"ptime:90")!=NULL){ + s->ptime=100; /* not allowed */ + }else if (strstr(fmtp,"ptime:100")!=NULL){ + s->ptime=100; + }else if (strstr(fmtp,"ptime:110")!=NULL){ + s->ptime=120; + }else if (strstr(fmtp,"ptime:120")!=NULL){ + s->ptime=120; + }else if (strstr(fmtp,"ptime:130")!=NULL){ + s->ptime=140; + }else if (strstr(fmtp,"ptime:140")!=NULL){ + s->ptime=140; + } + return 0; +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , enc_set_sr }, + { MS_FILTER_SET_BITRATE , enc_set_br }, + { MS_FILTER_ADD_FMTP , enc_add_fmtp }, + { MS_FILTER_ADD_ATTR , enc_add_attr}, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_speex_enc_desc={ + MS_SPEEX_ENC_ID, + "MSSpeexEnc", + "The free and wonderful speex codec", + MS_FILTER_ENCODER, + "speex", + 1, + 1, + enc_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_speex_enc_desc={ + .id=MS_SPEEX_ENC_ID, + .name="MSSpeexEnc", + .text="The free and wonderful speex codec", + .category=MS_FILTER_ENCODER, + .enc_fmt="speex", + .ninputs=1, + .noutputs=1, + .init=enc_init, + .preprocess=enc_preprocess, + .postprocess=enc_postprocess, + .process=enc_process, + .uninit=enc_uninit, + .methods=enc_methods +}; + +#endif + +typedef struct DecState{ + int rate; + int penh; + int frsz; + void *state; +} DecState; + +static void dec_init(MSFilter *f){ + DecState *s=(DecState *)ms_new(DecState,1); + s->rate=8000; + s->frsz=0; + s->state=NULL; + s->penh=1; + f->data=s; +} + +static void dec_uninit(MSFilter *f){ + DecState *s=(DecState*)f->data; + if (s==NULL) + return; + if (s->state!=NULL) + speex_decoder_destroy(s->state); + ms_free(s); +} + +static void dec_preprocess(MSFilter *f){ + DecState *s=(DecState*)f->data; + const SpeexMode *mode=NULL; + int modeid; + switch(s->rate){ + case 8000: + modeid = SPEEX_MODEID_NB; /* rate = 8000Hz */ + break; + case 16000: + modeid = SPEEX_MODEID_WB; /* rate = 16000Hz */ + break; + /* should be supported in the future */ + case 32000: + modeid = SPEEX_MODEID_UWB; /* rate = 32000Hz */ + break; + default: + ms_error("Unsupported rate for speex decoder (back to default rate=8000)."); + modeid=SPEEX_MODEID_NB; + } + /* warning: speex_lib_get_mode() is not available on speex<1.1.12 */ + mode = speex_lib_get_mode(modeid); + s->state=speex_decoder_init(mode); + speex_mode_query(mode,SPEEX_MODE_FRAME_SIZE,&s->frsz); + if (s->penh==1) + speex_decoder_ctl (s->state, SPEEX_SET_ENH, &s->penh); +} + +static void dec_postprocess(MSFilter *f){ + DecState *s=(DecState*)f->data; + speex_decoder_destroy(s->state); + s->state=NULL; +} + +static int dec_set_sr(MSFilter *f, void *arg){ + DecState *s=(DecState*)f->data; + s->rate=((int*)arg)[0]; + return 0; +} + +static void dec_process(MSFilter *f){ + DecState *s=(DecState*)f->data; + mblk_t *im; + mblk_t *om; + int err; + int frame_per_packet; + SpeexBits bits; + int bytes=s->frsz*2; + speex_bits_init(&bits); + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + speex_bits_reset(&bits); + speex_bits_read_from(&bits,(char*)im->b_rptr,im->b_wptr-im->b_rptr); + om=allocb(bytes*7,0); + /* support for multiple frame (max=7 frames???) in one RTP packet */ + for (frame_per_packet=0;frame_per_packet<7;frame_per_packet++) + { + int i; + err=speex_decode_int(s->state,&bits,(int16_t*)(om->b_wptr+(frame_per_packet*320))); + + i = speex_bits_remaining(&bits); + if (i<10) /* this seems to work: don't know why. */ + break; + } + if (err==0){ + om->b_wptr+=bytes*(frame_per_packet+1); + ms_queue_put(f->outputs[0],om); + }else { + if (err==-1) + ms_warning("speex end of stream"); + else if (err==-2) + ms_warning("speex corrupted stream"); + freemsg(om); + } + freemsg(im); + } + speex_bits_destroy(&bits); +} + +static MSFilterMethod dec_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , dec_set_sr }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_speex_dec_desc={ + MS_SPEEX_DEC_ID, + "MSSpeexDec", + "The free and wonderful speex codec", + MS_FILTER_DECODER, + "speex", + 1, + 1, + dec_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + dec_methods +}; + +#else + +MSFilterDesc ms_speex_dec_desc={ + .id=MS_SPEEX_DEC_ID, + .name="MSSpeexDec", + .text="The free and wonderful speex codec", + .category=MS_FILTER_DECODER, + .enc_fmt="speex", + .ninputs=1, + .noutputs=1, + .init=dec_init, + .preprocess=dec_preprocess, + .postprocess=dec_postprocess, + .process=dec_process, + .uninit=dec_uninit, + .methods=dec_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_speex_dec_desc) +MS_FILTER_DESC_EXPORT(ms_speex_enc_desc) diff --git a/linphone/mediastreamer2/src/msticker.c b/linphone/mediastreamer2/src/msticker.c new file mode 100644 index 000000000..0f8a336d6 --- /dev/null +++ b/linphone/mediastreamer2/src/msticker.c @@ -0,0 +1,468 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + + +#include "mediastreamer2/msticker.h" + + +void * ms_ticker_run(void *s); +static uint64_t get_cur_time(void *); + +void ms_ticker_start(MSTicker *s){ + s->run=TRUE; + ms_thread_create(&s->thread,NULL,ms_ticker_run,s); +} + + +void ms_ticker_init(MSTicker *ticker) +{ + ms_mutex_init(&ticker->lock,NULL); + ticker->execution_list=NULL; + ticker->ticks=1; + ticker->time=0; + ticker->interval=10; + ticker->run=FALSE; + ticker->exec_id=0; + ticker->get_cur_time_ptr=&get_cur_time; + ticker->get_cur_time_data=NULL; +#ifdef WIN32_TIMERS + ticker->TimeEvent=NULL; +#endif + ms_ticker_start(ticker); +} + +MSTicker *ms_ticker_new(){ + MSTicker *obj=(MSTicker *)ms_new(MSTicker,1); + ms_ticker_init(obj); + return obj; +} + +void ms_ticker_stop(MSTicker *s){ + ms_mutex_lock(&s->lock); + s->run=FALSE; + ms_mutex_unlock(&s->lock); + ms_thread_join(s->thread,NULL); +} + + +void ms_ticker_uninit(MSTicker *ticker) +{ + ms_ticker_stop(ticker); + ms_mutex_destroy(&ticker->lock); +} + +void ms_ticker_destroy(MSTicker *ticker){ + ms_ticker_uninit(ticker); + ms_free(ticker); +} + +static void find_filters(MSList **filters, MSFilter *f ){ + int i; + MSQueue *link; + if (f==NULL) ms_fatal("Bad graph."); + /*ms_message("seeing %s, seen=%i",f->desc->name,f->seen);*/ + if (f->seen){ + return; + } + f->seen=TRUE; + *filters=ms_list_append(*filters,f); + /* go upstream */ + for(i=0;idesc->ninputs;i++){ + link=f->inputs[i]; + if (link!=NULL) find_filters(filters,link->prev.filter); + } + /* go downstream */ + for(i=0;idesc->noutputs;i++){ + link=f->outputs[i]; + if (link!=NULL) find_filters(filters,link->next.filter); + } +} + +static MSList *get_sources(MSList *filters){ + MSList *sources=NULL; + MSFilter *f; + for(;filters!=NULL;filters=filters->next){ + f=(MSFilter*)filters->data; + if (f->desc->ninputs==0){ + sources=ms_list_append(sources,f); + } + } + return sources; +} + +int ms_ticker_attach(MSTicker *ticker,MSFilter *f) +{ + MSList *sources=NULL; + MSList *filters=NULL; + MSList *it; + + if (f->ticker!=NULL) { + ms_message("Filter %s is already being scheduled; nothing to do.",f->desc->name); + return 0; + } + + find_filters(&filters,f); + sources=get_sources(filters); + if (sources==NULL){ + ms_fatal("No sources found around filter %s",f->desc->name); + ms_list_free(filters); + return -1; + } + /*run preprocess on each filter: */ + for(it=filters;it!=NULL;it=it->next) + ms_filter_preprocess((MSFilter*)it->data,ticker); + ms_mutex_lock(&ticker->lock); + ticker->execution_list=ms_list_concat(ticker->execution_list,sources); + ms_mutex_unlock(&ticker->lock); + ms_list_free(filters); + return 0; +} + + + +int ms_ticker_detach(MSTicker *ticker,MSFilter *f){ + MSList *sources=NULL; + MSList *filters=NULL; + MSList *it; + + if (f->ticker==NULL) { + ms_message("Filter %s is not scheduled; nothing to do.",f->desc->name); + return 0; + } + + ms_mutex_lock(&ticker->lock); + + find_filters(&filters,f); + sources=get_sources(filters); + if (sources==NULL){ + ms_fatal("No sources found around filter %s",f->desc->name); + ms_list_free(filters); + ms_mutex_unlock(&ticker->lock); + return -1; + } + + for(it=sources;it!=NULL;it=ms_list_next(it)){ + ticker->execution_list=ms_list_remove(ticker->execution_list,it->data); + } + ms_mutex_unlock(&ticker->lock); + ms_list_for_each(filters,(void (*)(void*))ms_filter_postprocess); + ms_list_free(filters); + ms_list_free(sources); + return 0; +} + + +static bool_t filter_can_process(MSFilter *f, int tick){ + /* look if filters before this one have run */ + int i; + MSQueue *l; + for(i=0;idesc->ninputs;i++){ + l=f->inputs[i]; + if (l!=NULL){ + if (l->prev.filter->last_tick!=tick) return FALSE; + } + } + return TRUE; +} + +static void call_process(MSFilter *f){ + bool_t process_done=FALSE; + if (f->desc->ninputs==0){ + ms_filter_process(f); + }else{ + while (ms_filter_inputs_have_data(f)) { + if (process_done){ + ms_warning("Re-scheduling filter %s: all data should be consumed in one process call, so fix it.",f->desc->name); + } + ms_filter_process(f); + process_done=TRUE; + } + } +} + +static void run_graph(MSFilter *f, MSTicker *s, MSList **unschedulable, bool_t force_schedule){ + int i; + MSQueue *l; + if (f->last_tick!=s->ticks ){ + if (filter_can_process(f,s->ticks) || force_schedule) { + /* this is a candidate */ + f->last_tick=s->ticks; + call_process(f); + /* now recurse to next filters */ + for(i=0;idesc->noutputs;i++){ + l=f->outputs[i]; + if (l!=NULL){ + run_graph(l->next.filter,s,unschedulable, force_schedule); + } + } + }else{ + /* this filter has not all inputs that have been filled by filters before it. */ + *unschedulable=ms_list_prepend(*unschedulable,f); + } + } +} + +static void run_graphs(MSTicker *s, MSList *execution_list, bool_t force_schedule){ + MSList *it; + MSList *unschedulable=NULL; + for(it=execution_list;it!=NULL;it=it->next){ + run_graph((MSFilter*)it->data,s,&unschedulable,force_schedule); + } + /* filters that are part of a loop haven't been called in process() because one of their input refers to a filter that could not be scheduled (because they could not be scheduled themselves)... Do you understand ?*/ + /* we resolve this by simply assuming that they must be called anyway + for the loop to run correctly*/ + /* we just recall run_graphs on them, as if they were source filters */ + if (unschedulable!=NULL) { + run_graphs(s,unschedulable,TRUE); + ms_list_free(unschedulable); + } +} + +#ifdef __MACH__ +#include +#include +#endif + +static uint64_t get_cur_time(void *unused){ +#if defined(_WIN32_WCE) + DWORD timemillis = GetTickCount(); + return timemillis; +#elif defined(WIN32) + return timeGetTime() ; +#elif defined(__MACH__) && defined(__GNUC__) && (__GNUC__ >= 3) + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec*1000LL) + (tv.tv_usec/1000LL); +#elif defined(__MACH__) + struct timespec ts; + struct timeb time_val; + + ftime (&time_val); + ts.tv_sec = time_val.time; + ts.tv_nsec = time_val.millitm * 1000000; + return (ts.tv_sec*1000LL) + (ts.tv_nsec/1000000LL); +#else + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME,&ts)<0){ + ms_fatal("clock_gettime() doesn't work: %s",strerror(errno)); + } + return (ts.tv_sec*1000LL) + (ts.tv_nsec/1000000LL); +#endif +} + +static void sleepMs(int ms){ +#ifdef WIN32 + Sleep(ms); +#else + struct timespec ts; + ts.tv_sec=0; + ts.tv_nsec=ms*1000000LL; + nanosleep(&ts,NULL); +#endif +} + +static int set_high_prio(void){ + int precision=2; +#ifdef WIN32 + MMRESULT mm; + TIMECAPS ptc; + mm=timeGetDevCaps(&ptc,sizeof(ptc)); + if (mm==0){ + if (ptc.wPeriodMinticks=1; + ms_mutex_lock(&s->lock); + s->orig=s->get_cur_time_ptr(s->get_cur_time_data); + + while(s->run){ + s->ticks++; + run_graphs(s,s->execution_list,FALSE); + s->time+=s->interval; + while(1){ + realtime=s->get_cur_time_ptr(s->get_cur_time_data)-s->orig; + ms_mutex_unlock(&s->lock); + diff=s->time-realtime; + if (diff>0){ + /* sleep until next tick */ + sleepMs(diff); + }else{ + late=-diff; + if (late>s->interval*5 && late>lastlate){ + ms_warning("We are late of %d miliseconds.",late); + } + lastlate=late; + break; /*exit the while loop */ + } + ms_mutex_lock(&s->lock); + } + ms_mutex_lock(&s->lock); + } + ms_mutex_unlock(&s->lock); + unset_high_prio(precision); + ms_message("MSTicker thread exiting"); + + ms_thread_exit(NULL); + return NULL; +} + +#else + +void * ms_ticker_run(void *arg) +{ + MSTicker *s=(MSTicker*)arg; + uint64_t realtime; + int precision=2; + UINT timerId; + + precision = set_high_prio(); + + s->TimeEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + + s->ticks=1; + ms_mutex_lock(&s->lock); + s->orig=s->get_cur_time_ptr(s->get_cur_time_data); + + timerId = timeSetEvent (s->interval, precision, s->TimeEvent, 0, + TIME_PERIODIC | TIME_CALLBACK_EVENT_SET); + while(s->run){ + DWORD err; + + s->ticks++; + run_graphs(s,s->execution_list,FALSE); + + /* elapsed time since origin */ + s->time = s->get_cur_time_ptr(s->get_cur_time_data)- s->orig; + + ms_mutex_unlock(&s->lock); + err = WaitForSingleObject (s->TimeEvent, s->interval*1000 ); /* wake up each diff */ + if (err==WAIT_FAILED) + ms_message("WaitForSingleObject is failing"); + + ms_mutex_lock(&s->lock); + } + ms_mutex_unlock(&s->lock); + timeKillEvent (timerId); + CloseHandle (s->TimeEvent); + s->TimeEvent=NULL; + unset_high_prio(precision); + ms_message("MSTicker thread exiting"); + ms_thread_exit(NULL); + return NULL; +} + +#endif + +void ms_ticker_set_time_func(MSTicker *ticker, MSTickerTimeFunc func, void *user_data){ + if (func==NULL) func=get_cur_time; + /*ms_mutex_lock(&ticker->lock);*/ + ticker->get_cur_time_ptr=func; + ticker->get_cur_time_data=user_data; + /*re-set the origin to take in account that previous function ptr and the + new one may return different times*/ + ticker->orig=func(user_data)-ticker->time; + /*ms_mutex_unlock(&ticker->lock);*/ + ms_message("ms_ticker_set_time_func: ticker updated."); +} + +static void print_graph(MSFilter *f, MSTicker *s, MSList **unschedulable, bool_t force_schedule){ + int i; + MSQueue *l; + if (f->last_tick!=s->ticks ){ + if (filter_can_process(f,s->ticks) || force_schedule) { + /* this is a candidate */ + f->last_tick=s->ticks; + ms_message("print_graphs: %s", f->desc->name); + /* now recurse to next filters */ + for(i=0;idesc->noutputs;i++){ + l=f->outputs[i]; + if (l!=NULL){ + print_graph(l->next.filter,s,unschedulable, force_schedule); + } + } + }else{ + /* this filter has not all inputs that have been filled by filters before it. */ + *unschedulable=ms_list_prepend(*unschedulable,f); + } + } +} + +static void print_graphs(MSTicker *s, MSList *execution_list, bool_t force_schedule){ + MSList *it; + MSList *unschedulable=NULL; + for(it=execution_list;it!=NULL;it=it->next){ + print_graph((MSFilter*)it->data,s,&unschedulable,force_schedule); + } + /* filters that are part of a loop haven't been called in process() because one of their input refers to a filter that could not be scheduled (because they could not be scheduled themselves)... Do you understand ?*/ + /* we resolve this by simply assuming that they must be called anyway + for the loop to run correctly*/ + /* we just recall run_graphs on them, as if they were source filters */ + if (unschedulable!=NULL) { + print_graphs(s,unschedulable,TRUE); + ms_list_free(unschedulable); + } +} + +void ms_ticker_print_graphs(MSTicker *ticker){ + print_graphs(ticker,ticker->execution_list,FALSE); +} diff --git a/linphone/mediastreamer2/src/msv4l.c b/linphone/mediastreamer2/src/msv4l.c new file mode 100644 index 000000000..07e9e123d --- /dev/null +++ b/linphone/mediastreamer2/src/msv4l.c @@ -0,0 +1,1034 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef __linux + +#include "mediastreamer-config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_LINUX_VIDEODEV2_H +#include +#endif + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msv4l.h" +#include "mediastreamer2/mswebcam.h" +#include "nowebcam.h" + +/* From: Logitech QuickCam USB driver */ +#define QC_IOCTLBASE 220 +/* Get enable workaround for bugs, bitfield */ +#define VIDIOCQCGCOMPATIBLE _IOR ('v',QC_IOCTLBASE+10,int) +/* Set enable workaround for bugs, bitfield */ +#define VIDIOCQCSCOMPATIBLE _IOWR('v',QC_IOCTLBASE+10,int) + +#ifndef VIDIOSFPS +#define VIDIOSFPS _IOW('v',BASE_VIDIOCPRIVATE+20, int) +#endif + +typedef struct V4lState{ + int fd; + ms_thread_t thread; + char *dev; + char *mmapdbuf; + int msize;/*mmapped size*/ + MSVideoSize vsize; + MSVideoSize got_vsize; + int pix_fmt; + int int_pix_fmt; /*internal pixel format */ + mblk_t *frames[VIDEO_MAX_FRAME]; + mblk_t *mire; + queue_t rq; + ms_mutex_t mutex; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + int queued; + bool_t run; + bool_t usemire; + bool_t v4lv2; /*we interface with a V4Lv2 driver */ + bool_t force_v1; + bool_t auto_started; +}V4lState; + +static void *v4l_thread(void *s); +static int v4l_configure(V4lState *s); + +#ifdef HAVE_LINUX_VIDEODEV2_H + +static bool_t v4lv2_try_format(V4lState *s, int fmtid){ + struct v4l2_format fmt; + + memset(&fmt,0,sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = s->vsize.width; + fmt.fmt.pix.height = s->vsize.height; + fmt.fmt.pix.pixelformat = fmtid; + fmt.fmt.pix.field = V4L2_FIELD_ANY; + + if (ioctl (s->fd, VIDIOC_S_FMT, &fmt)<0){ + return FALSE; + } + s->got_vsize.width=s->vsize.width; + s->got_vsize.height=s->vsize.height; + return TRUE; +} + +static int v4lv2_configure(V4lState *s) +{ + struct v4l2_capability cap; + + if (ioctl (s->fd, VIDIOC_QUERYCAP, &cap)<0) { + ms_message("Not a v4lv2 driver."); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + ms_error("%s is not a video capture device\n",s->dev); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + ms_error("%s does not support streaming i/o\n",s->dev); + return -1; + } + + if (v4lv2_try_format(s,V4L2_PIX_FMT_YUV420)){ + s->pix_fmt=MS_YUV420P; + s->int_pix_fmt=V4L2_PIX_FMT_YUV420; + ms_message("v4lv2: YUV420P choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_NV12)){ + s->pix_fmt=MS_YUV420P; + s->int_pix_fmt=V4L2_PIX_FMT_NV12; + ms_message("v4lv2: V4L2_PIX_FMT_NV12 choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_MJPEG)){ + s->pix_fmt=MS_MJPEG; + s->int_pix_fmt=V4L2_PIX_FMT_MJPEG; + ms_message("v4lv2: MJPEG choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_YUYV)){ + s->pix_fmt=MS_YUYV; + s->int_pix_fmt=V4L2_PIX_FMT_YUYV; + ms_message("v4lv2: V4L2_PIX_FMT_YUYV choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_RGB24)){ + s->pix_fmt=MS_RGB24; + s->int_pix_fmt=V4L2_PIX_FMT_RGB24; + ms_message("v4lv2: RGB24 choosen"); + }else{ + ms_error("Could not find supported pixel format."); + return -1; + } + return 0; +} + +static int v4lv2_do_mmap(V4lState *s){ + struct v4l2_requestbuffers req; + int i; + enum v4l2_buf_type type; + + memset(&req,0,sizeof(req)); + + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + if (ioctl (s->fd, VIDIOC_REQBUFS, &req)<0) { + ms_error("Error requesting info on mmap'd buffers: %s",strerror(errno)); + return -1; + } + + for (i=0; ifd, VIDIOC_QUERYBUF, &buf)<0){ + ms_error("Could not VIDIOC_QUERYBUF : %s",strerror(errno)); + return -1; + } + + start=mmap (NULL /* start anywhere */, + buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, + s->fd, buf.m.offset); + + if (start==NULL){ + ms_error("Could not mmap: %s",strerror(errno)); + } + msg=esballoc(start,buf.length,0,NULL); + /* adjust to real size of picture*/ + if (s->pix_fmt==MS_RGB24) + msg->b_wptr+=s->vsize.width*s->vsize.height*3; + else + msg->b_wptr+=(s->vsize.width*s->vsize.height*3)/2; + + s->frames[i]=msg; + } + s->frame_max=req.count; + /* + for (i = 0; i < s->frame_max; ++i) { + struct v4l2_buffer buf; + + memset(&buf,0,sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + if (-1==ioctl (s->fd, VIDIOC_QBUF, &buf)){ + ms_error("VIDIOC_QBUF failed: %s",strerror(errno)); + } + } + */ + /*start capture immediately*/ + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 ==ioctl (s->fd, VIDIOC_STREAMON, &type)){ + ms_error("VIDIOC_STREAMON failed: %s",strerror(errno)); + return -1; + } + return 0; +} + +static mblk_t * v4lv2_grab_image(V4lState *s){ + struct v4l2_buffer buf; + unsigned int k; + memset(&buf,0,sizeof(buf)); + mblk_t *ret=NULL; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + if (s->queued){ + if (ioctl(s->fd, VIDIOC_DQBUF, &buf)<0) { + switch (errno) { + case EAGAIN: + case EIO: + /* Could ignore EIO, see spec. */ + break; + default: + ms_warning("VIDIOC_DQBUF failed: %s",strerror(errno)); + } + }else{ + if (buf.index >= s->frame_max){ + ms_error("buf.index>=s->max_frames !"); + return NULL; + } + s->queued--; + /*decrement ref count of dequeued buffer */ + ret=s->frames[buf.index]; + ret->b_datap->db_ref--; + if (buf.bytesused<=30){ + ms_warning("Ignoring empty buffer..."); + return NULL; + } + } + } + + /*queue buffers whose ref count has dropped to 1, because they are not + still used anywhere in the filter chain */ + for(k=0;kframe_max;++k){ + if (s->frames[k]->b_datap->db_ref==1){ + buf.index=k; + if (-1==ioctl (s->fd, VIDIOC_QBUF, &buf)) + ms_warning("VIDIOC_QBUF %i failed: %s",k, strerror(errno)); + else { + /*increment ref count of queued buffer*/ + s->frames[k]->b_datap->db_ref++; + s->queued++; + } + } + } + return ret; +} + +#endif + +static void v4l_init(MSFilter *f){ + V4lState *s=ms_new0(V4lState,1); + s->fd=-1; + s->run=FALSE; + s->v4lv2=FALSE; + s->mmapdbuf=NULL; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->pix_fmt=MS_RGB24; + s->dev=ms_strdup("/dev/video0"); + qinit(&s->rq); + s->mire=NULL; + ms_mutex_init(&s->mutex,NULL); + s->start_time=0; + s->frame_count=-1; + s->fps=15; + s->usemire=(getenv("DEBUG")!=NULL); + s->queued=0; + s->force_v1=FALSE; + s->auto_started=FALSE; + f->data=s; +} + +/* we try not to close the /dev/videoX device to workaround a bug of linux kernel. +The bug is this one: +One thread opens /dev/videoX, and mmap()s some pages to get data from the camera. +Then several threads are created (using clone) and automatically get a reference to the mmap'd page, thus a reference to the file_struct of the opened file descriptor. +Then when the first thread closes and unmap() the file descriptor, the .release method of the driver is not called because there are still some threads owning the reference to the mmap'd pages. +As far as I understand. +If all threads are correctly pthread_join()ed, then the file descriptor is closed correctly. +But unfortunately when using alsa dmix/asym plugins, some threads are started by those plugins and are kept alive (or zombie) for some time after the mmap()/close(). +*/ + +static int v4l_fd=-1; +static bool_t reuse_fd=FALSE; +static char *v4l_devname=NULL; + +static int v4l_start(MSFilter *f, void *arg) +{ + V4lState *s=(V4lState*)f->data; + int err=0; + if (v4l_fd>=0 && reuse_fd){ + if (strcmp(v4l_devname,s->dev)==0 ){ + /*use this one!*/ + ms_message("v4l_start: reusing previous file descriptor."); + s->fd=v4l_fd; + }else{ + ms_message("closing cached fd"); + close(v4l_fd); + v4l_fd=-1; + ms_free(v4l_devname); + v4l_devname=NULL; + } + } + if (s->fd==-1){ + s->fd=open(s->dev,O_RDWR); + ms_message("v4l_start: open, fd=%i",s->fd); + if (s->fd>=0){ + v4l_fd=s->fd; + v4l_devname=ms_strdup(s->dev); + } + } + if (s->fd<0){ + ms_error("MSV4l: cannot open video device (%s): %s.",s->dev,strerror(errno)); + if (!s->usemire){ + s->pix_fmt=MS_YUV420P; + s->fps=1; + } + return -1; + }else{ +#ifdef HAVE_LINUX_VIDEODEV2_H + if (s->force_v1 || v4lv2_configure(s)<0) {/*might not be V4LV2 */ +#else + if (1){ +#endif + struct video_capability vidcap; + err=v4l_configure(s); + if (err<0) + { + ms_error("MSV4l: could not get configuration of video device"); + close(s->fd); + s->fd=-1; + return -1; + } + if (!s->force_v1) reuse_fd=TRUE; + + err=ioctl(s->fd, VIDIOCGCAP, &vidcap); + if (err==0) + { + ms_message("MSV4l: Webcam is %s.", vidcap.name); + if (strcasecmp(vidcap.name, "Logitech QuickCam USB")==0) + { + int comp_arg=0; + err=ioctl(s->fd, VIDIOCQCSCOMPATIBLE, &comp_arg); + if (err==0) + { + ms_message("MSV4l: compatibility mode disabled for %s.", vidcap.name); + } + } + } + }else{ + ms_message("Device is a video4linux V2 one."); + s->v4lv2=TRUE; + reuse_fd=FALSE; + } + } + return 0; +} + +static void v4l_start_capture(V4lState *s){ + if (s->fd>=0){ + s->run=TRUE; + ms_thread_create(&s->thread,NULL,v4l_thread,s); + } +} + +static int v4l_stop(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + if (s->fd>=0){ + if (!reuse_fd){ + if (close(s->fd)<0){ + ms_warning("MSV4l: Could not close(): %s",strerror(errno)); + } + ms_message("v4l fd %i closed",s->fd); + } + s->fd=-1; + s->frame_count=-1; + } + return 0; +} + +static void v4l_stop_capture(V4lState *s){ + if (s->run){ + s->run=FALSE; + ms_thread_join(s->thread,NULL); + ms_message("v4l thread has joined."); + flushq(&s->rq,0); + } +} + + +static void v4l_uninit(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + if (s->fd>=0) v4l_stop(f,NULL); + ms_free(s->dev); + flushq(&s->rq,0); + ms_mutex_destroy(&s->mutex); + freemsg(s->mire); + ms_free(s); +} + +static bool_t try_format(int fd, struct video_picture *pict, int palette, int depth){ + int err; + pict->palette=palette; + pict->depth=depth; + err=ioctl(fd,VIDIOCSPICT,pict); + if (err<0){ + ms_warning("Could not set picture properties: %s",strerror(errno)); + return FALSE; + } + return TRUE; +} + +static int v4l_do_mmap(V4lState *s){ + struct video_mbuf vmbuf; + int err,i; + memset(&vmbuf,0,sizeof(vmbuf)); + /* try to get mmap properties */ + err=ioctl(s->fd,VIDIOCGMBUF,&vmbuf); + if (err<0){ + ms_error("Could not get mmap properties: %s",strerror(errno)); + return -1; + }else { + if (vmbuf.size>0){ + /* do the mmap */ + s->msize=vmbuf.size; + s->frame_max=vmbuf.frames; + } else { + ms_error("This device cannot support mmap."); + return -1; + } + } + s->mmapdbuf=mmap(NULL,s->msize,PROT_READ,MAP_SHARED,s->fd,0); + if (s->mmapdbuf==(void*)-1) { + /* for non-mmu arch */ + s->mmapdbuf=mmap(NULL,s->msize,PROT_READ,MAP_PRIVATE,s->fd,0); + if (s->mmapdbuf==(void*)-1) { + ms_error("Could not mmap: %s",strerror(errno)); + s->mmapdbuf=NULL; + return -1; + } + } + /* initialize the mediastreamer buffers */ + ms_message("Using %i-frames mmap'd buffer at %p, len %i", + s->frame_max, s->mmapdbuf,s->msize); + for(i=0;iframe_max;i++){ + mblk_t *buf=esballoc((uint8_t*)s->mmapdbuf+vmbuf.offsets[i],vmbuf.offsets[1],0,NULL); + /* adjust to real size of picture*/ + if (s->pix_fmt==MS_RGB24) + buf->b_wptr+=s->vsize.width*s->vsize.height*3; + else + buf->b_wptr+=(s->vsize.width*s->vsize.height*3)/2; + s->frames[i]=buf; + } + s->frame_ind=0; + return 0; +} + +static bool_t try_size(V4lState *s, MSVideoSize vsize){ + struct video_window win; + int err; + memset(&win,0,sizeof(win)); + /*set picture size */ + win.x=win.y=0; + win.width=vsize.width; + win.height=vsize.height; + win.flags=0; + win.clips=NULL; + win.clipcount=0; + + ms_message("Trying to set capture size to %ix%i", vsize.width,vsize.height); + err=ioctl(s->fd,VIDIOCSWIN,&win); + if (err<0){ + ms_warning("Could not set window size: %s",strerror(errno)); + return FALSE; + } + + err=ioctl(s->fd, VIDIOCGWIN, &win); + if (err<0){ + ms_warning("Could not get window size: %s",strerror(errno)); + return FALSE; + } + s->vsize.width=vsize.width; + s->vsize.height=vsize.height; + + if (s->vsize.width!=win.width || s->vsize.height!=win.height){ + ms_warning("Capture size is not what we expected: asked for %ix%i and get %ix%i",s->vsize.width,s->vsize.height, win.width, win.height); + } + s->got_vsize.width=win.width; + s->got_vsize.height=win.height; + ms_message("Capture size set to %ix%i", s->got_vsize.width,s->got_vsize.height); + return TRUE; +} + +static int v4l_configure(V4lState *s) +{ + struct video_channel chan; + struct video_picture pict; + struct video_capability cap; + int err; + int i; + int fps = 0; + int found=0; + + memset(&chan,0,sizeof(chan)); + memset(&pict,0,sizeof(pict)); + memset(&cap,0,sizeof(cap)); + + err=ioctl(s->fd,VIDIOCGCAP,&cap); + if (err!=0) + { + ms_warning("MSV4l: cannot get device capabilities: %s.",strerror(errno)); + return -1; + } + + ms_message("Found %s device. (maxsize=%ix%i)",cap.name, cap.maxwidth, cap.maxheight); + for (i=0;ifd,VIDIOCGCHAN,&chan); + if (err==0) + { + ms_message("Getting video channel %s",chan.name); + switch(chan.type){ + case VIDEO_TYPE_TV: + ms_message("Channel is a TV."); + break; + case VIDEO_TYPE_CAMERA: + ms_message("Channel is a camera"); + break; + default: + ms_warning("unknown video channel type."); + } + found=1; + break; /* find the first channel */ + } + } + if (found) ms_message("A valid video channel was found."); + /* select this channel */ + ioctl(s->fd,VIDIOCSCHAN,&chan); + + /* get picture properties */ + err=ioctl(s->fd,VIDIOCGPICT,&pict); + if (err<0){ + ms_warning("Could not get picture properties: %s",strerror(errno)); + return -1; + } + ms_message("Default picture properties: brightness=%i,hue=%i,colour=%i,contrast=%i,depth=%i, palette=%i.", + pict.brightness,pict.hue,pict.colour, pict.contrast,pict.depth, pict.palette); + + /* trying color format */ + if (try_format(s->fd,&pict,VIDEO_PALETTE_YUV420P,16)){ + ms_message("Driver supports YUV420P, using that format."); + s->pix_fmt=MS_YUV420P; + }else if (try_format(s->fd, &pict,VIDEO_PALETTE_RGB24,24)){ + ms_message("Driver supports RGB24, using that format."); + s->pix_fmt=MS_RGB24; + }else if (try_format(s->fd, &pict,VIDEO_PALETTE_YUV422, 16)){ + ms_message("Driver supports YUV422, using that format."); + s->pix_fmt=MS_YUYV; + }else if (try_format(s->fd, &pict,VIDEO_PALETTE_UYVY, 16)){ + ms_message("Driver supports UYVY, using that format."); + s->pix_fmt=MS_UYVY; + }else{ + ms_fatal("Unsupported video pixel format."); + return -1; + } + + if (!try_size(s,s->vsize)) { + if (!try_size(s,MS_VIDEO_SIZE_NS1)){ + if (!try_size(s,MS_VIDEO_SIZE_VGA)){ + if (!try_size(s,MS_VIDEO_SIZE_CIF)) { + if (!try_size(s,MS_VIDEO_SIZE_QCIF)) { + if (!try_size(s,MS_VIDEO_SIZE_QVGA)) { + return -1; + } + } + } + } + } + } + + /* Try HW frame rate control */ + fps = s->fps; + if (ioctl(s->fd, VIDIOSFPS, &fps) < 0 ) + ms_message("v4l_configure: cannot set HW frame rate control"); + else + ms_message("v4l_configure: set HW fps to be : %d", fps); + + return 0; +} + + +int ms_to_v4l_pix_fmt(MSPixFmt p){ + switch(p){ + case MS_YUV420P: + return VIDEO_PALETTE_YUV420P; + case MS_RGB24: + return VIDEO_PALETTE_RGB24; + case MS_YUYV: + return VIDEO_PALETTE_YUV422; + case MS_UYVY: + return VIDEO_PALETTE_UYVY; + default: + ms_fatal("unsupported pix fmt"); + return -1; + } +} + +static void plane_copy(uint8_t *dest, int dw, int dh, uint8_t *src, int sw, int sh, int bpp){ + int diffw=dw-sw; + int diffh=dh-sh; + int dlsize=dw*bpp; + int slsize=sw*bpp; + int i; + int dstartx=(diffw>0) ? diffw/2 : 0; + int dstarty=(diffh>0) ? diffh/2 : 0; + int sstartx=(diffw<0) ? diffw/2 : 0; + int sstarty=(diffh<0) ? diffh/2 : 0; + uint8_t *tmp1=dest; + uint8_t *tmp2=src; + + /* copy orig into dest */ + tmp2+=sstarty*slsize; + tmp1+=dstarty*dlsize; + for(i=dstarty;ivsize.width*s->vsize.height; + mblk_t *newpic; + if (s->pix_fmt==MS_YUV420P) size=size*3/2; + else if (s->pix_fmt==MS_YUYV) size=size*2; + else if (s->pix_fmt==MS_UYVY) size=size*2; + else if (s->pix_fmt==MS_RGB24) size=size*3; + else ms_fatal("crop_or_pad: unsupported pixel format."); + newpic=allocb(size,0); + memset(newpic->b_wptr,0,size); + pic_copy(newpic->b_wptr, s->vsize.width, s->vsize.height, + pic->b_rptr,s->got_vsize.width,s->got_vsize.height,s->pix_fmt); + newpic->b_wptr+=size; + return newpic; +} + +static mblk_t * v4l_grab_image_mmap(V4lState *s){ + struct video_mmap vmap; + int err; + int syncframe; + int jitter=s->frame_max-1; + int query_frame; + mblk_t *ret; + vmap.width=s->got_vsize.width; + vmap.height=s->got_vsize.height; + vmap.format=ms_to_v4l_pix_fmt(s->pix_fmt); + + query_frame=(s->frame_ind) % s->frame_max; + /*ms_message("v4l_mmap_process: query_frame=%i", + obj->query_frame);*/ + vmap.frame=query_frame; + err=ioctl(s->fd,VIDIOCMCAPTURE,&vmap); + if (err<0) { + ms_warning("v4l_grab_image_mmap: error in VIDIOCMCAPTURE: %s.",strerror(errno)); + usleep(10000); + return NULL; + } + /*g_message("v4l_mmap_process: query_frame=%i done", + obj->query_frame);*/ + syncframe=(s->frame_ind-jitter); + s->frame_ind++; + if (syncframe>=0){ + syncframe=syncframe%s->frame_max; + /*ms_message("Syncing on frame %i",syncframe);*/ + err=ioctl(s->fd,VIDIOCSYNC,&syncframe); + if (err<0) { + ms_warning("v4l_grab_image_mmap: error in VIDIOCSYNC: %s.",strerror(errno)); + return NULL; + } + /*g_message("got frame %i",syncframe);*/ + }else { + return NULL; + } + ret=s->frames[syncframe]; + /* crop or pad picture if obtained size is not what we want */ + if (s->vsize.width!=s->got_vsize.width){ + ret=crop_or_pad(s,ret); + } + return ret; +} + +static mblk_t * v4l_make_mire(V4lState *s){ + unsigned char *data; + int i,j,line,pos; + int patternw=s->vsize.width/6; + int patternh=s->vsize.height/6; + int red,green=0,blue=0; + if (s->mire==NULL){ + s->mire=allocb(s->vsize.width*s->vsize.height*3,0); + s->mire->b_wptr=s->mire->b_datap->db_lim; + } + data=s->mire->b_rptr; + for (i=0;ivsize.height;++i){ + line=i*s->vsize.width*3; + if ( ((i+s->frame_ind)/patternh) & 0x1) red=255; + else red= 0; + for (j=0;jvsize.width;++j){ + pos=line+(j*3); + + if ( ((j+s->frame_ind)/patternw) & 0x1) blue=255; + else blue= 0; + + data[pos]=red; + data[pos+1]=green; + data[pos+2]=blue; + } + } + s->frame_ind++; + return s->mire; +} + +static mblk_t * v4l_make_nowebcam(V4lState *s){ + if (s->mire==NULL && s->frame_ind==0){ + s->mire=ms_load_nowebcam(&s->vsize, -1); + } + s->frame_ind++; + return s->mire; +} + +static void v4l_purge(V4lState *s){ + int i; + int err; + int jitter=s->frame_max-1; + for (i=s->frame_ind-jitter;iframe_ind;++i){ + int syncframe=i%s->frame_max; + ms_message("syncing last frame"); + err=ioctl(s->fd,VIDIOCSYNC,&syncframe); + if (err<0) { + ms_warning("v4l_mmap_process: error in VIDIOCSYNC: %s.",strerror(errno)); + } + } +} + +#ifdef HAVE_LINUX_VIDEODEV2_H +static void v4lv2_purge(V4lState *s){ + struct v4l2_buffer buf; + memset(&buf,0,sizeof(buf)); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + for(;s->queued>0;s->queued--){ + if (ioctl(s->fd, VIDIOC_DQBUF, &buf)==-1){ + ms_warning("v4lv2_purge: Could not DQ buffer: %s",strerror(errno)); + } + } +} +#endif + +static void v4l_do_munmap(V4lState *s){ + int i; +#ifdef HAVE_LINUX_VIDEODEV2_H + enum v4l2_buf_type type; + if (s->v4lv2){ + v4lv2_purge(s); + /*stop capture immediately*/ + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 ==ioctl (s->fd, VIDIOC_STREAMOFF, &type)){ + ms_error("VIDIOC_STREAMOFF failed: %s",strerror(errno)); + } + } +#endif + if (!s->v4lv2){ + v4l_purge(s); + } + if (s->mmapdbuf!=NULL){ + if (munmap(s->mmapdbuf,s->msize)<0){ + ms_warning("MSV4l: Fail to unmap: %s",strerror(errno)); + } + ms_message("munmap() done (%p,%i)",s->mmapdbuf,s->msize); + s->mmapdbuf=NULL; + } + s->msize=0; + for(i=0;iframe_max;++i){ + if (s->v4lv2){ + mblk_t *msg=s->frames[i]; + int len=msg->b_datap->db_lim-msg->b_datap->db_base; + if (munmap(msg->b_datap->db_base,len)<0){ + ms_warning("MSV4l: Fail to unmap: %s",strerror(errno)); + } + } + freemsg(s->frames[i]); + s->frames[i]=NULL; + } +} + + +static void *v4l_thread(void *ptr){ + V4lState *s=(V4lState*)ptr; + int err=-1; + ms_message("v4l_thread starting"); + if (s->v4lv2){ +#ifdef HAVE_LINUX_VIDEODEV2_H + err=v4lv2_do_mmap(s); +#endif + }else{ + err=v4l_do_mmap(s); + } + if (err<0){ + ms_thread_exit(NULL); + } + while(s->run){ + mblk_t *m; +#ifdef HAVE_LINUX_VIDEODEV2_H + if (s->v4lv2) + m=v4lv2_grab_image(s); + else +#endif + m=v4l_grab_image_mmap(s); + + if (s->vsize.width!=s->got_vsize.width){ + if (m){ + /* mblock was allocated by crop or pad! */ + ms_mutex_lock(&s->mutex); + putq(&s->rq,m); + ms_mutex_unlock(&s->mutex); + }else{ + ms_error("grabbing failed !"); + } + } else if (m!=NULL) { + mblk_t *dm=dupmsg(m); + ms_mutex_lock(&s->mutex); + putq(&s->rq,dm); + ms_mutex_unlock(&s->mutex); + } + } + v4l_do_munmap(s); + ms_message("v4l_thread exited."); + ms_thread_exit(NULL); +} + + +static void v4l_process(MSFilter * obj){ + V4lState *s=(V4lState*)obj->data; + uint32_t timestamp; + int cur_frame; + if (s->frame_count==-1){ + s->start_time=obj->ticker->time; + s->frame_count=0; + } + cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame>=s->frame_count){ + mblk_t *om=NULL; + ms_mutex_lock(&s->mutex); + /*keep the most recent frame if several frames have been captured */ + if (s->fd!=-1){ + om=getq(&s->rq); + }else{ + if (s->usemire){ + om=dupmsg(v4l_make_mire(s)); + }else { + mblk_t *tmpm=v4l_make_nowebcam(s); + if (tmpm) om=dupmsg(tmpm); + } + } + ms_mutex_unlock(&s->mutex); + if (om!=NULL){ + timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/ + mblk_set_timestamp_info(om,timestamp); + mblk_set_marker_info(om,TRUE); + ms_queue_put(obj->outputs[0],om); + /*ms_message("picture sent");*/ + s->frame_count++; + } + }else flushq(&s->rq,0); +} + +static void v4l_preprocess(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + if (s->fd==-1){ + s->auto_started=TRUE; + v4l_start(f,NULL); + v4l_start_capture(s); + } +} + +static void v4l_postprocess(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + if (s->auto_started){ + v4l_stop_capture(s); + v4l_stop(f,NULL); + } +} + +static int v4l_set_fps(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + s->fps=*((float*)arg); + s->frame_count=-1; + return 0; +} + +static int v4l_get_pix_fmt(MSFilter *f,void *arg){ + V4lState *s=(V4lState*)f->data; + MSPixFmt res; + if (s->fd==-1){ + v4l_start(f,NULL); + res=s->pix_fmt; + v4l_stop(f,NULL); + }else res=s->pix_fmt; + *((MSPixFmt*)arg)=res; + return 0; +} + +static int v4l_set_vsize(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + s->vsize=*((MSVideoSize*)arg); + return 0; +} + +static int v4l_get_vsize(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + *(MSVideoSize*)arg=s->vsize; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , v4l_set_fps }, + { MS_FILTER_GET_PIX_FMT , v4l_get_pix_fmt }, + { MS_FILTER_SET_VIDEO_SIZE, v4l_set_vsize }, + { MS_V4L_START , v4l_start }, + { MS_V4L_STOP , v4l_stop }, + { MS_FILTER_GET_VIDEO_SIZE, v4l_get_vsize }, + { 0 , NULL } +}; + +MSFilterDesc ms_v4l_desc={ + .id=MS_V4L_ID, + .name="MSV4l", + .text="A video4linux compatible source filter to stream pictures.", + .ninputs=0, + .noutputs=1, + .category=MS_FILTER_OTHER, + .init=v4l_init, + .preprocess=v4l_preprocess, + .process=v4l_process, + .postprocess=v4l_postprocess, + .uninit=v4l_uninit, + .methods=methods +}; + +MS_FILTER_DESC_EXPORT(ms_v4l_desc) + +static MSFilter *v4l_create_reader(MSWebCam *obj){ + MSFilter *f=ms_filter_new_from_desc(&ms_v4l_desc); + V4lState *s=(V4lState*)f->data; + s->force_v1=TRUE; + return f; +} + +static void v4l_detect(MSWebCamManager *obj); + +static void v4l_cam_init(MSWebCam *cam){ + +} + +MSWebCamDesc v4l_desc={ + "V4L", + &v4l_detect, + &v4l_cam_init, + &v4l_create_reader, + NULL +}; + +static void v4l_detect(MSWebCamManager *obj){ + struct video_capability cap; + const char *devname="/dev/video0"; + int fd=open(devname,O_RDWR); + if (fd!=-1){ + if (ioctl (fd, VIDIOCGCAP, &cap)==0) { + /* is a V4Lv1 */ + MSWebCam *cam=ms_web_cam_new(&v4l_desc); + cam->name=ms_strdup(devname); + ms_web_cam_manager_add_cam(obj,cam); + } + close(fd); + } +} + + +#endif diff --git a/linphone/mediastreamer2/src/msv4l2.c b/linphone/mediastreamer2/src/msv4l2.c new file mode 100644 index 000000000..3b8f1bf1f --- /dev/null +++ b/linphone/mediastreamer2/src/msv4l2.c @@ -0,0 +1,455 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer-config.h" + +#ifdef HAVE_LINUX_VIDEODEV2_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/mswebcam.h" + +typedef struct V4l2State{ + int fd; + char *dev; + char *mmapdbuf; + int msize;/*mmapped size*/ + MSVideoSize vsize; + MSVideoSize got_vsize; + int pix_fmt; + int int_pix_fmt; /*internal pixel format */ + mblk_t *frames[VIDEO_MAX_FRAME]; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + int queued; + bool_t run; +}V4l2State; + +static int v4l2_open(V4l2State *s){ + int fd=open(s->dev,O_RDWR|O_NONBLOCK); + if (fd==-1){ + ms_error("Could not open %s: %s",s->dev,strerror(errno)); + return -1; + } + s->fd=fd; + return 0; +} + +static int v4l2_close(V4l2State *s){ + if (s->fd!=-1){ + close(s->fd); + s->fd=-1; + } + return 0; +} + +static bool_t v4lv2_try_format(V4l2State *s, int fmtid){ + struct v4l2_format fmt; + + memset(&fmt,0,sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = s->vsize.width; + fmt.fmt.pix.height = s->vsize.height; + fmt.fmt.pix.pixelformat = fmtid; + fmt.fmt.pix.field = V4L2_FIELD_ANY; + + if (ioctl (s->fd, VIDIOC_S_FMT, &fmt)<0){ + return FALSE; + } + return TRUE; +} + +static int v4l2_configure(V4l2State *s){ + struct v4l2_capability cap; + struct v4l2_format fmt; + + if (ioctl (s->fd, VIDIOC_QUERYCAP, &cap)<0) { + ms_message("Not a v4lv2 driver."); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + ms_error("%s is not a video capture device\n",s->dev); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + ms_error("%s does not support streaming i/o\n",s->dev); + return -1; + } + + if (v4lv2_try_format(s,V4L2_PIX_FMT_YUV420)){ + s->pix_fmt=MS_YUV420P; + s->int_pix_fmt=V4L2_PIX_FMT_YUV420; + ms_message("v4lv2: YUV420P choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_NV12)){ + s->pix_fmt=MS_YUV420P; + s->int_pix_fmt=V4L2_PIX_FMT_NV12; + ms_message("v4lv2: V4L2_PIX_FMT_NV12 choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_MJPEG)){ + s->pix_fmt=MS_MJPEG; + s->int_pix_fmt=V4L2_PIX_FMT_MJPEG; + ms_message("v4lv2: MJPEG choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_YUYV)){ + s->pix_fmt=MS_YUYV; + s->int_pix_fmt=V4L2_PIX_FMT_YUYV; + ms_message("v4lv2: V4L2_PIX_FMT_YUYV choosen"); + }else if (v4lv2_try_format(s,V4L2_PIX_FMT_RGB24)){ + s->pix_fmt=MS_RGB24; + s->int_pix_fmt=V4L2_PIX_FMT_RGB24; + ms_message("v4lv2: RGB24 choosen"); + }else{ + ms_error("Could not find supported pixel format."); + return -1; + } + memset(&fmt,0,sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (ioctl (s->fd, VIDIOC_G_FMT, &fmt)<0){ + ms_error("VIDIOC_G_FMT failed: %s",strerror(errno)); + }else{ + ms_message("Size of picture is %ix%i",fmt.fmt.pix.width,fmt.fmt.pix.height); + } + + return 0; +} + +static int v4l2_do_mmap(V4l2State *s){ + struct v4l2_requestbuffers req; + int i; + enum v4l2_buf_type type; + + memset(&req,0,sizeof(req)); + + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + if (ioctl (s->fd, VIDIOC_REQBUFS, &req)<0) { + ms_error("Error requesting info on mmap'd buffers: %s",strerror(errno)); + return -1; + } + + for (i=0; ifd, VIDIOC_QUERYBUF, &buf)<0){ + ms_error("Could not VIDIOC_QUERYBUF : %s",strerror(errno)); + return -1; + } + + start=mmap (NULL /* start anywhere */, + buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, + s->fd, buf.m.offset); + + if (start==NULL){ + ms_error("Could not mmap: %s",strerror(errno)); + } + msg=esballoc(start,buf.length,0,NULL); + msg->b_wptr+=buf.length; + s->frames[i]=msg; + } + s->frame_max=req.count; + /* + for (i = 0; i < s->frame_max; ++i) { + struct v4l2_buffer buf; + + memset(&buf,0,sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + if (-1==ioctl (s->fd, VIDIOC_QBUF, &buf)){ + ms_error("VIDIOC_QBUF failed: %s",strerror(errno)); + } + } + */ + /*start capture immediately*/ + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 ==ioctl (s->fd, VIDIOC_STREAMON, &type)){ + ms_error("VIDIOC_STREAMON failed: %s",strerror(errno)); + return -1; + } + return 0; +} + +static mblk_t * v4lv2_grab_image(V4l2State *s){ + struct v4l2_buffer buf; + unsigned int k; + memset(&buf,0,sizeof(buf)); + mblk_t *ret=NULL; + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + /*queue buffers whose ref count is 1, because they are not + still used anywhere in the filter chain */ + for(k=0;kframe_max;++k){ + if (s->frames[k]->b_datap->db_ref==1){ + buf.index=k; + if (-1==ioctl (s->fd, VIDIOC_QBUF, &buf)) + ms_warning("VIDIOC_QBUF %i failed: %s",k, strerror(errno)); + else { + ms_debug("v4l2: queue buf %i",k); + /*increment ref count of queued buffer*/ + s->frames[k]->b_datap->db_ref++; + s->queued++; + } + } + } + + if (s->queued){ + struct pollfd fds; + memset(&fds,0,sizeof(fds)); + fds.events=POLLIN; + fds.fd=s->fd; + /*check with poll if there is something to read */ + if (poll(&fds,1,0)==1 && fds.revents==POLLIN){ + if (ioctl(s->fd, VIDIOC_DQBUF, &buf)<0) { + switch (errno) { + case EAGAIN: + case EIO: + /* Could ignore EIO, see spec. */ + break; + default: + ms_warning("VIDIOC_DQBUF failed: %s",strerror(errno)); + } + }else{ + s->queued--; + ms_debug("v4l2: de-queue buf %i",buf.index); + /*decrement ref count of dequeued buffer */ + ret=s->frames[buf.index]; + ret->b_datap->db_ref--; + if (buf.index >= s->frame_max){ + ms_error("buf.index>=s->max_frames !"); + return NULL; + } + if (buf.bytesused<=30){ + ms_warning("Ignoring empty buffer..."); + return NULL; + } + ret->b_wptr=ret->b_rptr+buf.bytesused; + } + } + } + return ret; +} + +static void v4l2_do_munmap(V4l2State *s){ + int i; + enum v4l2_buf_type type; + /*stop capture immediately*/ + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 ==ioctl (s->fd, VIDIOC_STREAMOFF, &type)){ + ms_error("VIDIOC_STREAMOFF failed: %s",strerror(errno)); + } + + for(i=0;iframe_max;++i){ + mblk_t *msg=s->frames[i]; + int len=msg->b_datap->db_lim-msg->b_datap->db_base; + if (munmap(msg->b_datap->db_base,len)<0){ + ms_warning("MSV4l2: Fail to unmap: %s",strerror(errno)); + } + freemsg(s->frames[i]); + s->frames[i]=NULL; + } +} + + + +static void v4l2_init(MSFilter *f){ + V4l2State *s=ms_new0(V4l2State,1); + s->dev=ms_strdup("/dev/video0"); + s->fd=-1; + s->vsize=MS_VIDEO_SIZE_CIF; + s->fps=15; + f->data=s; +} + +static void v4l2_uninit(MSFilter *f){ + V4l2State *s=(V4l2State*)f->data; + ms_free(s->dev); + ms_free(s); +} + +static void v4l2_process(MSFilter *f){ + V4l2State *s=(V4l2State*)f->data; + uint32_t elapsed; + if (s->fd==-1){ + if (v4l2_open(s)==0 && v4l2_configure(s)==0 && v4l2_do_mmap(s)==0){ + ms_message("V4L2 video capture started."); + }else{ + v4l2_close(s); + } + s->start_time=f->ticker->time; + } + if (s->fd!=-1){ + /*see it is necessary to output a frame:*/ + elapsed=f->ticker->time-s->start_time; + if (((float)elapsed*s->fps/1000.0)>s->frame_count){ + mblk_t *m; + m=v4lv2_grab_image(s); + if (m){ + mblk_t *om=dupb(m); + mblk_set_marker_info(om,(s->pix_fmt==MS_MJPEG)); + ms_queue_put(f->outputs[0],om); + s->frame_count++; + } + } + } +} + +static void v4l2_postprocess(MSFilter *f){ + V4l2State *s=(V4l2State*)f->data; + if (s->fd!=-1){ + v4l2_do_munmap(s); + v4l2_close(s); + } +} + +static int v4l2_set_fps(MSFilter *f, void *arg){ + V4l2State *s=(V4l2State*)f->data; + s->fps=*(float*)arg; + return 0; +} + +static int v4l2_set_vsize(MSFilter *f, void *arg){ + V4l2State *s=(V4l2State*)f->data; + s->vsize=*(MSVideoSize*)arg; + return 0; +} + +static int v4l2_get_vsize(MSFilter *f, void *arg){ + V4l2State *s=(V4l2State*)f->data; + *(MSVideoSize*)arg=s->vsize; + return 0; +} + +static int v4l2_get_pixfmt(MSFilter *f, void *arg){ + V4l2State *s=(V4l2State*)f->data; + if (s->fd==-1){ + if (v4l2_open(s)==0){ + v4l2_configure(s); + *(MSPixFmt*)arg=s->pix_fmt; + v4l2_close(s); + return 0; + }else return -1; + } + *(MSPixFmt*)arg=s->pix_fmt; + return 0; +} + +static int v4l2_set_devfile(MSFilter *f, void *arg){ + V4l2State *s=(V4l2State*)f->data; + if (s->dev) ms_free(s->dev); + s->dev=ms_strdup((char*)arg); + return 0; +} + +static MSFilterMethod v4l2_methods[]={ + { MS_FILTER_SET_FPS , v4l2_set_fps }, + { MS_FILTER_SET_VIDEO_SIZE, v4l2_set_vsize }, + { MS_FILTER_GET_VIDEO_SIZE, v4l2_get_vsize }, + { MS_FILTER_GET_PIX_FMT , v4l2_get_pixfmt }, + { 0 , NULL } +}; + +MSFilterDesc ms_v4l2_desc={ + .id=MS_V4L2_CAPTURE_ID, + .name="MSV4L2Capture", + .text="A filter to grab pictures from Video4Linux2-powered cameras", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .init=v4l2_init, + .process=v4l2_process, + .postprocess=v4l2_postprocess, + .uninit=v4l2_uninit, + .methods=v4l2_methods +}; + +MS_FILTER_DESC_EXPORT(ms_v4l2_desc) + +static MSFilter *v4l2_create_reader(MSWebCam *obj){ + MSFilter *f=ms_filter_new(MS_V4L2_CAPTURE_ID); + v4l2_set_devfile(f,obj->name); + return f; +} + +static void v4l2_detect(MSWebCamManager *obj); + +static void v4l2_cam_init(MSWebCam *cam){ +} + +MSWebCamDesc v4l2_desc={ + "V4L2", + &v4l2_detect, + &v4l2_cam_init, + &v4l2_create_reader, + NULL +}; + +static void v4l2_detect(MSWebCamManager *obj){ + struct v4l2_capability cap; + char devname[32]; + int i; + for(i=0;i<10;++i){ + int fd; + snprintf(devname,sizeof(devname),"/dev/video%i",i); + fd=open(devname,O_RDWR); + if (fd!=-1){ + if (ioctl (fd, VIDIOC_QUERYCAP, &cap)==0) { + /* is a V4LV2 */ + MSWebCam *cam=ms_web_cam_new(&v4l2_desc); + cam->name=ms_strdup(devname); + ms_web_cam_manager_add_cam(obj,cam); + } + close(fd); + } + } +} + + +#endif diff --git a/linphone/mediastreamer2/src/msv4m.c b/linphone/mediastreamer2/src/msv4m.c new file mode 100644 index 000000000..12ba947f9 --- /dev/null +++ b/linphone/mediastreamer2/src/msv4m.c @@ -0,0 +1,508 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef __APPLE__ + +#include "mediastreamer-config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msv4l.h" +#include "nowebcam.h" + +// build for carbon +#define TARGET_API_MAC_CARBON 1 + +#if __APPLE_CC__ + #include + #include +#else + #include + #include + #include + + #include +#endif + +typedef struct V4lState{ + SeqGrabComponent seqgrab; + SGChannel sgchanvideo; + GWorldPtr pgworld; + ImageSequence decomseq; + + char *mmapdbuf; + int msize;/*mmapped size*/ + MSVideoSize vsize; + MSVideoSize got_vsize; + int pix_fmt; + int int_pix_fmt; /*internal pixel format */ + mblk_t *mire; + queue_t rq; + ms_mutex_t mutex; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + int queued; + bool_t run; + bool_t usemire; +}V4lState; + +static void v4m_init(MSFilter *f){ + V4lState *s=ms_new0(V4lState,1); + s->seqgrab=NULL; + s->sgchanvideo=NULL; + s->pgworld=NULL; + s->decomseq=0; + + s->run=FALSE; + s->mmapdbuf=NULL; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->pix_fmt=MS_RGB24; + qinit(&s->rq); + s->mire=NULL; + ms_mutex_init(&s->mutex,NULL); + s->start_time=0; + s->frame_count=-1; + s->fps=15; + s->usemire=(getenv("DEBUG")!=NULL); + s->queued=0; + f->data=s; +} + + +#define BailErr(x) {err = x; if(err != noErr) goto bail;} + +pascal OSErr sgdata_callback(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon); +pascal OSErr sgdata_callback(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon) +{ +#pragma unused(offset,chRefCon,time,writeType) + + CodecFlags ignore; + V4lState *s=(V4lState *)refCon; + ComponentResult err = noErr; + + if (!s) goto bail; + + Rect boundsRect = {0, 0, s->vsize.height, s->vsize.width}; /* 240 , 320*/ + if (s->pgworld) { + + if (s->decomseq == 0) { + Rect sourceRect = { 0, 0 }; + MatrixRecord scaleMatrix; + ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0); + + err = SGGetChannelSampleDescription(c,(Handle)imageDesc); + BailErr(err); + + // make a scaling matrix for the sequence + sourceRect.right = (**imageDesc).width; + sourceRect.bottom = (**imageDesc).height; + RectMatrix(&scaleMatrix, &sourceRect, &boundsRect); + + err = DecompressSequenceBegin(&s->decomseq, // pointer to field to receive unique ID for sequence + imageDesc, // handle to image description structure + s->pgworld, // port for the DESTINATION image + NULL, // graphics device handle, if port is set, set to NULL + NULL, // source rectangle defining the portion of the image to decompress + &scaleMatrix, // transformation matrix + srcCopy, // transfer mode specifier + NULL, // clipping region in dest. coordinate system to use as a mask + 0, // flags + codecNormalQuality, // accuracy in decompression + bestSpeedCodec); // compressor identifier or special identifiers ie. bestSpeedCodec + BailErr(err); + + DisposeHandle((Handle)imageDesc); + imageDesc = NULL; + } + + // decompress a frame into the GWorld - can queue a frame for async decompression when passed in a completion proc + // once the image is in the GWorld it can be manipulated at will + err = DecompressSequenceFrameS(s->decomseq, // sequence ID returned by DecompressSequenceBegin + p, // pointer to compressed image data + len, // size of the buffer + 0, // in flags + &ignore, // out flags + NULL); // async completion proc + BailErr(err); + + { + unsigned line; + mblk_t *buf; + int size = s->vsize.width * s->vsize.height * 3; + buf=allocb(size,0); + + PixMap * pixmap = *GetGWorldPixMap(s->pgworld); + uint8_t * data; + unsigned rowBytes = pixmap->rowBytes & (((unsigned short) 0xFFFF) >> 2); + unsigned pixelSize = pixmap->pixelSize / 8; // Pixel size in bytes + unsigned lineOffset = rowBytes - s->vsize.width * pixelSize; + + data = (uint8_t *) GetPixBaseAddr(GetGWorldPixMap(s->pgworld)); + + for (line = 0 ; line < s->vsize.height ; line++) { + unsigned offset = line * (s->vsize.width * pixelSize + lineOffset); + memcpy(buf->b_wptr + ((line * s->vsize.width) * pixelSize), data + offset, (rowBytes - lineOffset)); + } + + if (s->pix_fmt==MS_RGB24) + { + /* Conversion from top down bottom up (BGR to RGB and flip) */ + unsigned long Index,nPixels; + unsigned char *blue; + unsigned char tmp; + short iPixelSize; + + blue=buf->b_wptr; + + nPixels=s->vsize.width*s->vsize.height; + iPixelSize=24/8; + + for(Index=0;Index!=nPixels;Index++) // For each pixel + { + tmp=*blue; + *blue=*(blue+2); + *(blue+2)=tmp; + blue+=iPixelSize; + } + } + + buf->b_wptr+=size; + //ms_mutex_lock(&s->mutex); /* called during SGIdle? */ + putq(&s->rq, buf); + //ms_mutex_unlock(&s->mutex); + } + } + +bail: + return err; +} + +static int v4m_close(V4lState *s) +{ + if(s->seqgrab) + CloseComponent(s->seqgrab); + s->seqgrab=NULL; + if (s->decomseq) + CDSequenceEnd(s->decomseq); + s->decomseq=NULL; + if (s->pgworld!=NULL) + DisposeGWorld(s->pgworld); + s->pgworld=NULL; + return 0; +} + +static int sequence_grabber_start(V4lState *s) +{ + int err; + Rect theRect = {0, 0, s->vsize.height, s->vsize.width}; + + err = QTNewGWorld(&(s->pgworld), // returned GWorld + k24BGRPixelFormat, + &theRect, // bounding rectangle + 0, // color table + NULL, // graphic device handle + 0); // flags + if (err!=noErr) + { + return -1; + } + + if(!LockPixels(GetPortPixMap(s->pgworld))) + { + v4m_close(s); + return -1; + } + + s->seqgrab = OpenDefaultComponent(SeqGrabComponentType, 0); + err = SGInitialize(s->seqgrab); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + err = SGSetDataRef(s->seqgrab, 0, 0, seqGrabDontMakeMovie); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGSetGWorld(s->seqgrab, s->pgworld, GetMainDevice()); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGNewChannel(s->seqgrab, VideoMediaType, &s->sgchanvideo); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGSetChannelBounds(s->sgchanvideo, &theRect); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGSetChannelUsage(s->sgchanvideo, seqGrabRecord); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGSetDataProc(s->seqgrab,NewSGDataUPP(sgdata_callback),(long)s); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + err = SGStartRecord(s->seqgrab); + if (err!=noErr) + { + v4m_close(s); + return -1; + } + + return 0; +} + +static int v4m_start(MSFilter *f, void *arg) +{ + V4lState *s=(V4lState*)f->data; + int err=0; + + err = sequence_grabber_start(s); + + if (err!=0) + { + s->pix_fmt=MS_YUV420P; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + return 0; + } + + ms_message("v4m video device opened."); + s->pix_fmt=MS_RGB24; + + return 0; +} + +static void v4m_start_capture(V4lState *s){ + if (s->seqgrab!=NULL){ + s->run=TRUE; + } +} + +static int v4m_stop(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + if (s->seqgrab!=NULL){ + ms_mutex_lock(&s->mutex); + SGStop(s->seqgrab); + v4m_close(s); + flushq(&s->rq,0); + ms_mutex_unlock(&s->mutex); + } + return 0; +} + +static void v4m_stop_capture(V4lState *s){ + if (s->run){ + s->run=FALSE; + ms_message("v4m capture stopped."); + } +} + + +static void v4m_uninit(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + if (s->seqgrab!=NULL) v4m_stop(f,NULL); + //ms_free(s->dev); + flushq(&s->rq,0); + ms_mutex_destroy(&s->mutex); + freemsg(s->mire); + ms_free(s); +} + +static mblk_t * v4m_make_mire(V4lState *s){ + unsigned char *data; + int i,j,line,pos; + int patternw=s->vsize.width/6; + int patternh=s->vsize.height/6; + int red,green=0,blue=0; + if (s->mire==NULL){ + s->mire=allocb(s->vsize.width*s->vsize.height*3,0); + s->mire->b_wptr=s->mire->b_datap->db_lim; + } + data=s->mire->b_rptr; + for (i=0;ivsize.height;++i){ + line=i*s->vsize.width*3; + if ( ((i+s->frame_ind)/patternh) & 0x1) red=255; + else red= 0; + for (j=0;jvsize.width;++j){ + pos=line+(j*3); + + if ( ((j+s->frame_ind)/patternw) & 0x1) blue=255; + else blue= 0; + + data[pos]=red; + data[pos+1]=green; + data[pos+2]=blue; + } + } + s->frame_ind++; + return s->mire; +} + +static mblk_t * v4m_make_nowebcam(V4lState *s){ + if (s->mire==NULL && s->frame_ind==0){ + s->mire=ms_load_nowebcam(&s->vsize, -1); + } + s->frame_ind++; + return s->mire; +} + +static void v4m_process(MSFilter * obj){ + V4lState *s=(V4lState*)obj->data; + uint32_t timestamp; + int cur_frame; + if (s->frame_count==-1){ + s->start_time=obj->ticker->time; + s->frame_count=0; + } + + ms_mutex_lock(&s->mutex); + + if (s->seqgrab!=NULL) + { + SGIdle(s->seqgrab); + } + + cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame>=s->frame_count){ + mblk_t *om=NULL; + /*keep the most recent frame if several frames have been captured */ + if (s->seqgrab!=NULL){ + om=getq(&s->rq); + }else{ + if (s->pix_fmt==MS_YUV420P + && s->vsize.width==MS_VIDEO_SIZE_CIF_W + && s->vsize.height==MS_VIDEO_SIZE_CIF_H) + { + if (s->usemire){ + om=dupmsg(v4m_make_mire(s)); + }else { + mblk_t *tmpm=v4m_make_nowebcam(s); + if (tmpm) om=dupmsg(tmpm); + } + } + } + if (om!=NULL){ + timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/ + mblk_set_timestamp_info(om,timestamp); + mblk_set_marker_info(om,TRUE); + ms_queue_put(obj->outputs[0],om); + /*ms_message("picture sent");*/ + s->frame_count++; + } + }else flushq(&s->rq,0); + + ms_mutex_unlock(&s->mutex); +} + +static void v4m_preprocess(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + v4m_start_capture(s); +} + +static void v4m_postprocess(MSFilter *f){ + V4lState *s=(V4lState*)f->data; + v4m_stop_capture(s); +} + +static int v4m_set_fps(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + s->fps=*((float*)arg); + s->frame_count=-1; + return 0; +} + +static int v4m_get_pix_fmt(MSFilter *f,void *arg){ + V4lState *s=(V4lState*)f->data; + *((MSPixFmt*)arg) = s->pix_fmt; + return 0; +} + +static int v4m_set_vsize(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + s->vsize=*((MSVideoSize*)arg); + return 0; +} + +static int v4m_get_vsize(MSFilter *f, void *arg){ + V4lState *s=(V4lState*)f->data; + *(MSVideoSize*)arg=s->vsize; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , v4m_set_fps }, + { MS_FILTER_GET_PIX_FMT , v4m_get_pix_fmt }, + { MS_FILTER_SET_VIDEO_SIZE, v4m_set_vsize }, + { MS_V4L_START , v4m_start }, + { MS_V4L_STOP , v4m_stop }, + { MS_FILTER_GET_VIDEO_SIZE, v4m_get_vsize }, + { 0 , NULL } +}; + +MSFilterDesc ms_v4l_desc={ + .id=MS_V4L_ID, + .name="MSV4m", + .text="A video for macosx compatible source filter to stream pictures.", + .ninputs=0, + .noutputs=1, + .category=MS_FILTER_OTHER, + .init=v4m_init, + .preprocess=v4m_preprocess, + .process=v4m_process, + .postprocess=v4m_postprocess, + .uninit=v4m_uninit, + .methods=methods +}; + +MS_FILTER_DESC_EXPORT(ms_v4l_desc) + +#endif diff --git a/linphone/mediastreamer2/src/msvideo.c b/linphone/mediastreamer2/src/msvideo.c new file mode 100644 index 000000000..df26f3175 --- /dev/null +++ b/linphone/mediastreamer2/src/msvideo.c @@ -0,0 +1,104 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msvideo.h" + +static void yuv_buf_init(YuvBuf *buf, int w, int h, uint8_t *ptr){ + int ysize,usize; + ysize=w*h; + usize=ysize/4; + buf->w=w; + buf->h=h; + buf->planes[0]=ptr; + buf->planes[1]=buf->planes[0]+ysize; + buf->planes[2]=buf->planes[1]+usize; + buf->strides[0]=w; + buf->strides[1]=w/2; + buf->strides[2]=buf->strides[1]; +} + +int yuv_buf_init_from_mblk(YuvBuf *buf, mblk_t *m){ + int size=m->b_wptr-m->b_rptr; + int w,h; + if (size==(MS_VIDEO_SIZE_QCIF_W*MS_VIDEO_SIZE_QCIF_H*3)/2){ + w=MS_VIDEO_SIZE_QCIF_W; + h=MS_VIDEO_SIZE_QCIF_H; + }else if (size==(MS_VIDEO_SIZE_CIF_W*MS_VIDEO_SIZE_CIF_H*3)/2){ + w=MS_VIDEO_SIZE_CIF_W; + h=MS_VIDEO_SIZE_CIF_H; + }else if (size==(MS_VIDEO_SIZE_QQVGA_W*MS_VIDEO_SIZE_QQVGA_H*3)/2){ + w=MS_VIDEO_SIZE_QQVGA_W; + h=MS_VIDEO_SIZE_QQVGA_H; + }else if (size==(MS_VIDEO_SIZE_QVGA_W*MS_VIDEO_SIZE_QVGA_H*3)/2){ + w=MS_VIDEO_SIZE_QVGA_W; + h=MS_VIDEO_SIZE_QVGA_H; + }else if (size==(MS_VIDEO_SIZE_VGA_W*MS_VIDEO_SIZE_VGA_H*3)/2){ + w=MS_VIDEO_SIZE_VGA_W; + h=MS_VIDEO_SIZE_VGA_H; + }else if (size==(MS_VIDEO_SIZE_4CIF_W*MS_VIDEO_SIZE_4CIF_H*3)/2){ + w=MS_VIDEO_SIZE_4CIF_W; + h=MS_VIDEO_SIZE_4CIF_H; + }else if (size==(MS_VIDEO_SIZE_720P_W*MS_VIDEO_SIZE_720P_H*3)/2){ + w=MS_VIDEO_SIZE_720P_W; + h=MS_VIDEO_SIZE_720P_H; + }else if (size==(MS_VIDEO_SIZE_NS1_W*MS_VIDEO_SIZE_NS1_H*3)/2){ + w=MS_VIDEO_SIZE_NS1_W; + h=MS_VIDEO_SIZE_NS1_H; + }else if (size==(160*112*3)/2){/*format used by econf*/ + w=160; + h=112; + }else { + ms_error("Unsupported image size: size=%i (bug somewhere !)",size); + return -1; + } + yuv_buf_init(buf,w,h,m->b_rptr); + return 0; +} + +void yuv_buf_init_from_mblk_with_size(YuvBuf *buf, mblk_t *m, int w, int h){ + yuv_buf_init(buf,w,h,m->b_rptr); +} + +mblk_t * yuv_buf_alloc(YuvBuf *buf, int w, int h){ + int size=(w*h*3)/2; + mblk_t *msg=allocb(size,0); + yuv_buf_init(buf,w,h,msg->b_wptr); + msg->b_wptr+=size; + return msg; +} + +static void plane_copy(const uint8_t *src_plane, int src_stride, + uint8_t *dst_plane, int dst_stride, MSVideoSize roi){ + int i; + for(i=0;i + +static const float max_e=32767*32767; +static const float coef=0.1; + +typedef struct Volume{ + float energy; +}Volume; + +static void volume_init(MSFilter *f){ + f->data=ms_new0(Volume,1); +} + +static void volume_uninit(MSFilter *f){ + ms_free(f->data); +} + +static int volume_get(MSFilter *f, void *arg){ + float *farg=(float*)arg; + Volume *v=(Volume*)f->data; + *farg=10*log10f(v->energy/max_e); + return 0; +} + +static void volume_process(MSFilter *f){ + mblk_t *m; + int16_t *sample; + Volume *v=(Volume*)f->data; + float en=v->energy; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + for ( sample=(int16_t*)m->b_rptr; + sample<(int16_t*)m->b_wptr; + ++sample){ + float s=*sample; + en=(s*s*coef) + (1.0-coef)*en; + } + ms_queue_put(f->outputs[0],m); + } + v->energy=en; +} + +static MSFilterMethod methods[]={ + { MS_VOLUME_GET , volume_get }, + { 0 , NULL } +}; + +#ifndef _MSC_VER +MSFilterDesc ms_volume_desc={ + .name="MSVolume", + .text="A filter to make level measurements on 16 bits pcm audio stream", + .id=MS_VOLUME_ID, + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=1, + .init=volume_init, + .uninit=volume_uninit, + .process=volume_process, + .methods=methods +}; +#else +MSFilterDesc ms_volume_desc={ + MS_VOLUME_ID, + "MSVolume", + "A filter to make level measurements on 16 bits pcm audio stream", + MS_FILTER_OTHER, + NULL, + 1, + 1, + volume_init, + NULL, + volume_process, + NULL, + volume_uninit, + methods +}; +#endif diff --git a/linphone/mediastreamer2/src/mswebcam.c b/linphone/mediastreamer2/src/mswebcam.c new file mode 100644 index 000000000..8cdd75719 --- /dev/null +++ b/linphone/mediastreamer2/src/mswebcam.c @@ -0,0 +1,116 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mswebcam.h" +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/msfilter.h" + +static MSWebCamManager *scm=NULL; + +static MSWebCamManager * create_manager(){ + MSWebCamManager *obj=(MSWebCamManager *)ms_new(MSWebCamManager,1); + obj->cams=NULL; + return obj; +} + +void ms_web_cam_manager_destroy(void){ + if (scm!=NULL){ + ms_list_for_each(scm->cams,(void (*)(void*))ms_web_cam_destroy); + ms_list_free(scm->cams); + } + ms_free(scm); + scm=NULL; +} + +MSWebCamManager * ms_web_cam_manager_get(void){ + if (scm==NULL) scm=create_manager(); + return scm; +} + +MSWebCam * ms_web_cam_manager_get_cam(MSWebCamManager *m, const char *id){ + MSList *elem; + for (elem=m->cams;elem!=NULL;elem=elem->next){ + MSWebCam *cam=(MSWebCam*)elem->data; + if (id==NULL) return cam; + if (strcmp(ms_web_cam_get_string_id(cam),id)==0) return cam; + } + if (id!=NULL) ms_warning("no camera with id %s",id); + return NULL; +} + +MSWebCam * ms_web_cam_manager_get_default_cam(MSWebCamManager *m){ + if (m->cams!=NULL) + return (MSWebCam*)m->cams->data; + return NULL; +} + +const MSList * ms_web_cam_manager_get_list(MSWebCamManager *m){ + return m->cams; +} + +void ms_web_cam_manager_add_cam(MSWebCamManager *m, MSWebCam *c){ + ms_message("Webcam %s added",ms_web_cam_get_string_id(c)); + m->cams=ms_list_append(m->cams,c); +} + +void ms_web_cam_manager_register_desc(MSWebCamManager *m, MSWebCamDesc *desc){ + if (desc->detect!=NULL) + desc->detect(m); +} + +MSWebCam * ms_web_cam_new(MSWebCamDesc *desc){ + MSWebCam *obj=(MSWebCam *)ms_new(MSWebCam,1); + obj->desc=desc; + obj->name=NULL; + obj->data=NULL; + obj->id=NULL; + if (desc->init!=NULL) + desc->init(obj); + return obj; +} + +const char *ms_web_cam_get_driver_type(const MSWebCam *obj){ + return obj->desc->driver_type; +} + +const char *ms_web_cam_get_name(const MSWebCam *obj){ + return obj->name; +} + +const char *ms_web_cam_get_string_id(MSWebCam *obj){ + if (obj->id==NULL) obj->id=ms_strdup_printf("%s: %s",obj->desc->driver_type,obj->name); + return obj->id; +} + +struct _MSFilter * ms_web_cam_create_reader(MSWebCam *obj){ + if (obj->desc->create_reader!=NULL) + return obj->desc->create_reader(obj); + else ms_warning("ms_web_cam_create_reader: unimplemented by %s wrapper",obj->desc->driver_type); + return NULL; +} + +void ms_web_cam_destroy(MSWebCam *obj){ + if (obj->desc->uninit!=NULL) obj->desc->uninit(obj); + if (obj->name!=NULL) ms_free(obj->name); + if (obj->id!=NULL) ms_free(obj->id); + ms_free(obj); +} diff --git a/linphone/mediastreamer2/src/mtu.c b/linphone/mediastreamer2/src/mtu.c new file mode 100644 index 000000000..74a3e5e91 --- /dev/null +++ b/linphone/mediastreamer2/src/mtu.c @@ -0,0 +1,236 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +/* mtu.c : discover the mtu automatically */ + +#include "mediastreamer2/mscommon.h" + + +#if defined(WIN32) + +HINSTANCE m_IcmpInst = NULL; + +typedef struct ip_option_information { + UCHAR Ttl; + UCHAR Tos; + UCHAR Flags; + UCHAR OptionsSize; + PUCHAR OptionsData; +} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION; + +typedef BOOL (WINAPI *ICMPCLOSEHANDLE)(HANDLE IcmpHandle); +typedef HANDLE (WINAPI *ICMPCREATEFILE)(VOID); +typedef DWORD (WINAPI *ICMPSENDECHO)(HANDLE IcmpHandle,ULONG DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout); + +ICMPCLOSEHANDLE pIcmpCloseHandle = NULL; +ICMPCREATEFILE pIcmpCreateFile = NULL; +ICMPSENDECHO pIcmpSendEcho = NULL; + +#define IP_FLAG_DF 0x2 // Don't fragment this packet. +#define IP_OPT_ROUTER_ALERT 0x94 // Router Alert Option + +#define IP_STATUS_BASE 11000 +#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9) +#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10) + +static int mtus[] = { + 1500, // Ethernet, Point-to-Point (default) + 1492, // IEEE 802.3 + 1006, // SLIP, ARPANET + 576, // X.25 Networks + 544, // DEC IP Portal + 512, // NETBIOS + 508, // IEEE 802/Source-Rt Bridge, ARCNET + 296, // Point-to-Point (low delay) + 68, // Official minimum + 0 +}; + +int ms_discover_mtu(const char *host) +{ + int i; + + struct addrinfo hints,*ai=NULL; + char port[10]; + char ipaddr[INET6_ADDRSTRLEN]; + int err; + + HANDLE hIcmp; + unsigned long target_addr; + + struct ip_option_information ip_opts; + unsigned char reply_buffer[10000]; + + if (!m_IcmpInst) + { + m_IcmpInst = LoadLibrary("icmp.dll"); + if (m_IcmpInst) + { + pIcmpCloseHandle = (ICMPCLOSEHANDLE)GetProcAddress(m_IcmpInst, "IcmpCloseHandle"); + pIcmpCreateFile = (ICMPCREATEFILE) GetProcAddress(m_IcmpInst, "IcmpCreateFile"); + pIcmpSendEcho = (ICMPSENDECHO) GetProcAddress(m_IcmpInst, "IcmpSendEcho"); + } + } + + hIcmp = pIcmpCreateFile(); + + memset(&hints,0,sizeof(hints)); + hints.ai_family = PF_INET; + hints.ai_socktype = SOCK_DGRAM; + + snprintf(port,sizeof(port),"0"); + err=getaddrinfo(host,port,&hints,&ai); + if (err!=0){ + pIcmpCloseHandle( hIcmp ); + ms_error("getaddrinfo(): error\n"); + return -1; + } + getnameinfo (ai->ai_addr, ai->ai_addrlen, ipaddr, sizeof (ipaddr), port, + sizeof (port), NI_NUMERICHOST | NI_NUMERICSERV); + freeaddrinfo(ai); + + target_addr=inet_addr(ipaddr); + + + /* Prepare the IP options */ + memset(&ip_opts,0,sizeof(ip_opts)); + ip_opts.Ttl=30; + ip_opts.Flags = IP_FLAG_DF | IP_OPT_ROUTER_ALERT; + + + // ignore icmpbuff data contents + for (i=0;mtus[i]!=0;i++) + { + char icmpbuff[2048]; + char *icmp_data = icmpbuff; + + int status = -1; + if (pIcmpSendEcho) + status=pIcmpSendEcho(hIcmp, + target_addr, + (LPVOID)icmp_data, + mtus[i]-60, /* icmp_data_size */ + &ip_opts, + reply_buffer, + sizeof(reply_buffer), + 3000L); // 5 seconds + if (status || GetLastError() == IP_REQ_TIMED_OUT) + { + pIcmpCloseHandle( hIcmp ); + return mtus[i]; + } + } + + pIcmpCloseHandle( hIcmp ); + + return -1; +} + +#elif defined(__linux) + +#include +#include +#include +#include +#include +#include +#include + +#ifndef IP_MTU +#define IP_MTU 14 +#endif + +int ms_discover_mtu(const char *host){ + int sock; + int err,mtu=0,new_mtu; + socklen_t optlen; + char buf[1500-28]={0}; + char port[10]; + struct addrinfo hints,*ai=NULL; + int rand_port; + int retry=0; + struct timeval tv; + + memset(&hints,0,sizeof(hints)); + hints.ai_family = PF_INET; + hints.ai_socktype = SOCK_DGRAM; + + gettimeofday(&tv,NULL); + srandom(tv.tv_usec); + rand_port=random() & 0xFFFF; + if (rand_port<1000) rand_port+=1000; + snprintf(port,sizeof(port),"%i",rand_port); + err=getaddrinfo(host,port,&hints,&ai); + if (err!=0){ + ms_error("getaddrinfo(): %s\n",gai_strerror(err)); + return -1; + } + sock=socket(PF_INET,SOCK_DGRAM,0); + + mtu=IP_PMTUDISC_DO; + optlen=sizeof(mtu); + err=setsockopt(sock,IPPROTO_IP,IP_MTU_DISCOVER,&mtu,optlen); + if (err!=0){ + ms_error("setsockopt(): %s",strerror(errno)); + return -1; + } + err=connect(sock,ai->ai_addr,ai->ai_addrlen); + freeaddrinfo(ai); + if (err!=0){ + ms_error("connect(): %s",strerror(errno)); + return -1; + } + mtu=sizeof(buf); + do{ + send(sock,buf,mtu,0); + usleep(500000);/*wait for an icmp message come back */ + err=getsockopt(sock,IPPROTO_IP,IP_MTU,&new_mtu,&optlen); + if (err!=0){ + ms_error("getsockopt(): %s",strerror(errno)); + return -1; + }else{ + ms_message("Partial MTU discovered : %i",new_mtu); + if (new_mtu==mtu) break; + else mtu=new_mtu; + } + retry++; + }while(retry<10); + + ms_message("mtu to %s is %i",host,mtu); + return mtu; +} + +#else + +int ms_discover_mtu(const char*host){ + ms_warning("mtu discovery not implemented."); + return -1; +} + +#endif + + +void ms_set_mtu(int mtu){ + /*60= IPv6+UDP+RTP overhead */ + if (mtu>60){ + if (mtu>1500) mtu=1500;/*limit to 1500, the mediastreamer2 buffer are not large enough anyway*/ + ms_set_payload_max_size(mtu-60); + }else ms_set_payload_max_size(0); +} diff --git a/linphone/mediastreamer2/src/nowebcam.c b/linphone/mediastreamer2/src/nowebcam.c new file mode 100644 index 000000000..0b3bae8ff --- /dev/null +++ b/linphone/mediastreamer2/src/nowebcam.c @@ -0,0 +1,217 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mscommon.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/mswebcam.h" + +#include "ffmpeg-priv.h" + +#include + +#ifdef WIN32 +#include +#include +#include +#include +#include +#endif + +static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){ + AVCodecContext av_context; + int got_picture=0; + AVFrame orig; + AVPicture dest; + mblk_t *ret; + struct SwsContext *sws_ctx; + + avcodec_get_context_defaults(&av_context); + if (avcodec_open(&av_context,avcodec_find_decoder(CODEC_ID_MJPEG))<0){ + ms_error("jpeg2yuv: avcodec_open failed"); + return NULL; + } + if (avcodec_decode_video(&av_context,&orig,&got_picture,jpgbuf,bufsize)<0){ + ms_error("jpeg2yuv: avcodec_decode_video failed"); + avcodec_close(&av_context); + return NULL; + } + ret=allocb(avpicture_get_size(PIX_FMT_YUV420P,reqsize->width,reqsize->height),0); + ret->b_wptr=ret->b_datap->db_lim; + avpicture_fill(&dest,ret->b_rptr,PIX_FMT_YUV420P,reqsize->width,reqsize->height); + + sws_ctx=sws_getContext(av_context.width,av_context.height,PIX_FMT_YUV420P, + reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR, + NULL, NULL, NULL); + if (sws_scale(sws_ctx,orig.data,orig.linesize,0,av_context.height,dest.data,dest.linesize)<0){ + ms_error("jpeg2yuv: sws_scale() failed."); + } + sws_freeContext(sws_ctx); + avcodec_close(&av_context); + return ret; +} + +mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){ + mblk_t *m=NULL; + struct stat statbuf; + uint8_t *jpgbuf; +#if !defined(_MSC_VER) + int fd=open(jpgpath,O_RDONLY); +#else + int fd=_open(jpgpath,O_RDONLY); +#endif + if (fd!=-1){ + fstat(fd,&statbuf); + jpgbuf=(uint8_t*)alloca(statbuf.st_size); +#if !defined(_MSC_VER) + read(fd,jpgbuf,statbuf.st_size); +#else + _read(fd,jpgbuf,statbuf.st_size); +#endif + m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize); + }else{ + ms_error("Cannot load %s",jpgpath); + } + return m; +} + +#ifndef PACKAGE_DATA_DIR +#define PACKAGE_DATA_DIR "." +#endif + +#ifndef NOWEBCAM_JPG +#define NOWEBCAM_JPG "nowebcamCIF" +#endif + +mblk_t *ms_load_nowebcam(MSVideoSize *reqsize, int idx){ + char tmp[256]; + if (idx<0) + snprintf(tmp, sizeof(tmp), "%s/images/%s.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG); + else + snprintf(tmp, sizeof(tmp), "%s/images/%s%i.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG, idx); + return ms_load_jpeg_as_yuv(tmp,reqsize); +} + +typedef struct _SIData{ + MSVideoSize vsize; + int index; + uint64_t lasttime; + mblk_t *pic; +}SIData; + +void static_image_init(MSFilter *f){ + SIData *d=(SIData*)ms_new(SIData,1); + d->vsize.width=MS_VIDEO_SIZE_CIF_W; + d->vsize.height=MS_VIDEO_SIZE_CIF_H; + d->index=-1; + d->lasttime=0; + d->pic=NULL; + f->data=d; +} + +void static_image_uninit(MSFilter *f){ + ms_free(f->data); +} + +void static_image_preprocess(MSFilter *f){ + SIData *d=(SIData*)f->data; + d->pic=ms_load_nowebcam(&d->vsize,d->index); +} + +void static_image_process(MSFilter *f){ + SIData *d=(SIData*)f->data; + /*output a frame every second*/ + if ((f->ticker->time - d->lasttime>1000) || d->lasttime==0){ + if (d->pic) ms_queue_put(f->outputs[0],dupb(d->pic)); + d->lasttime=f->ticker->time; + } +} + +void static_image_postprocess(MSFilter *f){ + SIData *d=(SIData*)f->data; + if (d->pic) { + freemsg(d->pic); + d->pic=NULL; + } +} + +int static_image_set_vsize(MSFilter *f, void* data){ + SIData *d=(SIData*)f->data; + d->vsize=*(MSVideoSize*)data; + return 0; +} + +int static_image_get_pix_fmt(MSFilter *f, void *data){ + *(MSPixFmt*)data=MS_YUV420P; + return 0; +} + +MSFilterMethod static_image_methods[]={ + { MS_FILTER_SET_VIDEO_SIZE, static_image_set_vsize }, + { MS_FILTER_GET_PIX_FMT, static_image_get_pix_fmt }, + { 0,0 } +}; + +MSFilterDesc ms_static_image_desc={ + MS_STATIC_IMAGE_ID, + "MSStaticImage", + "A filter that outputs a static image.", + MS_FILTER_OTHER, + NULL, + 0, + 1, + static_image_init, + static_image_preprocess, + static_image_process, + static_image_postprocess, + static_image_uninit, + static_image_methods +}; + +MS_FILTER_DESC_EXPORT(ms_static_image_desc) + +static void static_image_detect(MSWebCamManager *obj); + +static void static_image_cam_init(MSWebCam *cam){ + cam->name=ms_strdup("Static picture"); +} + + +static MSFilter *static_image_create_reader(MSWebCam *obj){ + return ms_filter_new_from_desc(&ms_static_image_desc); +} + +MSWebCamDesc static_image_desc={ + "StaticImage", + &static_image_detect, + &static_image_cam_init, + &static_image_create_reader, + NULL +}; + +static void static_image_detect(MSWebCamManager *obj){ + MSWebCam *cam=ms_web_cam_new(&static_image_desc); + ms_web_cam_manager_add_cam(obj,cam); +} + diff --git a/linphone/mediastreamer2/src/nowebcam.h b/linphone/mediastreamer2/src/nowebcam.h new file mode 100644 index 000000000..b77ec505d --- /dev/null +++ b/linphone/mediastreamer2/src/nowebcam.h @@ -0,0 +1,28 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#ifndef nowebcam_h +#define nowebcam_h + +mblk_t *ms_load_jpeg_as_yuv(const char *path, MSVideoSize *reqsize); +mblk_t *ms_load_nowebcam(MSVideoSize *reqsize, int idx); + +#endif + diff --git a/linphone/mediastreamer2/src/nowebcamCIF.jpg b/linphone/mediastreamer2/src/nowebcamCIF.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ab8bdc2ace897259946d67357523a6c9796cd3a GIT binary patch literal 14247 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 + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ALLOCA_H /*FreeBSD does not have alloca.h*/ +#include +#endif + +MSFilter *ms_oss_read_new(MSSndCard *card); +MSFilter *ms_oss_write_new(MSSndCard *card); + +static int oss_open(const char *devname, int bits,int stereo, int rate, int *minsz) +{ + int fd; + int p=0,cond=0; + int i=0; + int min_size=0,blocksize=512; + int err; + int frag; + audio_buf_info info; + + //g_message("opening sound device"); + fd=open(devname,O_RDWR|O_NONBLOCK); + if (fd<0) return -EWOULDBLOCK; + /* unset nonblocking mode */ + /* We wanted non blocking open but now put it back to normal ; thanks Xine !*/ + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK); + + /* reset is maybe not needed but takes time*/ + /*ioctl(fd, SNDCTL_DSP_RESET, 0); */ + + /* This code is used to limit the internal buffer of the sound + card so that no internal delay can occur in the sound card */ + frag = ( ( 32767 << 16 ) | 7 ); + if( ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &frag ) ) { + ms_warning("oss_open: can't set fragment size:%s.",strerror(errno)); + } + + p=AFMT_S16_NE; + + err=ioctl(fd,SNDCTL_DSP_SETFMT,&p); + if (err<0){ + ms_warning("oss_open: can't set sample format:%s.",strerror(errno)); + } + + + p = bits; /* 16 bits */ + err=ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &p); + if (err<0){ + ms_warning("oss_open: can't set sample size to %i:%s.",bits,strerror(errno)); + } + + p = rate; /* rate in khz*/ + err=ioctl(fd, SNDCTL_DSP_SPEED, &p); + if (err<0){ + ms_warning("oss_open: can't set sample rate to %i:%s.",rate,strerror(errno)); + } + + p = stereo; /* stereo or not */ + err=ioctl(fd, SNDCTL_DSP_STEREO, &p); + if (err<0){ + ms_warning("oss_open: can't set mono/stereo mode:%s.",strerror(errno)); + } + + if (rate==16000) blocksize=4096; /* oss emulation is not very good at 16khz */ + else blocksize=blocksize*(rate/8000); + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + + /* try to subdivide BLKSIZE to reach blocksize if necessary */ + if (min_size>blocksize) + { + cond=1; + p=min_size/blocksize; + while(cond) + { + i=ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &p); + //printf("SUB_DIVIDE said error=%i,errno=%i\n",i,errno); + if ((i==0) || (p==1)) cond=0; + else p=p/2; + } + } + ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size); + if (min_size>blocksize) + { + ms_warning("dsp block size set to %i.",min_size); + }else{ + /* no need to access the card with less latency than needed*/ + min_size=blocksize; + } + + ms_message("/dev/dsp opened: rate=%i,bits=%i,stereo=%i blocksize=%i.", + rate,bits,stereo,min_size); + + if( ioctl( fd, SNDCTL_DSP_GETISPACE, &info ) == -1 ) { + ms_warning("oss_open: can't get ispace:%s.",strerror(errno)); + } + else{ + ms_warning("oss_open: audio buffer size: %i.", info.fragsize * sizeof( short )); + } + + + /* start recording !!! Alex */ + { + int fl,res; + + fl=PCM_ENABLE_OUTPUT|PCM_ENABLE_INPUT; + res=ioctl(fd, SNDCTL_DSP_SETTRIGGER, &fl); + if (res<0) ms_warning("OSS_TRIGGER: %s",strerror(errno)); + } + *minsz=min_size; + return fd; +} + +typedef struct OssData{ + char *pcmdev; + char *mixdev; + int pcmfd; + int rate; + int bits; + ms_thread_t thread; + ms_mutex_t mutex; + queue_t rq; + MSBufferizer * bufferizer; + bool_t read_started; + bool_t write_started; + bool_t stereo; +} OssData; + +static void oss_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent) +{ + OssData *d=(OssData*)card->data; + int p,mix_fd; + int osscmd; + if (d->mixdev==NULL) return; + switch(e){ + case MS_SND_CARD_MASTER: + osscmd=SOUND_MIXER_VOLUME; + break; + case MS_SND_CARD_CAPTURE: + osscmd=SOUND_MIXER_IGAIN; + break; + case MS_SND_CARD_PLAYBACK: + osscmd=SOUND_MIXER_PCM; + break; + default: + ms_warning("oss_card_set_level: unsupported command."); + return; + } + p=(((int)percent)<<8 | (int)percent); + mix_fd = open(d->mixdev, O_WRONLY); + ioctl(mix_fd,MIXER_WRITE(osscmd), &p); + close(mix_fd); +} + +static int oss_get_level(MSSndCard *card, MSSndCardMixerElem e) +{ + OssData *d=(OssData*)card->data; + int p=0,mix_fd; + int osscmd; + if (d->mixdev==NULL) return -1; + switch(e){ + case MS_SND_CARD_MASTER: + osscmd=SOUND_MIXER_VOLUME; + break; + case MS_SND_CARD_CAPTURE: + osscmd=SOUND_MIXER_IGAIN; + break; + case MS_SND_CARD_PLAYBACK: + osscmd=SOUND_MIXER_PCM; + break; + default: + ms_warning("oss_card_get_level: unsupported command."); + return -1; + } + mix_fd = open(d->mixdev, O_RDONLY); + ioctl(mix_fd,MIXER_READ(osscmd), &p); + close(mix_fd); + return p>>8; +} + +static void oss_set_source(MSSndCard *card, MSSndCardCapture source) +{ + OssData *d=(OssData*)card->data; + int p=0; + int mix_fd; + if (d->mixdev==NULL) return; + + switch(source){ + case MS_SND_CARD_MIC: + p = 1 << SOUND_MIXER_MIC; + break; + case MS_SND_CARD_LINE: + p = 1 << SOUND_MIXER_LINE; + break; + } + + mix_fd = open(d->mixdev, O_WRONLY); + ioctl(mix_fd, SOUND_MIXER_WRITE_RECSRC, &p); + close(mix_fd); +} + +static void oss_init(MSSndCard *card){ + OssData *d=ms_new(OssData,1); + d->pcmdev=NULL; + d->mixdev=NULL; + d->pcmfd=-1; + d->read_started=FALSE; + d->write_started=FALSE; + d->bits=16; + d->rate=8000; + d->stereo=FALSE; + qinit(&d->rq); + d->bufferizer=ms_bufferizer_new(); + ms_mutex_init(&d->mutex,NULL); + card->data=d; +} + +static void oss_uninit(MSSndCard *card){ + OssData *d=(OssData*)card->data; + if (d->pcmdev!=NULL) ms_free(d->pcmdev); + if (d->mixdev!=NULL) ms_free(d->mixdev); + ms_bufferizer_destroy(d->bufferizer); + flushq(&d->rq,0); + ms_mutex_destroy(&d->mutex); + ms_free(d); +} + +#define DSP_NAME "/dev/dsp" +#define MIXER_NAME "/dev/mixer" + +static void oss_detect(MSSndCardManager *m); +static MSSndCard *oss_duplicate(MSSndCard *obj); + +MSSndCardDesc oss_card_desc={ + .driver_type="OSS", + .detect=oss_detect, + .init=oss_init, + .set_level=oss_set_level, + .get_level=oss_get_level, + .set_capture=oss_set_source, + .create_reader=ms_oss_read_new, + .create_writer=ms_oss_write_new, + .uninit=oss_uninit, + .duplicate=oss_duplicate +}; + +static MSSndCard *oss_duplicate(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&oss_card_desc); + OssData *dcard=(OssData*)card->data; + OssData *dobj=(OssData*)obj->data; + dcard->pcmdev=ms_strdup(dobj->pcmdev); + dcard->mixdev=ms_strdup(dobj->mixdev); + card->name=ms_strdup(obj->name); + return card; +} + +static MSSndCard *oss_card_new(const char *pcmdev, const char *mixdev){ + MSSndCard *card=ms_snd_card_new(&oss_card_desc); + OssData *d=(OssData*)card->data; + d->pcmdev=ms_strdup(pcmdev); + d->mixdev=ms_strdup(mixdev); + card->name=ms_strdup(pcmdev); + return card; +} + +static void oss_detect(MSSndCardManager *m){ + int i; + char pcmdev[sizeof(DSP_NAME)+3]; + char mixdev[sizeof(MIXER_NAME)+3]; + if (access(DSP_NAME,F_OK)==0){ + MSSndCard *card=oss_card_new(DSP_NAME,MIXER_NAME); + ms_snd_card_manager_add_card(m,card); + card=oss_card_new(DSP_NAME,MIXER_NAME); + ms_snd_card_manager_add_card(m,card); + } + for(i=0;i<10;i++){ + snprintf(pcmdev,sizeof(pcmdev),"%s%i",DSP_NAME,i); + snprintf(mixdev,sizeof(mixdev),"%s%i",MIXER_NAME,i); + if (access(pcmdev,F_OK)==0){ + MSSndCard *card=oss_card_new(pcmdev,mixdev); + ms_snd_card_manager_add_card(m,card); + } + } +} + +static void * oss_thread(void *p){ + MSSndCard *card=(MSSndCard*)p; + OssData *d=(OssData*)card->data; + int bsize=0; + uint8_t *rtmpbuff=NULL; + uint8_t *wtmpbuff=NULL; + int err; + mblk_t *rm=NULL; + d->pcmfd=oss_open(d->pcmdev,d->bits,d->stereo,d->rate,&bsize); + if (d->pcmfd>=0){ + rtmpbuff=(uint8_t*)malloc(bsize); + wtmpbuff=(uint8_t*)malloc(bsize); + if(rtmpbuff == NULL || wtmpbuff == NULL) { + free(rtmpbuff); + free(wtmpbuff); + return NULL; + } + } + while(d->read_started || d->write_started){ + if (d->pcmfd>=0){ + if (d->read_started){ + struct timeval timeout; + fd_set read_fds; + audio_buf_info info; + if (rm==NULL) rm=allocb(bsize,0); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO( &read_fds ); + FD_SET( d->pcmfd, &read_fds ); + if( select( d->pcmfd + 1, &read_fds, NULL, NULL, &timeout ) == -1 ) { + } + if (FD_ISSET( d->pcmfd, &read_fds ) && ioctl( d->pcmfd, SNDCTL_DSP_GETISPACE, &info ) != -1) + { + if (info.bytes>=bsize) + { + err=read(d->pcmfd,rm->b_wptr,bsize); + if (err<0){ + ms_warning("Fail to read %i bytes from soundcard: %s", + bsize,strerror(errno)); + }else{ + rm->b_wptr+=err; + ms_mutex_lock(&d->mutex); + putq(&d->rq,rm); + ms_mutex_unlock(&d->mutex); + rm=NULL; + } + } + else + { + timeout.tv_sec = 0; + timeout.tv_usec = 5000; + select(0, 0, NULL, NULL, &timeout ); + } + } + else + { + timeout.tv_sec = 0; + timeout.tv_usec = 5000; + select(0, 0, NULL, NULL, &timeout ); + } + }else { + int sz = read(d->pcmfd,rtmpbuff,bsize); + if( sz!=bsize) ms_warning("sound device read returned %i !",sz); + } + if (d->write_started){ + + audio_buf_info info; + if( ms_bufferizer_get_avail(d->bufferizer)>=bsize && ioctl( d->pcmfd, SNDCTL_DSP_GETOSPACE, &info ) == 0 ) { + if( info.fragstotal - info.fragments > 15 ) { + static int c=0; + /* drop the fragment if the buffer starts to fill up */ + /* we got too much data: I prefer to empty the incoming buffer */ + while (ms_bufferizer_get_avail(d->bufferizer)>bsize*4){ + ms_mutex_lock(&d->mutex); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + ms_mutex_unlock(&d->mutex); + c=c+err*4; + ms_warning("drop fragment when buffer gets too much data (%i - discarded:%i)", info.fragstotal - info.fragments, c); + if (err==0) + break; + } + + }else { + ms_mutex_lock(&d->mutex); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + ms_mutex_unlock(&d->mutex); + err=write(d->pcmfd,wtmpbuff,bsize); + if (err<0){ + ms_warning("Fail to write %i bytes from soundcard: %s", + bsize,strerror(errno)); + } + } + } + + }else { + int sz; + memset(wtmpbuff,0,bsize); + sz = write(d->pcmfd,wtmpbuff,bsize); + if( sz!=bsize) ms_warning("sound device write returned %i !",sz); + } + }else usleep(20000); + } + if (d->pcmfd>=0) { + close(d->pcmfd); + d->pcmfd=-1; + } + free(rtmpbuff); + free(wtmpbuff); + if (rm!=NULL) freemsg(rm); + /*reset to default parameters */ + d->bits=16; + d->rate=8000; + d->stereo=FALSE; + return NULL; +} + +static void oss_start_r(MSSndCard *card){ + OssData *d=(OssData*)card->data; + ms_mutex_lock(&d->mutex); + if (d->read_started==FALSE && d->write_started==FALSE){ + d->read_started=TRUE; + ms_thread_create(&d->thread,NULL,oss_thread,card); + }else d->read_started=TRUE; + flushq(&d->rq,0); + ms_mutex_unlock(&d->mutex); +} + +static void oss_stop_r(MSSndCard *card){ + OssData *d=(OssData*)card->data; + d->read_started=FALSE; + if (d->write_started==FALSE){ + ms_thread_join(d->thread,NULL); + } +} + +static void _flush_buffer(MSBufferizer *obj){ + flushq(&obj->q,0); + obj->size=0; +} + +static void oss_start_w(MSSndCard *card){ + OssData *d=(OssData*)card->data; + ms_mutex_lock(&d->mutex); + if (d->read_started==FALSE && d->write_started==FALSE){ + d->write_started=TRUE; + ms_thread_create(&d->thread,NULL,oss_thread,card); + }else{ + d->write_started=TRUE; + } + _flush_buffer(d->bufferizer); + ms_mutex_unlock(&d->mutex); +} + +static void oss_stop_w(MSSndCard *card){ + OssData *d=(OssData*)card->data; + d->write_started=FALSE; + if (d->read_started==FALSE){ + ms_thread_join(d->thread,NULL); + } +} + +static mblk_t *oss_get(MSSndCard *card){ + OssData *d=(OssData*)card->data; + mblk_t *m; + ms_mutex_lock(&d->mutex); + m=getq(&d->rq); + ms_mutex_unlock(&d->mutex); + return m; +} + +static void oss_put(MSSndCard *card, mblk_t *m){ + OssData *d=(OssData*)card->data; + ms_mutex_lock(&d->mutex); + ms_bufferizer_put(d->bufferizer,m); + ms_mutex_unlock(&d->mutex); +} + + +static void oss_read_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + oss_start_r(card); +} + +static void oss_read_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + oss_stop_r(card); +} + +static void oss_read_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=oss_get(card))!=NULL){ + ms_queue_put(f->outputs[0],m); + } +} + +static void oss_write_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + oss_start_w(card); +} + +static void oss_write_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + oss_stop_w(card); +} + +static void oss_write_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + oss_put(card,m); + } +} + +static int set_rate(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + OssData *d=(OssData*)card->data; + d->rate=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + OssData *d=(OssData*)card->data; + d->stereo=(*((int*)arg)==2); + return 0; +} + +static MSFilterMethod oss_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { 0 , NULL } +}; + +MSFilterDesc oss_read_desc={ + .id=MS_OSS_READ_ID, + .name="MSOssRead", + .text="Sound capture filter for OSS drivers", + .category=MS_FILTER_OTHER, + .ninputs=0, + .noutputs=1, + .preprocess=oss_read_preprocess, + .process=oss_read_process, + .postprocess=oss_read_postprocess, + .methods=oss_methods +}; + + +MSFilterDesc oss_write_desc={ + .id=MS_OSS_WRITE_ID, + .name="MSOssWrite", + .text="Sound playback filter for OSS drivers", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=0, + .preprocess=oss_write_preprocess, + .process=oss_write_process, + .postprocess=oss_write_postprocess, + .methods=oss_methods +}; + +MSFilter *ms_oss_read_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&oss_read_desc); + f->data=card; + return f; +} + + +MSFilter *ms_oss_write_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&oss_write_desc); + f->data=card; + return f; +} + +MS_FILTER_DESC_EXPORT(oss_read_desc) +MS_FILTER_DESC_EXPORT(oss_write_desc) diff --git a/linphone/mediastreamer2/src/pasnd.c b/linphone/mediastreamer2/src/pasnd.c new file mode 100644 index 000000000..c4b411faa --- /dev/null +++ b/linphone/mediastreamer2/src/pasnd.c @@ -0,0 +1,594 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" + +#include "portaudio.h" + +MSFilter *ms_pasnd_read_new(MSSndCard *card); +MSFilter *ms_pasnd_write_new(MSSndCard *card); + +typedef struct PASndData{ + char *pcmdev; + char *mixdev; + int sound_err; + char waveoutbuffer[30][3200]; + PaStream *waveoutdev; + + PaStream *waveindev; + + int rate; + int bits; + ms_thread_t thread; + ms_mutex_t mutex; + queue_t rq; + MSBufferizer * bufferizer; + bool_t read_started; + bool_t write_started; + bool_t stereo; + + SpeexPreprocessState *pst; +} PASndData; + +int SpeakerCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) +{ + PASndData *device = (PASndData*)userData; + uint8_t *wtmpbuff=NULL; + int err; + + memset(outputBuffer,0, framesPerBuffer*2); + if (!device->read_started && !device->write_started) + { + return 0; + } + + wtmpbuff=(uint8_t*)alloca(framesPerBuffer*2); + + memset(outputBuffer,0, framesPerBuffer*2); + + ms_mutex_lock(&device->mutex); + + /* remove extra buffer when latency is increasing: + this often happen with USB device */ + if (device->bufferizer->size>=320*6){ + ms_warning("Extra data for sound card (total:%i %ims)", + device->bufferizer->size, (device->bufferizer->size*20)/320); + err=ms_bufferizer_read(device->bufferizer,wtmpbuff, framesPerBuffer*2); + err=ms_bufferizer_read(device->bufferizer,wtmpbuff, framesPerBuffer*2); + err=ms_bufferizer_read(device->bufferizer,wtmpbuff, framesPerBuffer*2); + err=ms_bufferizer_read(device->bufferizer,wtmpbuff, framesPerBuffer*2); + err=ms_bufferizer_read(device->bufferizer,wtmpbuff, framesPerBuffer*2); + ms_warning("Extra data for sound card removed (total:%i %ims)", + device->bufferizer->size, (device->bufferizer->size*20)/320); + } + + err=ms_bufferizer_read(device->bufferizer,wtmpbuff,framesPerBuffer*2); + ms_mutex_unlock(&device->mutex); + if (err==framesPerBuffer*2) + { + memcpy (outputBuffer, wtmpbuff, framesPerBuffer*2); + } + + return 0; +} + +int WaveInCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) +{ + PASndData *device = (PASndData*)userData; + + if (!device->read_started && !device->write_started) + { + return 0; + } + + ms_mutex_lock(&device->mutex); + if (device->read_started) + { + int vad; + mblk_t *rm=NULL; + if (rm==NULL) rm=allocb(framesPerBuffer*2,0); + memcpy(rm->b_wptr,inputBuffer, framesPerBuffer*2); + + if (device->pst!=NULL) + { + vad = speex_preprocess(device->pst, (spx_int16_t *)rm->b_wptr, NULL); +#if 0 + if (vad!=1) + ms_message("WaveInCallback : %d", vad); +#endif + } + + rm->b_wptr+=framesPerBuffer*2; + + putq(&device->rq,rm); + rm=NULL; + } + ms_mutex_unlock(&device->mutex); + + return 0; +} + +static int pasnd_open(PASndData *device, int devnumber, int bits,int stereo, int rate, int *minsz) +{ + PaStreamParameters outputParameters; + PaStreamParameters inputParameters; + PaError err; + + const PaHostApiInfo *pa_hai = Pa_GetHostApiInfo(Pa_GetDefaultHostApi()); + + ms_warning("pasnd_open : opening default input device: name=%s (%i)", + pa_hai->name, pa_hai->defaultInputDevice); + ms_warning("pasnd_open : opening default output device name=%s (%i)", + pa_hai->name, pa_hai->defaultOutputDevice); + + outputParameters.device = devnumber; /* default output device */ + outputParameters.device = pa_hai->defaultOutputDevice; + outputParameters.channelCount = 1; /* stereo output */ + outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */ + outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + err = Pa_OpenStream( + &device->waveoutdev, /* stream */ + NULL, /* no input */ + &outputParameters, // + rate, // double sampleRate + 160*(rate/8000), //unsigned long framesPerBuffer + paClipOff, + SpeakerCallback, //PortAudioCallback *callback + (void *) device); //void *userData + + if (err != paNoError) + { + ms_warning("Failed to open out device. (Pa_OpenDefaultStream:0x%i)", err); + return -1; + } + + inputParameters.device = devnumber; /* default input device */ + inputParameters.device = pa_hai->defaultInputDevice; + inputParameters.channelCount = 1; /* stereo input */ + inputParameters.sampleFormat = paInt16; /* 32 bit floating point input */ + inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; + inputParameters.hostApiSpecificStreamInfo = NULL; + + err = Pa_OpenStream( + &device->waveindev, //PortAudioStream** stream + &inputParameters, /* input param*/ + NULL, /* output param */ + rate, // double sampleRate + 160*(rate/8000), //unsigned long framesPerBuffer + paClipOff, + WaveInCallback, //PortAudioCallback *callback + (void *) device); //void *userData + + + if (err != paNoError) + { + ms_warning("Failed to open in device. (Pa_OpenDefaultStream:0x%i)", err); + return -1; + } + + err = Pa_StartStream( device->waveoutdev ); + if( err != paNoError ) + { + ms_warning("Failed to start out device. (Pa_StartStream:0x%i)", err); + return -1; + } + + device->pst = speex_preprocess_state_init((device->rate/8000 * 320)/2, device->rate); + if (device->pst!=NULL) { + float f; + int i=1; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_VAD, &i); + i=1; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=0; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_AGC, &i); + f=8000; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); + i=0; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB, &i); + f=.4; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=.3; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + } + + err = Pa_StartStream( device->waveindev ); + if( err != paNoError ) + { + ms_warning("Failed to start in device: trying default device. (Pa_StartStream:0x%i)", err); + return -1; + } + + *minsz=device->rate/8000 * 320; + return 0; +} + +static void pasnd_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent) +{ + PASndData *d=(PASndData*)card->data; + + if (d->mixdev==NULL) return; + switch(e){ + case MS_SND_CARD_MASTER: + return; + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("pasnd_card_set_level: unsupported command."); + return; + } +} + +static int pasnd_get_level(MSSndCard *card, MSSndCardMixerElem e) +{ + PASndData *d=(PASndData*)card->data; + + if (d->mixdev==NULL) return -1; + switch(e){ + case MS_SND_CARD_MASTER: + return 60; + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("pasnd_card_get_level: unsupported command."); + return -1; + } + return -1; +} + +static void pasnd_set_source(MSSndCard *card, MSSndCardCapture source) +{ + PASndData *d=(PASndData*)card->data; + if (d->mixdev==NULL) return; + + switch(source){ + case MS_SND_CARD_MIC: + break; + case MS_SND_CARD_LINE: + break; + } +} + +static void pasnd_init(MSSndCard *card){ + PASndData *d=ms_new(PASndData,1); + memset(d, 0, sizeof(PASndData)); + d->pcmdev=NULL; + d->mixdev=NULL; + d->sound_err=-1; /* not opened */ + d->read_started=FALSE; + d->write_started=FALSE; + d->bits=16; + d->rate=8000; + d->stereo=FALSE; + qinit(&d->rq); + d->bufferizer=ms_bufferizer_new(); + ms_mutex_init(&d->mutex,NULL); + card->data=d; + d->pst=0; +} + +static void pasnd_uninit(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + if (d==NULL) + return; + if (d->pcmdev!=NULL) ms_free(d->pcmdev); + if (d->mixdev!=NULL) ms_free(d->mixdev); + ms_bufferizer_destroy(d->bufferizer); + flushq(&d->rq,0); + + ms_mutex_destroy(&d->mutex); + + if (d->pst!=NULL) + speex_preprocess_state_destroy(d->pst); + + ms_free(d); +} + +#define DSP_NAME "/dev/dsp" +#define MIXER_NAME "/dev/mixer" + +static void pasnd_detect(MSSndCardManager *m); +static MSSndCard *pasnd_duplicate(MSSndCard *obj); + +MSSndCardDesc pasnd_card_desc={ + "PASND", + pasnd_detect, + pasnd_init, + pasnd_set_level, + pasnd_get_level, + pasnd_set_source, + ms_pasnd_read_new, + ms_pasnd_write_new, + pasnd_uninit, + pasnd_duplicate +}; + +static MSSndCard *pasnd_duplicate(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&pasnd_card_desc); + PASndData *dcard=(PASndData*)card->data; + PASndData *dobj=(PASndData*)obj->data; + dcard->pcmdev=ms_strdup(dobj->pcmdev); + dcard->mixdev=ms_strdup(dobj->mixdev); + card->name=ms_strdup(obj->name); + return card; +} + +static MSSndCard *pasnd_card_new(const char *pcmdev, const char *mixdev){ + MSSndCard *card=ms_snd_card_new(&pasnd_card_desc); + PASndData *d=(PASndData*)card->data; + d->pcmdev=ms_strdup(pcmdev); + d->mixdev=ms_strdup(mixdev); + card->name=ms_strdup(pcmdev); + return card; +} + +static void pasnd_detect(MSSndCardManager *m){ + int err = 0; + unsigned int numDevices; + const PaDeviceInfo *pdi; + char pcmdev[1024]; + char mixdev[1024]; + int i; + + err = Pa_Initialize(); + if( err != paNoError ) + { + ms_warning("PortAudio error: %s\n", Pa_GetErrorText( err ) ); + return; + } + + numDevices = Pa_GetDeviceCount(); + + for( i=0; iname); + snprintf(mixdev,sizeof(mixdev),"%s",pdi->name); + if (i == 0) + { + card=pasnd_card_new(pcmdev,mixdev); + ms_snd_card_manager_add_card(m,card); + } + card=pasnd_card_new(pcmdev,mixdev); + ms_snd_card_manager_add_card(m,card); + } + } +} + +static void pasnd_closedriver(PASndData *d) +{ + if (d->sound_err==0) { + + int err = Pa_StopStream( d->waveindev ); + if( err != paNoError ) + { + ms_warning("Failed to stop device. (Pa_StopStream:0x%i)", err); + } + + err = Pa_CloseStream( d->waveindev); + if( err != paNoError ) + { + ms_warning("failed to close recording sound card (Pa_CloseStream:0x%i)", err); + } + else + { + ms_message("successfully closed recording sound card"); + } + + err = Pa_StopStream( d->waveoutdev ); + if( err != paNoError ) + { + ms_warning("Failed to stop device. (Pa_StopStream:0x%i)", err); + } + + err = Pa_CloseStream( d->waveoutdev ); + if( err != paNoError ) + { + ms_error("failed to stop recording sound card (Pa_CloseStream:0x%i)", err); + } + else + { + ms_message("successfully stopped recording sound card"); + } + + + d->sound_err=-1; + } +} + +static void pasnd_start_r(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + if (d->read_started==FALSE && d->write_started==FALSE){ + int bsize=0; + d->read_started=TRUE; + d->sound_err=pasnd_open(d, 0, d->bits,d->stereo,d->rate,&bsize); + }else d->read_started=TRUE; +} + +static void pasnd_stop_r(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + d->read_started=FALSE; + if (d->write_started==FALSE){ + /* ms_thread_join(d->thread,NULL); */ + pasnd_closedriver(d); + } +} + +static void pasnd_start_w(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + if (d->read_started==FALSE && d->write_started==FALSE){ + int bsize=0; + d->write_started=TRUE; + d->sound_err=pasnd_open(d, 0, d->bits,d->stereo,d->rate,&bsize); + }else{ + d->write_started=TRUE; + } +} + +static void pasnd_stop_w(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + d->write_started=FALSE; + if (d->read_started==FALSE){ + /* ms_thread_join(d->thread,NULL); */ + pasnd_closedriver(d); + } +} + +static mblk_t *pasnd_get(MSSndCard *card){ + PASndData *d=(PASndData*)card->data; + mblk_t *m; + ms_mutex_lock(&d->mutex); + m=getq(&d->rq); + ms_mutex_unlock(&d->mutex); + return m; +} + +static void pasnd_put(MSSndCard *card, mblk_t *m){ + PASndData *d=(PASndData*)card->data; + ms_mutex_lock(&d->mutex); + ms_bufferizer_put(d->bufferizer,m); + ms_mutex_unlock(&d->mutex); +} + + +static void pasnd_read_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + pasnd_start_r(card); +} + +static void pasnd_read_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + pasnd_stop_r(card); +} + +static void pasnd_read_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=pasnd_get(card))!=NULL){ + ms_queue_put(f->outputs[0],m); + } +} + +static void pasnd_write_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + pasnd_start_w(card); +} + +static void pasnd_write_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + pasnd_stop_w(card); +} + +static void pasnd_write_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + pasnd_put(card,m); + } +} + +static int set_rate(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + PASndData *d=(PASndData*)card->data; + d->rate=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + PASndData *d=(PASndData*)card->data; + d->stereo=(*((int*)arg)==2); + return 0; +} + +static MSFilterMethod pasnd_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { 0 , NULL } +}; + +MSFilterDesc pasnd_read_desc={ + MS_PASND_READ_ID, + "MSPasndRead", + "Sound capture filter for Port Audio Sound drivers", + MS_FILTER_OTHER, + NULL, + 0, + 1, + NULL, + pasnd_read_preprocess, + pasnd_read_process, + pasnd_read_postprocess, + NULL, + pasnd_methods +}; + + +MSFilterDesc pasnd_write_desc={ + MS_PASND_WRITE_ID, + "MSPasndWrite", + "Sound playback filter for Port Audio Sound drivers", + MS_FILTER_OTHER, + NULL, + 1, + 0, + NULL, + pasnd_write_preprocess, + pasnd_write_process, + pasnd_write_postprocess, + NULL, + pasnd_methods +}; + +MSFilter *ms_pasnd_read_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&pasnd_read_desc); + f->data=card; + return f; +} + + +MSFilter *ms_pasnd_write_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&pasnd_write_desc); + f->data=card; + return f; +} + +MS_FILTER_DESC_EXPORT(pasnd_read_desc) +MS_FILTER_DESC_EXPORT(pasnd_write_desc) diff --git a/linphone/mediastreamer2/src/pixconv.c b/linphone/mediastreamer2/src/pixconv.c new file mode 100644 index 000000000..a6bf135bc --- /dev/null +++ b/linphone/mediastreamer2/src/pixconv.c @@ -0,0 +1,200 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" + +#include "ffmpeg-priv.h" + +extern void ms_ffmpeg_check_init(); + +#ifndef PIX_FMT_YUYV422 +#define PIX_FMT_YUYV422 PIX_FMT_YUV422 +#endif + +int ms_pix_fmt_to_ffmpeg(MSPixFmt fmt){ + switch(fmt){ + case MS_RGB24: + return PIX_FMT_RGB24; + case MS_YUV420P: + return PIX_FMT_YUV420P; + case MS_YUYV: + return PIX_FMT_YUYV422; + case MS_UYVY: + return PIX_FMT_UYVY422; + case MS_YUY2: + return PIX_FMT_YUYV422; /* <- same as MS_UYVY */ + default: + ms_fatal("format not supported."); + return -1; + } + return -1; +} + +MSPixFmt ffmpeg_pix_fmt_to_ms(int fmt){ + switch(fmt){ + case PIX_FMT_RGB24: + return MS_RGB24; + case PIX_FMT_YUV420P: + return MS_YUV420P; + case PIX_FMT_YUYV422: + return MS_YUYV; + case PIX_FMT_UYVY422: + return MS_UYVY; /* same as MS_YUY2 */ + default: + ms_fatal("format not supported."); + return MS_YUV420P; /* default */ + } + return MS_YUV420P; /* default */ +} + +typedef struct PixConvState{ + YuvBuf outbuf; + mblk_t *yuv_msg; + struct SwsContext *sws_ctx; + MSVideoSize size; + enum PixelFormat in_fmt; + enum PixelFormat out_fmt; +}PixConvState; + +static void pixconv_init(MSFilter *f){ + PixConvState *s=(PixConvState *)ms_new(PixConvState,1); + s->yuv_msg=NULL; + s->size.width = MS_VIDEO_SIZE_CIF_W; + s->size.height = MS_VIDEO_SIZE_CIF_H; + s->in_fmt=PIX_FMT_YUV420P; + s->out_fmt=PIX_FMT_YUV420P; + s->sws_ctx=NULL; + f->data=s; + ms_ffmpeg_check_init(); +} + +static void pixconv_uninit(MSFilter *f){ + PixConvState *s=(PixConvState*)f->data; + if (s->sws_ctx!=NULL){ + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + if (s->yuv_msg!=NULL) freemsg(s->yuv_msg); + ms_free(s); +} + +static mblk_t * pixconv_alloc_mblk(PixConvState *s){ + if (s->yuv_msg!=NULL){ + int ref=s->yuv_msg->b_datap->db_ref; + if (ref==1){ + return dupmsg(s->yuv_msg); + }else{ + /*the last msg is still referenced by somebody else*/ + ms_message("Somebody still retaining yuv buffer (ref=%i)",ref); + freemsg(s->yuv_msg); + s->yuv_msg=NULL; + } + } + s->yuv_msg=yuv_buf_alloc(&s->outbuf,s->size.width,s->size.height); + return dupmsg(s->yuv_msg); +} + +static void pixconv_process(MSFilter *f){ + mblk_t *im,*om; + PixConvState *s=(PixConvState*)f->data; + + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + if (s->in_fmt==s->out_fmt){ + om=im; + }else{ + AVPicture inbuf; + avpicture_fill(&inbuf,im->b_rptr,s->in_fmt,s->size.width,s->size.height); + om=pixconv_alloc_mblk(s); + if (s->sws_ctx==NULL){ + s->sws_ctx=sws_getContext(s->size.width,s->size.height, + s->in_fmt,s->size.width,s->size.height, + s->out_fmt,SWS_FAST_BILINEAR, + NULL, NULL, NULL); + } + if (sws_scale(s->sws_ctx,inbuf.data,inbuf.linesize, 0, + s->size.height, s->outbuf.planes, s->outbuf.strides)<0){ + ms_error("MSPixConv: Error in sws_scale()."); + } + freemsg(im); + } + if (om!=NULL) ms_queue_put(f->outputs[0],om); + } +} + +static int pixconv_set_vsize(MSFilter *f, void*arg){ + PixConvState *s=(PixConvState*)f->data; + s->size=*(MSVideoSize*)arg; + return 0; +} + +static int pixconv_set_pixfmt(MSFilter *f, void *arg){ + MSPixFmt fmt=*(MSPixFmt*)arg; + PixConvState *s=(PixConvState*)f->data; + s->in_fmt=(enum PixelFormat)ms_pix_fmt_to_ffmpeg(fmt); + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_VIDEO_SIZE, pixconv_set_vsize }, + { MS_FILTER_SET_PIX_FMT, pixconv_set_pixfmt }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_pix_conv_desc={ + MS_PIX_CONV_ID, + "MSPixConv", + "A pixel format converter", + MS_FILTER_OTHER, + NULL, + 1, + 1, + pixconv_init, + NULL, + pixconv_process, + NULL, + pixconv_uninit, + methods +}; + +#else + +MSFilterDesc ms_pix_conv_desc={ + .id=MS_PIX_CONV_ID, + .name="MSPixConv", + .text="A pixel format converter", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=1, + .init=pixconv_init, + .process=pixconv_process, + .uninit=pixconv_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_pix_conv_desc) + diff --git a/linphone/mediastreamer2/src/rfc2429.h b/linphone/mediastreamer2/src/rfc2429.h new file mode 100644 index 000000000..414b2ea56 --- /dev/null +++ b/linphone/mediastreamer2/src/rfc2429.h @@ -0,0 +1,50 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef rfc2429_h +#define rfc2429_h + +#define MAKE_MASK(bits) ( (1<<(bits)) -1 ) + +static inline unsigned int rfc2429_get_P(const uint8_t *header){ + return (header[0]>>2) & 0x1; +} + +static inline void rfc2429_set_P(uint8_t *header, bool_t val){ + header[0]=header[0] | ( (val&0x1)<<2); +} + +static inline unsigned int rfc2429_get_V(const uint8_t *header){ + return (header[0]>>1) & 0x1; +} + +static inline unsigned int rfc2429_get_PLEN(const uint8_t *header){ + unsigned short *p=(unsigned short*)header; + return (ntohs(p[0])>>3) & MAKE_MASK(6); +} + +static inline unsigned int rfc2429_get_PEBIT(const uint8_t *header){ + unsigned short *p=(unsigned short*)header; + return ntohs(p[0]) & MAKE_MASK(3); +} + + +#endif diff --git a/linphone/mediastreamer2/src/rfc3984.c b/linphone/mediastreamer2/src/rfc3984.c new file mode 100644 index 000000000..ffb2895b8 --- /dev/null +++ b/linphone/mediastreamer2/src/rfc3984.c @@ -0,0 +1,321 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/rfc3984.h" +#include "mediastreamer2/msfilter.h" + +#define TYPE_FU_A 28 /*fragmented unit 0x1C*/ +#define TYPE_STAP_A 24 /*single time aggregation packet 0x18*/ + + +static inline void nal_header_init(uint8_t *h, uint8_t nri, uint8_t type){ + *h=((nri&0x3)<<5) | (type & ((1<<5)-1)); +} + +static inline uint8_t nal_header_get_type(const uint8_t *h){ + return (*h) & ((1<<5)-1); +} + +static inline uint8_t nal_header_get_nri(const uint8_t *h){ + return ((*h) >> 5) & 0x3; +} + +void rfc3984_init(Rfc3984Context *ctx){ + ms_queue_init(&ctx->q); + ctx->m=NULL; + ctx->maxsz=ms_get_payload_max_size(); + ctx->mode=0; + ctx->last_ts=0x943FEA43;/*some random value*/ + ctx->stap_a_allowed=TRUE; +} + +void rfc3984_set_max_payload_size(Rfc3984Context *ctx, int size){ + ctx->maxsz=size; +} + +static void send_packet(MSQueue *rtpq, uint32_t ts, mblk_t *m, bool_t marker){ + mblk_set_timestamp_info(m,ts); + mblk_set_marker_info(m,marker); + ms_queue_put(rtpq,m); +} + +static void put_nal_size(mblk_t *m, uint16_t sz){ + uint16_t size=htons(sz); + *(uint16_t*)m->b_wptr=size; + m->b_wptr+=2; +} + +static mblk_t * prepend_stapa(mblk_t *m){ + mblk_t *hm=allocb(3,0); + nal_header_init(hm->b_wptr,nal_header_get_nri(m->b_rptr),TYPE_STAP_A); + hm->b_wptr+=1; + put_nal_size(hm,msgdsize(m)); + hm->b_cont=m; + return hm; +} + +static mblk_t * concat_nalus(mblk_t *m1, mblk_t *m2){ + mblk_t *l=allocb(2,0); + /*eventually append a stap-A header to m1, if not already done*/ + if (nal_header_get_type(m1->b_rptr)!=TYPE_STAP_A){ + m1=prepend_stapa(m1); + } + put_nal_size(l,msgdsize(m2)); + l->b_cont=m2; + concatb(m1,l); + return m1; +} + +static mblk_t *prepend_fu_indicator_and_header(mblk_t *m, uint8_t indicator, + bool_t start, bool_t end, uint8_t type){ + mblk_t *h=allocb(2,0); + h->b_wptr[0]=indicator; + h->b_wptr[1]=((start&0x1)<<7)|((end&0x1)<<6)|type; + h->b_wptr+=2; + h->b_cont=m; + if (start) m->b_rptr++;/*skip original nalu header */ + return h; +} + +static void frag_nalu_and_send(MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bool_t marker, int maxsize){ + mblk_t *m; + int payload_max_size=maxsize-2;/*minus FUA header*/ + uint8_t fu_indicator; + uint8_t type=nal_header_get_type(nalu->b_rptr); + uint8_t nri=nal_header_get_nri(nalu->b_rptr); + bool_t start=TRUE; + + nal_header_init(&fu_indicator,nri,TYPE_FU_A); + while(nalu->b_wptr-nalu->b_rptr>payload_max_size){ + m=dupb(nalu); + nalu->b_rptr+=payload_max_size; + m->b_wptr=nalu->b_rptr; + m=prepend_fu_indicator_and_header(m,fu_indicator,start,FALSE,type); + send_packet(rtpq,ts,m,FALSE); + start=FALSE; + } + /*send last packet */ + m=prepend_fu_indicator_and_header(nalu,fu_indicator,FALSE,TRUE,type); + send_packet(rtpq,ts,m,marker); +} + +static void rfc3984_pack_mode_0(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){ + mblk_t *m; + bool_t end; + int size; + while((m=ms_queue_get(naluq))!=NULL){ + end=ms_queue_empty(naluq); + size=m->b_wptr-m->b_rptr; + if (size>ctx->maxsz){ + ms_warning("This H264 packet does not fit into mtu: size=%i",size); + } + send_packet(rtpq,ts,m,end); + } +} + +/*process NALUs and pack them into rtp payloads */ +static void rfc3984_pack_mode_1(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){ + mblk_t *m,*prevm=NULL; + int prevsz=0,sz; + bool_t end; + while((m=ms_queue_get(naluq))!=NULL){ + end=ms_queue_empty(naluq); + sz=m->b_wptr-m->b_rptr; + if (ctx->stap_a_allowed){ + if (prevm!=NULL){ + if ((prevsz+sz)<(ctx->maxsz-2)){ + prevm=concat_nalus(prevm,m); + m=NULL; + prevsz+=sz+2;/*+2 for the stapa size field*/ + continue; + }else{ + /*send prevm packet: either single nal or STAP-A*/ + if (prevm->b_cont!=NULL){ + ms_debug("Sending STAP-A"); + }else + ms_debug("Sending previous msg as single NAL"); + send_packet(rtpq,ts,prevm,FALSE); + prevm=NULL; + prevsz=0; + } + } + if (sz<(ctx->maxsz/2)){ + /*try to aggregate it with next packet*/ + prevm=m; + prevsz=sz+3; /*STAP-A header + size*/ + m=NULL; + }else{ + + /*send as single nal or FU-A*/ + if (sz>ctx->maxsz){ + ms_debug("Sending FU-A packets"); + frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz); + }else{ + ms_debug("Sending Single NAL"); + send_packet(rtpq,ts,m,end); + } + } + }else{ + if (sz>ctx->maxsz){ + ms_debug("Sending FU-A packets"); + frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz); + }else{ + ms_debug("Sending Single NAL"); + send_packet(rtpq,ts,m,end); + } + } + } + if (prevm){ + ms_debug("Sending Single NAL (2)"); + send_packet(rtpq,ts,prevm,TRUE); + } +} + +static mblk_t * aggregate_fua(Rfc3984Context *ctx, mblk_t *im){ + mblk_t *om=NULL; + uint8_t fu_header; + uint8_t nri,type; + bool_t start,end; + fu_header=im->b_rptr[1]; + type=nal_header_get_type(&fu_header); + start=fu_header>>7; + end=(fu_header>>6)&0x1; + if (start){ + nri=nal_header_get_nri(im->b_rptr); + if (ctx->m!=NULL){ + ms_error("receiving FU-A start while previous FU-A is not " + "finished"); + freemsg(ctx->m); + ctx->m=NULL; + } + im->b_rptr++; + nal_header_init(im->b_rptr,nri,type); + ctx->m=im; + }else{ + if (ctx->m!=NULL){ + im->b_rptr+=2; + concatb(ctx->m,im); + }else{ + ms_error("Receiving continuation FU packet but no start."); + freemsg(im); + } + } + if (end && ctx->m){ + msgpullup(ctx->m,-1); + om=ctx->m; + ctx->m=NULL; + } + return om; +} + +/*process incoming rtp data and output NALUs, whenever possible*/ +void rfc3984_unpack(Rfc3984Context *ctx, mblk_t *im, MSQueue *out){ + uint8_t type=nal_header_get_type(im->b_rptr); + uint8_t *p; + int marker = mblk_get_marker_info(im); + uint32_t ts=mblk_get_timestamp_info(im); + + if (ctx->last_ts!=ts){ + /*a new frame is arriving, in case the marker bit was not set in previous frame, output it now*/ + /* unless this is a FU-A (workarond some other apps bugs)*/ + ctx->last_ts=ts; + if (ctx->m==NULL){ + while(!ms_queue_empty(&ctx->q)){ + ms_queue_put(out,ms_queue_get(&ctx->q)); + } + } + } + + if (im->b_cont) msgpullup(im,-1); + + if (type==TYPE_STAP_A){ + ms_debug("Receiving STAP-A"); + /*split into nalus*/ + uint16_t sz; + uint8_t *buf=(uint8_t*)&sz; + mblk_t *nal; + for(p=im->b_rptr+1;pb_wptr;){ + buf[0]=p[0]; + buf[1]=p[1]; + sz=ntohs(sz); + nal=dupb(im); + p+=2; + nal->b_rptr=p; + p+=sz; + nal->b_wptr=p; + if (p>im->b_wptr){ + ms_error("Malformed STAP-A packet"); + freemsg(nal); + break; + } + ms_queue_put(&ctx->q,nal); + } + freemsg(im); + }else if (type==TYPE_FU_A){ + ms_debug("Receiving FU-A"); + mblk_t *o=aggregate_fua(ctx,im); + if (o) ms_queue_put(&ctx->q,o); + }else{ + if (ctx->m){ + /*discontinued FU-A, purge it*/ + freemsg(ctx->m); + ctx->m=NULL; + } + /*single nal unit*/ + ms_debug("Receiving single NAL"); + ms_queue_put(&ctx->q,im); + } + + if (marker){ + ctx->last_ts=ts; + ms_debug("Marker bit set"); + /*end of frame, output everything*/ + while(!ms_queue_empty(&ctx->q)){ + ms_queue_put(out,ms_queue_get(&ctx->q)); + } + } +} + + +void rfc3984_pack(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){ + switch(ctx->mode){ + case 0: + rfc3984_pack_mode_0(ctx,naluq,rtpq,ts); + break; + case 1: + rfc3984_pack_mode_1(ctx,naluq,rtpq,ts); + break; + default: + ms_error("Bad or unsupported mode %i",ctx->mode); + } +} + +void rfc3984_uninit(Rfc3984Context *ctx){ + ms_queue_flush(&ctx->q); + if (ctx->m) freemsg(ctx->m); + ctx->m=NULL; +} + +void rfc3984_set_mode(Rfc3984Context *ctx, int mode){ + ctx->mode=mode; +} + +void rfc3984_enable_stap_a(Rfc3984Context *ctx, bool_t yesno){ + ctx->stap_a_allowed=yesno; +} diff --git a/linphone/mediastreamer2/src/sdlout.c b/linphone/mediastreamer2/src/sdlout.c new file mode 100644 index 000000000..641e57a97 --- /dev/null +++ b/linphone/mediastreamer2/src/sdlout.c @@ -0,0 +1,375 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" + +#include +#include + +typedef struct SdlOut +{ + MSVideoSize size; + MSVideoSize local_size; /*size of local preview */ + MSPixFmt format; + SDL_Surface *screen; + SDL_Overlay *overlay; + mblk_t *smallb; + int scale_factor; + bool_t lsize_init; +} SdlOut; + + +#define SCALE_FACTOR 6 + +static bool_t sdl_initialized=FALSE; + +static void sdl_out_init(MSFilter *f){ + SdlOut *obj=ms_new(SdlOut,1); + obj->size.width = MS_VIDEO_SIZE_CIF_W; + obj->size.height = MS_VIDEO_SIZE_CIF_H; + obj->local_size.width = MS_VIDEO_SIZE_CIF_W; + obj->local_size.height = MS_VIDEO_SIZE_CIF_H; + obj->lsize_init=FALSE; + obj->scale_factor=SCALE_FACTOR; + obj->format=MS_RGB24; + obj->screen=NULL; + obj->overlay=NULL; + obj->smallb=NULL; + +#if !defined(WIN32) && !defined(__APPLE__) + if (!sdl_initialized){ + + /* Initialize the SDL library */ + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + ms_error("Couldn't initialize SDL: %s", SDL_GetError()); + return; + } + /* Clean up on exit */ + atexit(SDL_Quit); + sdl_initialized=TRUE; + } +#endif + f->data=obj; +} + +static void sdl_destroy_window(SdlOut *obj){ + if (obj->overlay!=NULL){ + SDL_FreeYUVOverlay(obj->overlay); + obj->overlay=NULL; + } + if (obj->screen!=NULL){ + SDL_FreeSurface(obj->screen); + obj->screen=NULL; + } +} + +static void sdl_out_uninit(MSFilter *f){ + SdlOut *s=(SdlOut*)f->data; + sdl_destroy_window(s); + if (s->smallb!=NULL) freemsg(s->smallb); + ms_free(s); +} + +static void sdl_create_window(SdlOut *obj){ + obj->screen = SDL_SetVideoMode(obj->size.width, obj->size.height, 0,SDL_SWSURFACE); + if ( obj->screen == NULL ) { + ms_warning("Couldn't set video mode: %s\n", + SDL_GetError()); + return ; + } + if (obj->screen->flags & SDL_HWSURFACE) ms_message("SDL surface created in hardware"); + SDL_WM_SetCaption("Linphone Video", NULL); + + if (obj->format==MS_YUV420P){ + ms_message("Using yuv overlay."); + obj->overlay=SDL_CreateYUVOverlay(obj->size.width,obj->size.height,SDL_YV12_OVERLAY,obj->screen); + if (obj->overlay==NULL){ + ms_warning("Couldn't create yuv overlay: %s\n", + SDL_GetError()); + return; + }else{ + if (obj->overlay->hw_overlay) ms_message("YUV overlay using hardware acceleration."); + } + } +} + +mblk_t * resize_yuv_small(unsigned char *pict, int w, int h, int scale){ + int i,j,id,jd; + int nh,nw; + unsigned char *smallpict; + int ysize,usize,ydsize,udsize; + int smallpict_sz; + unsigned char *dptr,*sptr; + mblk_t *smallb; + nw=w/scale; + nh=h/scale; + ysize=w*h; + usize=ysize/4; + ydsize=nw*nh; + udsize=ydsize/4; + smallpict_sz=(ydsize*3)/2; + smallb=allocb(smallpict_sz,0); + smallpict=smallb->b_wptr; + smallb->b_wptr+=smallpict_sz; + + dptr=smallpict; + sptr=pict; + for (j=0,jd=0;jb_rptr; + int i,j; + int jlim,ilim; + int off; + unsigned char *dptr; + + ilim=MIN(x+w,lay->w); + jlim=MIN(y+h,lay->h); + SDL_LockYUVOverlay(lay); + /* set Y */ + dptr=lay->pixels[0]; + for (j=y;jw; + for (i=x;ipixels[2]; + for (j=y/2;jw/2); + for (i=x/2;ipixels[1]; + for (j=y/2;jw/2); + for (i=x/2;ib_rptr; + int ysize=lay->pitches[0]*lay->h; + int usize; + w2=lay->w/2; + h2=lay->h/2; + usize=w2*h2; + SDL_LockYUVOverlay(lay); + memcpy(lay->pixels[0],data,ysize); + memcpy(lay->pixels[2],data+ysize,usize); + memcpy(lay->pixels[1],data+ysize+usize,usize); + SDL_UnlockYUVOverlay(lay); +} + +static void sdl_out_process(MSFilter *f){ + SdlOut *obj=(SdlOut*)f->data; + mblk_t *inm0=NULL; + mblk_t *inm1=NULL; + int err; + SDL_Rect smallrect; + SDL_Rect rect; + bool_t got_preview=FALSE; + +#if defined(WIN32) || defined(__APPLE__) + if (!sdl_initialized){ + + /* Initialize the SDL library */ + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + ms_error("Couldn't initialize SDL: %s", SDL_GetError()); + return; + } + /* Clean up on exit */ + atexit(SDL_Quit); + sdl_initialized=TRUE; + } +#endif + + if (obj->screen==NULL){ + sdl_create_window(obj); + } + + rect.w=obj->size.width; + rect.h=obj->size.height; + rect.x=0; + rect.y=0; + smallrect.w=obj->size.width/SCALE_FACTOR; + smallrect.h=obj->size.height/SCALE_FACTOR; + smallrect.x=obj->size.width - smallrect.w ; + smallrect.y=obj->size.height -smallrect.h; + + + while (f->inputs[0]!=NULL && (inm0=ms_queue_get(f->inputs[0]))!=NULL){ + SDL_Surface *surf; + if (obj->format==MS_YUV420P){ + fill_overlay(obj->overlay,inm0); + }else { + surf=SDL_CreateRGBSurfaceFrom(inm0->b_rptr,obj->size.width,obj->size.height,24,obj->size.width*3,0,0,0,0); + + err=SDL_BlitSurface(surf,NULL,obj->screen,NULL); + if (err<0) ms_warning("Fail to blit surface: %s",SDL_GetError()); + SDL_FreeSurface(surf); + } + freemsg(inm0); + } + while (f->inputs[1]!=NULL && (inm1=ms_queue_get(f->inputs[1]))!=NULL){ + /* this message is blitted on the right,bottom corner of the screen */ + SDL_Surface *surf; + got_preview=TRUE; + if (!obj->lsize_init){ + /*attempt to guess the video size of the local preview buffer*/ + int bsize=msgdsize(inm1); + if (bsize<(MS_VIDEO_SIZE_CIF_W*MS_VIDEO_SIZE_CIF_H*3/2)){ + /*surely qcif ?*/ + obj->local_size.width=MS_VIDEO_SIZE_QCIF_W; + obj->local_size.height=MS_VIDEO_SIZE_QCIF_H; + ms_message("preview is in QCIF."); + obj->scale_factor=SCALE_FACTOR/2; + } + obj->lsize_init=TRUE; + } + if (obj->format==MS_YUV420P){ + if (obj->smallb!=NULL) { + freemsg(obj->smallb); + } + obj->smallb=resize_yuv_small(inm1->b_rptr,obj->local_size.width,obj->local_size.height,obj->scale_factor); + fill_overlay_at_pos(obj->overlay,obj->smallb,smallrect.x, smallrect.y, smallrect.w, smallrect.h); + freemsg(inm1); + }else { + surf=SDL_CreateRGBSurfaceFrom(inm1->b_rptr,obj->size.width,obj->size.height,24,obj->size.width*3,0,0,0,0); + + err=SDL_BlitSurface(surf,NULL,obj->screen,&smallrect); + if (err<0) ms_warning("Fail to blit surface: %s",SDL_GetError()); + SDL_FreeSurface(surf); + } + } + if (!got_preview){ + /* this is the case were we have only inm0, we have to redisplay inm1 */ + if (obj->format==MS_YUV420P){ + if (obj->smallb!=NULL){ + fill_overlay_at_pos(obj->overlay,obj->smallb,smallrect.x, smallrect.y, smallrect.w, smallrect.h); + } + } + } + + if (obj->format==MS_YUV420P) SDL_DisplayYUVOverlay(obj->overlay,&rect); + else SDL_UpdateRect(obj->screen,0,0,obj->size.width,obj->size.height); + +#if defined(WIN32) || defined(__APPLE__) + { + SDL_Event event; + SDL_PollEvent(&event); + } +#endif +} + +static int sdl_out_set_pix_fmt(MSFilter *f,void *arg){ + SdlOut *s=(SdlOut*)f->data; + s->format=*(MSPixFmt*)arg; + return 0; +} + +static int sdl_out_set_vsize(MSFilter *f,void *arg){ + SdlOut *s=(SdlOut*)f->data; + s->size=*(MSVideoSize*)arg; + s->local_size=*(MSVideoSize*)arg; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_PIX_FMT , sdl_out_set_pix_fmt}, + { MS_FILTER_SET_VIDEO_SIZE , sdl_out_set_vsize }, + { 0 ,NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_sdl_out_desc={ + MS_SDL_OUT_ID, + "MSSdlOut", + "A video display window using SDL", + MS_FILTER_OTHER, + NULL, + 2, + 0, + sdl_out_init, + NULL, + sdl_out_process, + NULL, + sdl_out_uninit, + methods +}; + +#else + +MSFilterDesc ms_sdl_out_desc={ + .id=MS_SDL_OUT_ID, + .name="MSSdlOut", + .text="A video display window using SDL", + .category=MS_FILTER_OTHER, + .ninputs=2, + .noutputs=0, + .init=sdl_out_init, + .process=sdl_out_process, + .uninit=sdl_out_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_sdl_out_desc) diff --git a/linphone/mediastreamer2/src/sizeconv.c b/linphone/mediastreamer2/src/sizeconv.c new file mode 100644 index 000000000..9e34ba819 --- /dev/null +++ b/linphone/mediastreamer2/src/sizeconv.c @@ -0,0 +1,235 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msvideo.h" + +#include "ffmpeg-priv.h" + +typedef struct SizeConvState{ + MSVideoSize target_vsize; + MSVideoSize in_vsize; + YuvBuf outbuf; + struct SwsContext *sws_ctx; + mblk_t *om; + + float fps; + float start_time; + int frame_count; + queue_t rq; +} SizeConvState; + + +/*this MSFilter will do on the fly picture size conversion. It attempts to guess the picture size from the yuv buffer size. YUV420P is assumed on input. +For now it only supports QCIF->CIF, QVGA->CIF and CIF->CIF (does nothing in this case)*/ + +static void size_conv_init(MSFilter *f){ + SizeConvState *s=(SizeConvState *)ms_new(SizeConvState,1); + s->target_vsize.width = MS_VIDEO_SIZE_CIF_W; + s->target_vsize.height = MS_VIDEO_SIZE_CIF_H; + s->in_vsize.width=0; + s->in_vsize.height=0; + s->sws_ctx=NULL; + s->om=NULL; + s->start_time=0; + s->frame_count=-1; + s->fps=-1; /* default to process ALL frames */ + qinit(&s->rq); + f->data=s; +} + +static void size_conv_uninit(MSFilter *f){ + SizeConvState *s=(SizeConvState*)f->data; + ms_free(s); +} + +static void size_conv_postprocess(MSFilter *f){ + SizeConvState *s=(SizeConvState*)f->data; + if (s->sws_ctx!=NULL) { + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + if (s->om!=NULL){ + freemsg(s->om); + s->om=NULL; + } + flushq(&s->rq,0); +} + +static mblk_t *size_conv_alloc_mblk(SizeConvState *s){ + if (s->om!=NULL){ + int ref=s->om->b_datap->db_ref; + if (ref==1){ + return dupmsg(s->om); + }else{ + /*the last msg is still referenced by somebody else*/ + ms_message("size_conv_alloc_mblk: Somebody still retaining yuv buffer (ref=%i)",ref); + freemsg(s->om); + s->om=NULL; + } + } + s->om=yuv_buf_alloc(&s->outbuf,s->target_vsize.width,s->target_vsize.height); + return dupmsg(s->om); +} + +static struct SwsContext * get_resampler(SizeConvState *s, int w, int h){ + if (s->in_vsize.width!=w || + s->in_vsize.height!=h || s->sws_ctx==NULL){ + if (s->sws_ctx!=NULL){ + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + s->sws_ctx=sws_getContext(w,h,PIX_FMT_YUV420P, + s->target_vsize.width,s->target_vsize.height,PIX_FMT_YUV420P, + SWS_FAST_BILINEAR,NULL, NULL, NULL); + s->in_vsize.width=w; + s->in_vsize.height=h; + } + return s->sws_ctx; +} + +static void size_conv_process(MSFilter *f){ + SizeConvState *s=(SizeConvState*)f->data; + YuvBuf inbuf; + mblk_t *im; + int cur_frame; + + ms_filter_lock(f); + + if (s->frame_count==-1){ + s->start_time=f->ticker->time; + s->frame_count=0; + } + while((im=ms_queue_get(f->inputs[0]))!=NULL ){ + putq(&s->rq, im); + } + + cur_frame=((f->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame<=s->frame_count && s->fps>=0) { + /* too much frame */ + while(s->rq.q_mcount>1){ + ms_message("MSSizeConv: extra frame removed."); + im=getq(&s->rq); + freemsg(im); + } + ms_filter_unlock(f); + return; + } + + if (cur_frame>s->frame_count && s->fps>=0) { + /*keep the most recent frame if several frames have been captured */ + while(s->rq.q_mcount>1){ + ms_message("MSSizeConv: extra frame removed."); + im=getq(&s->rq); + freemsg(im); + } + } + while((im=getq(&s->rq))!=NULL ){ + if (yuv_buf_init_from_mblk(&inbuf,im)==0){ + if (inbuf.w==s->target_vsize.width && + inbuf.h==s->target_vsize.height){ + ms_queue_put(f->outputs[0],im); + }else{ + struct SwsContext *sws_ctx=get_resampler(s,inbuf.w,inbuf.h); + mblk_t *om=size_conv_alloc_mblk(s); + if (sws_scale(sws_ctx,inbuf.planes,inbuf.strides, 0, + inbuf.h, s->outbuf.planes, s->outbuf.strides)<0){ + ms_error("MSSizeConv: error in sws_scale()."); + } + ms_queue_put(f->outputs[0],om); + freemsg(im); + } + s->frame_count++; + }else freemsg(im); + } + + ms_filter_unlock(f); +} + + +static int sizeconv_set_vsize(MSFilter *f, void*arg){ + SizeConvState *s=(SizeConvState*)f->data; + ms_filter_lock(f); + s->target_vsize=*(MSVideoSize*)arg; + freemsg(s->om); + s->om=NULL; + if (s->sws_ctx!=NULL) { + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + ms_filter_unlock(f); + return 0; +} + +static int sizeconv_set_fps(MSFilter *f, void *arg){ + SizeConvState *s=(SizeConvState*)f->data; + s->fps=*((float*)arg); + s->frame_count=-1; /* reset counter used for fps */ + return 0; +} + + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , sizeconv_set_fps }, + { MS_FILTER_SET_VIDEO_SIZE, sizeconv_set_vsize }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_size_conv_desc={ + MS_SIZE_CONV_ID, + "MSSizeConv", + "A video size converter", + MS_FILTER_OTHER, + NULL, + 1, + 1, + size_conv_init, + NULL, + size_conv_process, + size_conv_postprocess, + size_conv_uninit, + methods +}; + +#else + +MSFilterDesc ms_size_conv_desc={ + .id=MS_SIZE_CONV_ID, + .name="MSSizeConv", + .text="a small video size converter", + .ninputs=1, + .noutputs=1, + .init=size_conv_init, + .process=size_conv_process, + .postprocess=size_conv_postprocess, + .uninit=size_conv_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_size_conv_desc) + diff --git a/linphone/mediastreamer2/src/speexec.c b/linphone/mediastreamer2/src/speexec.c new file mode 100644 index 000000000..6a3a4e164 --- /dev/null +++ b/linphone/mediastreamer2/src/speexec.c @@ -0,0 +1,249 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#ifdef WIN32 +#include /* for alloca */ +#endif + +static const int framesize=128; +static const int filter_length=2048; /*250 ms*/ + +typedef struct SpeexECState{ + SpeexEchoState *ecstate; + MSBufferizer in[2]; + int framesize; + int filterlength; + int samplerate; + SpeexPreprocessState *den; + int ref; + int echo; + int out; +}SpeexECState; + +static void speex_ec_init(MSFilter *f){ + SpeexECState *s=(SpeexECState *)ms_new(SpeexECState,1); + + s->samplerate=8000; + s->framesize=framesize; + s->filterlength=filter_length; + + ms_bufferizer_init(&s->in[0]); + ms_bufferizer_init(&s->in[1]); + s->ecstate=speex_echo_state_init(s->framesize,s->filterlength); + s->den = speex_preprocess_state_init(s->framesize, s->samplerate); + + f->data=s; +} + +static void speex_ec_uninit(MSFilter *f){ + SpeexECState *s=(SpeexECState*)f->data; + ms_bufferizer_uninit(&s->in[0]); + ms_bufferizer_uninit(&s->in[1]); + speex_echo_state_destroy(s->ecstate); + if (s->den!=NULL) + speex_preprocess_state_destroy(s->den); + + ms_free(s); +} + +/* inputs[0]= reference signal (sent to soundcard) + inputs[1]= echo signal (read from soundcard) +*/ + + +static void speex_ec_process(MSFilter *f){ + SpeexECState *s=(SpeexECState*)f->data; + int nbytes=s->framesize*2; + uint8_t *in1; + mblk_t *om0,*om1; +#ifdef HAVE_SPEEX_NOISE + spx_int32_t *noise=(spx_int32_t*)alloca(nbytes*sizeof(spx_int32_t)+1); +#else + float *noise=NULL; +#endif +#ifdef AMD_WIN32_HACK + static int count=0; +#endif + + /*read input and put in bufferizers*/ + ms_bufferizer_put_from_queue(&s->in[0],f->inputs[0]); + ms_bufferizer_put_from_queue(&s->in[1],f->inputs[1]); + + in1=(uint8_t*)alloca(nbytes); + + ms_debug("speexec: in0=%i, in1=%i",ms_bufferizer_get_avail(&s->in[0]),ms_bufferizer_get_avail(&s->in[1])); + + while (ms_bufferizer_get_avail(&s->in[0])>=nbytes && ms_bufferizer_get_avail(&s->in[1])>=nbytes){ + om0=allocb(nbytes,0); + ms_bufferizer_read(&s->in[0],(uint8_t*)om0->b_wptr,nbytes); + /* we have reference signal */ + /* the reference signal is sent through outputs[0]*/ + + om0->b_wptr+=nbytes; + ms_queue_put(f->outputs[0],om0); + + ms_bufferizer_read(&s->in[1],in1,nbytes); + /* we have echo signal */ + om1=allocb(nbytes,0); + speex_echo_cancel(s->ecstate,(short*)in1,(short*)om0->b_rptr,(short*)om1->b_wptr,(spx_int32_t*)noise); + if (s->den!=NULL && noise!=NULL) + speex_preprocess(s->den, (short*)om1->b_wptr, (spx_int32_t*)noise); + + om1->b_wptr+=nbytes; + ms_queue_put(f->outputs[1],om1); +#ifdef AMD_WIN32_HACK + count++; + if (count==100*3) + { + ms_message("periodic reset of echo canceller."); + speex_echo_state_reset(s->ecstate); + count=0; + } +#endif + } + + if (ms_bufferizer_get_avail(&s->in[0])> 4*320*(s->samplerate/8000)) /* above 4*20ms -> useless */ + { + /* reset evrything */ + ms_warning("speexec: -reset of echo canceller- in0=%i, in1=%i",ms_bufferizer_get_avail(&s->in[0]),ms_bufferizer_get_avail(&s->in[1])); + flushq(&s->in[1].q,0); + flushq(&s->in[0].q,0); + ms_bufferizer_init(&s->in[0]); + ms_bufferizer_init(&s->in[1]); + speex_echo_state_reset(s->ecstate); + } + + while (ms_bufferizer_get_avail(&s->in[1])> 4*320*(s->samplerate/8000)){ + om1=allocb(nbytes,0); + ms_bufferizer_read(&s->in[1],(uint8_t*)om1->b_wptr,nbytes); + om1->b_wptr+=nbytes; + ms_queue_put(f->outputs[1],om1); + ms_message("too much echo signal, sending anyway."); + speex_echo_state_reset(s->ecstate); + } + +} + +static int speex_ec_set_sr(MSFilter *f, void *arg){ +#ifdef SPEEX_ECHO_SET_SAMPLING_RATE + SpeexECState *s=(SpeexECState*)f->data; + + s->samplerate = *(int*)arg; + + if (s->ecstate==NULL) + speex_echo_state_destroy(s->ecstate); + if (s->den!=NULL) + speex_preprocess_state_destroy(s->den); + + s->ecstate=speex_echo_state_init(s->framesize,s->filterlength); + speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate); + s->den = speex_preprocess_state_init(s->framesize, s->samplerate); +#else + ms_error("Speex echocanceler does not support 16Khz sampling rate in this version!"); +#endif + return 0; +} + +static int speex_ec_set_framesize(MSFilter *f, void *arg){ + SpeexECState *s=(SpeexECState*)f->data; + s->framesize = *(int*)arg; + + if (s->ecstate==NULL) + speex_echo_state_destroy(s->ecstate); + if (s->den!=NULL) + speex_preprocess_state_destroy(s->den); + + s->ecstate=speex_echo_state_init(s->framesize,s->filterlength); +#ifdef SPEEX_ECHO_SET_SAMPLING_RATE + speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate); +#endif + s->den = speex_preprocess_state_init(s->framesize, s->samplerate); + return 0; +} + +static int speex_ec_set_filterlength(MSFilter *f, void *arg){ + SpeexECState *s=(SpeexECState*)f->data; + s->filterlength = *(int*)arg; + + if (s->ecstate==NULL) + speex_echo_state_destroy(s->ecstate); + if (s->den!=NULL) + speex_preprocess_state_destroy(s->den); + + s->ecstate=speex_echo_state_init(s->framesize,s->filterlength); +#ifdef SPEEX_ECHO_SET_SAMPLING_RATE + speex_echo_ctl(s->ecstate, SPEEX_ECHO_SET_SAMPLING_RATE, &s->samplerate); +#endif + s->den = speex_preprocess_state_init(s->framesize, s->samplerate); + + return 0; +} + +static MSFilterMethod speex_ec_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE, speex_ec_set_sr }, + { MS_FILTER_SET_FRAMESIZE, speex_ec_set_framesize }, + { MS_FILTER_SET_FILTERLENGTH, speex_ec_set_filterlength }, + { 0 , NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_speex_ec_desc={ + MS_SPEEX_EC_ID, + "MSSpeexEC", + "Echo canceler using speex library", + MS_FILTER_OTHER, + NULL, + 2, + 2, + speex_ec_init, + NULL, + speex_ec_process, + NULL, + speex_ec_uninit, + speex_ec_methods +}; + +#else + +MSFilterDesc ms_speex_ec_desc={ + .id=MS_SPEEX_EC_ID, + .name="MSSpeexEC", + .text="Echo canceler using speex library", + .category=MS_FILTER_OTHER, + .ninputs=2, + .noutputs=2, + .init=speex_ec_init, + .process=speex_ec_process, + .uninit=speex_ec_uninit, + .methods=speex_ec_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_speex_ec_desc) diff --git a/linphone/mediastreamer2/src/swscale.h b/linphone/mediastreamer2/src/swscale.h new file mode 100644 index 000000000..a0c735b69 --- /dev/null +++ b/linphone/mediastreamer2/src/swscale.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2001-2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_SWSCALE_H +#define FFMPEG_SWSCALE_H + +/** + * @file swscale.h + * @brief + * external api for the swscale stuff + */ + +#include "libavutil/avutil.h" + +#define LIBSWSCALE_VERSION_MAJOR 0 +#define LIBSWSCALE_VERSION_MINOR 5 +#define LIBSWSCALE_VERSION_MICRO 1 + +#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT + +#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) + +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 + +#define SWS_SRC_V_CHR_DROP_MASK 0x30000 +#define SWS_SRC_V_CHR_DROP_SHIFT 16 + +#define SWS_PARAM_DEFAULT 123456 + +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented +//internal chrominace subsampling info +#define SWS_FULL_CHR_H_INT 0x2000 +//input subsampling info +#define SWS_FULL_CHR_H_INP 0x4000 +#define SWS_DIRECT_BGR 0x8000 +#define SWS_ACCURATE_RND 0x40000 + +#define SWS_CPU_CAPS_MMX 0x80000000 +#define SWS_CPU_CAPS_MMX2 0x20000000 +#define SWS_CPU_CAPS_3DNOW 0x40000000 +#define SWS_CPU_CAPS_ALTIVEC 0x10000000 +#define SWS_CPU_CAPS_BFIN 0x01000000 + +#define SWS_MAX_REDUCE_CUTOFF 0.002 + +#define SWS_CS_ITU709 1 +#define SWS_CS_FCC 4 +#define SWS_CS_ITU601 5 +#define SWS_CS_ITU624 5 +#define SWS_CS_SMPTE170M 5 +#define SWS_CS_SMPTE240M 7 +#define SWS_CS_DEFAULT 5 + + + +// when used for filters they must have an odd number of elements +// coeffs cannot be shared between vectors +typedef struct { + double *coeff; + int length; +} SwsVector; + +// vectors can be shared +typedef struct { + SwsVector *lumH; + SwsVector *lumV; + SwsVector *chrH; + SwsVector *chrV; +} SwsFilter; + +struct SwsContext; + +void sws_freeContext(struct SwsContext *swsContext); + +struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, + SwsFilter *srcFilter, SwsFilter *dstFilter, double *param); +int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]); +int sws_scale_ordered(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) attribute_deprecated; + + +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation); +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation); +SwsVector *sws_getGaussianVec(double variance, double quality); +SwsVector *sws_getConstVec(double c, int length); +SwsVector *sws_getIdentityVec(void); +void sws_scaleVec(SwsVector *a, double scalar); +void sws_normalizeVec(SwsVector *a, double height); +void sws_convVec(SwsVector *a, SwsVector *b); +void sws_addVec(SwsVector *a, SwsVector *b); +void sws_subVec(SwsVector *a, SwsVector *b); +void sws_shiftVec(SwsVector *a, int shift); +SwsVector *sws_cloneVec(SwsVector *a); + +void sws_printVec(SwsVector *a); +void sws_freeVec(SwsVector *a); + +SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, + float lumaSarpen, float chromaSharpen, + float chromaHShift, float chromaVShift, + int verbose); +void sws_freeFilter(SwsFilter *filter); + +struct SwsContext *sws_getCachedContext(struct SwsContext *context, + int srcW, int srcH, int srcFormat, + int dstW, int dstH, int dstFormat, int flags, + SwsFilter *srcFilter, SwsFilter *dstFilter, double *param); + +#endif /* FFMPEG_SWSCALE_H */ diff --git a/linphone/mediastreamer2/src/tee.c b/linphone/mediastreamer2/src/tee.c new file mode 100644 index 000000000..fd300fef0 --- /dev/null +++ b/linphone/mediastreamer2/src/tee.c @@ -0,0 +1,110 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mstee.h" + +#define MS_TEE_NOUTPUTS 10 + +typedef struct _TeeData{ + bool_t muted[MS_TEE_NOUTPUTS]; +}TeeData; + +static void tee_init(MSFilter *f){ + f->data=ms_new0(TeeData,1); +} + +static void tee_uninit(MSFilter *f){ + ms_free(f->data); +} + +static void tee_process(MSFilter *f){ + TeeData *d=(TeeData*)f->data; + mblk_t *im; + int i; + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + for(i=0;idesc->noutputs;i++){ + if (f->outputs[i]!=NULL && !d->muted[i]) + ms_queue_put(f->outputs[i],dupmsg(im)); + } + freemsg(im); + } +} + +static int tee_mute(MSFilter *f, void *arg){ + TeeData *d=(TeeData*)f->data; + int pin=((int*)arg)[0]; + if (pin>=0 && pinmuted[pin]=TRUE; + return 0; + } + return -1; +} + +static int tee_unmute(MSFilter *f, void *arg){ + TeeData *d=(TeeData*)f->data; + int pin=((int*)arg)[0]; + if (pin>=0 && pinmuted[pin]=FALSE; + return 0; + } + return -1; +} + +static MSFilterMethod tee_methods[]={ + { MS_TEE_MUTE , tee_mute }, + { MS_TEE_UNMUTE , tee_unmute }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_tee_desc={ + MS_TEE_ID, + "MSTee", + "A filter that reads from input and copy to its multiple outputs.", + MS_FILTER_OTHER, + NULL, + 1, + MS_TEE_NOUTPUTS, + tee_init, + NULL, + tee_process, + NULL, + tee_uninit, + tee_methods +}; + +#else + +MSFilterDesc ms_tee_desc={ + .id=MS_TEE_ID, + .name="MSTee", + .text="A filter that reads from input and copy to its multiple outputs.", + .category=MS_FILTER_OTHER, + .ninputs=1, + .noutputs=MS_TEE_NOUTPUTS, + .init=tee_init, + .process=tee_process, + .uninit=tee_uninit, + .methods=tee_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_tee_desc) diff --git a/linphone/mediastreamer2/src/theora.c b/linphone/mediastreamer2/src/theora.c new file mode 100644 index 000000000..f43282eb0 --- /dev/null +++ b/linphone/mediastreamer2/src/theora.c @@ -0,0 +1,582 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msvideo.h" + +#include + +typedef struct EncState{ + theora_state tstate; + theora_info tinfo; + yuv_buffer yuv; + mblk_t *packed_conf; + uint64_t start_time; + uint64_t conf_time; + unsigned int mtu; +} EncState; + +static void enc_init(MSFilter *f){ + EncState *s=(EncState *)ms_new(EncState,1); + theora_info_init(&s->tinfo); + s->tinfo.width=MS_VIDEO_SIZE_CIF_W; + s->tinfo.height=MS_VIDEO_SIZE_CIF_H; + s->tinfo.frame_width=MS_VIDEO_SIZE_CIF_W; + s->tinfo.frame_height=MS_VIDEO_SIZE_CIF_H; + s->tinfo.offset_x=0; + s->tinfo.offset_y=0; + s->tinfo.target_bitrate=500000; + s->tinfo.pixelformat=OC_PF_420; + s->tinfo.fps_numerator=15; + s->tinfo.fps_denominator=1; + s->tinfo.aspect_numerator=1; + s->tinfo.aspect_denominator=1; + s->tinfo.colorspace=OC_CS_UNSPECIFIED; + s->tinfo.dropframes_p=0; + s->tinfo.quick_p=1; + s->tinfo.quality=63; + s->tinfo.keyframe_auto_p=1; + s->tinfo.keyframe_frequency=64; + s->tinfo.keyframe_frequency_force=64; + s->tinfo.keyframe_data_target_bitrate=s->tinfo.target_bitrate*1.2; + s->tinfo.keyframe_auto_threshold=80; + s->tinfo.keyframe_mindistance=8; + s->tinfo.noise_sensitivity=1; + s->packed_conf=NULL; + s->start_time=0; + s->conf_time=0; + s->mtu=ms_get_payload_max_size()-6; + f->data=s; +} + +static void enc_uninit(MSFilter *f){ + EncState *s=(EncState*)f->data; + theora_info_clear(&s->tinfo); + ms_free(s); +} + +static int enc_set_vsize(MSFilter *f, void*data){ + MSVideoSize *vs=(MSVideoSize*)data; + EncState *s=(EncState*)f->data; + s->tinfo.width=vs->width; + s->tinfo.height=vs->height; + s->tinfo.frame_width=vs->width; + s->tinfo.frame_height=vs->height; + return 0; +} + +static int enc_get_vsize(MSFilter *f, void *data){ + EncState *s=(EncState*)f->data; + MSVideoSize *vs=(MSVideoSize*)data; + vs->width=s->tinfo.width; + vs->height=s->tinfo.height; + return 0; +} + +static int enc_add_attr(MSFilter *f, void*data){ + /*const char *attr=(const char*)data; + EncState *s=(EncState*)f->data;*/ + return 0; +} + +static int enc_set_fps(MSFilter *f, void *data){ + float *fps=(float*)data; + EncState *s=(EncState*)f->data; + s->tinfo.fps_numerator=*fps; + s->tinfo.keyframe_frequency=(*fps)*5; + s->tinfo.keyframe_frequency_force=(*fps)*5; + return 0; +} + +static int enc_get_fps(MSFilter *f, void *data){ + EncState *s=(EncState*)f->data; + float *fps=(float*)data; + *fps=s->tinfo.fps_numerator; + return 0; +} + +static int enc_set_br(MSFilter *f, void*data){ + int br=*(int*)data; + EncState *s=(EncState*)f->data; + MSVideoSize vsize; + float fps; + float codecbr=(float)br; + vsize.width=s->tinfo.width; + vsize.height=s->tinfo.height; + fps=s->tinfo.fps_numerator; + s->tinfo.target_bitrate=codecbr*0.8; + s->tinfo.keyframe_data_target_bitrate=codecbr; + /*those default settings would need to be affined*/ + if (br>=512000){ + vsize.width = MS_VIDEO_SIZE_CIF_W; + vsize.height = MS_VIDEO_SIZE_CIF_H; + s->tinfo.quality=32; + fps=15; + }else if (br>=256000){ + vsize.width = MS_VIDEO_SIZE_CIF_W; + vsize.height = MS_VIDEO_SIZE_CIF_H; + s->tinfo.quality=5; + fps=12; + }else if(br>=128000){ + vsize.width=MS_VIDEO_SIZE_QCIF_W; + vsize.height=MS_VIDEO_SIZE_QCIF_H; + s->tinfo.quality=20; + fps=10; + }else if(br>=64000){ + vsize.width=MS_VIDEO_SIZE_QCIF_W; + vsize.height=MS_VIDEO_SIZE_QCIF_H; + s->tinfo.quality=7; + fps=7; + } + enc_set_vsize(f,&vsize); + enc_set_fps(f,&fps); + return 0; +} + +static int enc_set_mtu(MSFilter *f, void*data){ + EncState *s=(EncState*)f->data; + s->mtu=*(int*)data; + return 0; +} + +#define THEORA_RAW_DATA 0 +#define THEORA_PACKED_CONF 1 +#define THEORA_COMMENT 2 +#define THEORA_RESERVED 3 + +#define NOT_FRAGMENTED 0 +#define START_FRAGMENT 1 +#define CONT_FRAGMENT 2 +#define END_FRAGMENT 3 + + +static inline void payload_header_set(uint8_t *buf, uint32_t ident, uint8_t ft, uint8_t tdt, uint8_t pkts){ + uint32_t tmp; + tmp=((ident&0xFFFFFF)<<8) | ((ft&0x3)<<6) | ((tdt&0x3)<<4) | (pkts&0xf); + *((uint32_t*)buf)=htonl(tmp); +} + +static inline uint32_t payload_header_get_ident(uint8_t *buf){ + uint32_t *tmp=(uint32_t*)buf; + return (ntohl(*tmp)>>8) & 0xFFFFFF; +} + +static inline uint32_t payload_header_get_tdt(uint8_t *buf){ + uint32_t *tmp=(uint32_t*)buf; + return ((ntohl(*tmp))>>4) & 0x3; +} + +static inline uint32_t payload_header_get_ft(uint8_t *buf){ + uint32_t *tmp=(uint32_t*)buf; + return ((ntohl(*tmp))>>6) & 0x3; +} + +static inline uint32_t payload_header_get_pkts(uint8_t *buf){ + uint32_t *tmp=(uint32_t*)buf; + return ntohl(*tmp) & 0xf; +} + +static int create_packed_conf(EncState *s){ + ogg_packet p; + theora_state *tstate=&s->tstate; + mblk_t *h,*t; + if (theora_encode_header(tstate,&p)!=0){ + ms_error("theora_encode_header() error."); + return -1; + } + h=allocb(p.bytes,0); + memcpy(h->b_wptr,p.packet,p.bytes); + h->b_wptr+=p.bytes; + if (theora_encode_tables(tstate,&p)!=0){ + ms_error("theora_encode_tables error."); + freemsg(h); + return -1; + } + t=allocb(p.bytes,0); + memcpy(t->b_wptr,p.packet,p.bytes); + t->b_wptr+=p.bytes; + h->b_cont=t; + msgpullup(h,-1); + s->packed_conf=h; + return 0; +} + +static void enc_preprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + int err; + if ((err=theora_encode_init(&s->tstate,&s->tinfo))!=0){ + ms_error("error in theora_encode_init() : %i !",err); + } + s->yuv.y_width=s->tinfo.width; + s->yuv.y_height=s->tinfo.height; + s->yuv.y_stride=s->tinfo.width; + s->yuv.uv_width=s->tinfo.width/2; + s->yuv.uv_height=s->tinfo.height/2; + s->yuv.uv_stride=s->tinfo.width/2; + create_packed_conf(s); + s->conf_time=0; + s->start_time=f->ticker->time; +} + +static void enc_postprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + theora_clear(&s->tstate); + + //If preprocess is called after postprocess, + //then we loose all info... + //theora_info_clear(&s->tinfo); + + if (s->packed_conf) { + freemsg(s->packed_conf); + s->packed_conf=NULL; + } +} + +static void enc_fill_yuv(yuv_buffer *yuv, mblk_t *im){ + yuv->y=(uint8_t*)im->b_rptr; + yuv->u=(uint8_t*)im->b_rptr+(yuv->y_stride*yuv->y_height); + yuv->v=(uint8_t*)yuv->u+(yuv->uv_stride*yuv->uv_height); +} + + +static void packetize_and_send(MSFilter *f, EncState *s, mblk_t *om, uint32_t timestamp, uint8_t tdt){ + mblk_t *packet; + mblk_t *h; + int npackets=0; + static const int ident=0xdede; + while(om!=NULL){ + if (om->b_wptr-om->b_rptr>=s->mtu){ + packet=dupb(om); + packet->b_wptr=packet->b_rptr+s->mtu; + om->b_rptr=packet->b_wptr; + }else { + packet=om; + om=NULL; + } + ++npackets; + h=allocb(6,0); + if (npackets==1){ + if (om==NULL) + payload_header_set(h->b_wptr,ident,NOT_FRAGMENTED,tdt,1); + else + payload_header_set(h->b_wptr,ident,START_FRAGMENT,tdt,1); + }else{ + if (om==NULL) + payload_header_set(h->b_wptr,ident,END_FRAGMENT,tdt,1); + else + payload_header_set(h->b_wptr,ident,CONT_FRAGMENT,tdt,1); + } + h->b_wptr+=4; + *((uint16_t*)h->b_wptr)=htons(msgdsize(packet)); + h->b_wptr+=2; + h->b_cont=packet; + mblk_set_timestamp_info(h,timestamp); + ms_debug("sending theora frame of size %i",msgdsize(h)); + ms_queue_put(f->outputs[0],h); + } +} + +bool_t need_send_conf(EncState *s, uint64_t elapsed){ +#ifdef AMD_HACK + if (elapsed<5000 && elapsed>=s->conf_time){ + s->conf_time+=500; + return TRUE; + } +#else + /*send immediately then 10 seconds later */ + if ( (elapsed<1000 && s->conf_time==0) + || (elapsed>10000 && s->conf_time==1)){ + s->conf_time++; + return TRUE; + } +#endif + return FALSE; +} + +static void enc_process(MSFilter *f){ + mblk_t *im,*om; + ogg_packet op; + EncState *s=(EncState*)f->data; + uint64_t timems=f->ticker->time; + uint32_t timestamp=timems*90; + uint64_t elapsed=timems-s->start_time; + while((im=ms_queue_get(f->inputs[0]))!=NULL){ + /*for the firsts frames only send theora packed conf*/ + om=NULL; + + if (need_send_conf(s,elapsed)){ + if (s->packed_conf) { + om=dupmsg(s->packed_conf); + ms_message("sending theora packed conf (%i bytes)",msgdsize(om)); + packetize_and_send(f,s,om,timestamp,THEORA_PACKED_CONF); + }else { + ms_error("No packed conf to send."); + } + }else{ + enc_fill_yuv(&s->yuv,im); + ms_debug("subtmitting yuv frame to theora encoder..."); + if (theora_encode_YUVin(&s->tstate,&s->yuv)!=0){ + ms_error("theora_encode_YUVin error."); + }else{ + if (theora_encode_packetout(&s->tstate,0,&op)==1){ + ms_debug("Got theora coded frame"); + om=allocb(op.bytes,0); + memcpy(om->b_wptr,op.packet,op.bytes); + om->b_wptr+=op.bytes; + packetize_and_send(f,s,om,timestamp,THEORA_RAW_DATA); + } + } + } + freemsg(im); + } +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_SET_VIDEO_SIZE, enc_set_vsize }, + { MS_FILTER_SET_FPS, enc_set_fps }, + { MS_FILTER_GET_VIDEO_SIZE, enc_get_vsize }, + { MS_FILTER_GET_FPS, enc_get_fps }, + { MS_FILTER_ADD_ATTR, enc_add_attr }, + { MS_FILTER_SET_BITRATE, enc_set_br }, + { MS_FILTER_SET_MTU, enc_set_mtu }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_theora_enc_desc={ + MS_THEORA_ENC_ID, + "MSTheoraEnc", + "The theora video encoder from xiph.org", + MS_FILTER_ENCODER, + "theora", + 1, + 1, + enc_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_theora_enc_desc={ + .id=MS_THEORA_ENC_ID, + .name="MSTheoraEnc", + .text="The open-source and royalty-free 'theora' video codec from xiph.org", + .category=MS_FILTER_ENCODER, + .enc_fmt="theora", + .ninputs=1, + .noutputs=1, + .init=enc_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=enc_methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_theora_enc_desc) + +typedef struct DecState{ + theora_state tstate; + theora_info tinfo; + mblk_t *yuv; + mblk_t *curframe; + bool_t ready; +}DecState; + +static void dec_init(MSFilter *f){ + DecState *s=(DecState *)ms_new(DecState,1); + s->ready=FALSE; + theora_info_init(&s->tinfo); + s->yuv=NULL; + s->curframe=NULL; + f->data=s; +} + +static void dec_uninit(MSFilter *f){ + DecState *s=(DecState*)f->data; + if (s->yuv!=NULL) freemsg(s->yuv); + if (s->curframe!=NULL) freemsg(s->curframe); + theora_info_clear(&s->tinfo); + ms_free(s); +} + +static bool_t dec_init_theora(DecState *s, ogg_packet *op){ + theora_comment tcom; + static const int ident_packet_size=42; + theora_comment_init(&tcom); + tcom.vendor="dummy"; + op->b_o_s=1; + if (theora_decode_header(&s->tinfo,&tcom,op)==0){ + op->packet+=ident_packet_size; + op->bytes-=ident_packet_size; + /*recall once to decode tables*/ + if (theora_decode_header(&s->tinfo,&tcom,op)==0){ + if (theora_decode_init(&s->tstate,&s->tinfo)==0){ + ms_debug("theora decoder ready, pixfmt=%i", + s->tinfo.pixelformat); + return TRUE; + } + }else{ + ms_warning("error decoding theora tables"); + } + }else{ + ms_warning("error decoding theora header"); + } + return FALSE; +} +/* remove payload header and agregates fragmented packets */ +static mblk_t *dec_unpacketize(MSFilter *f, DecState *s, mblk_t *im, int *tdt){ + uint8_t ft; + *tdt=payload_header_get_tdt((uint8_t*)im->b_rptr); + ft=payload_header_get_ft((uint8_t*)im->b_rptr); + im->b_rptr+=6; + + if (ft==NOT_FRAGMENTED) return im; + if (ft==START_FRAGMENT){ + if (s->curframe!=NULL) + freemsg(s->curframe); + s->curframe=im; + }else if (ft==CONT_FRAGMENT){ + if (s->curframe!=NULL) + concatb(s->curframe,im); + else + freemsg(im); + }else{/*end fragment*/ + if (s->curframe!=NULL){ + mblk_t *ret; + concatb(s->curframe,im); + msgpullup(s->curframe,-1); + ret=s->curframe; + s->curframe=NULL; + return ret; + }else + freemsg(im); + } + return NULL; +} + +static void dec_process_frame(MSFilter *f, DecState *s, ogg_packet *op){ + yuv_buffer yuv; + if (theora_decode_packetin(&s->tstate,op)==0){ + if (theora_decode_YUVout(&s->tstate,&yuv)==0){ + mblk_t *om; + int i; + int ylen=yuv.y_width*yuv.y_height; + int uvlen=yuv.uv_width*yuv.uv_height; + ms_debug("Got yuv buffer from theora decoder"); + if (s->yuv==NULL){ + int len=(ylen)+(2*uvlen); + s->yuv=allocb(len,0); + } + om=dupb(s->yuv); + for(i=0;ib_wptr,yuv.y+yuv.y_stride*i,yuv.y_width); + om->b_wptr+=yuv.y_width; + } + for(i=0;ib_wptr,yuv.u+yuv.uv_stride*i,yuv.uv_width); + om->b_wptr+=yuv.uv_width; + } + for(i=0;ib_wptr,yuv.v+yuv.uv_stride*i,yuv.uv_width); + om->b_wptr+=yuv.uv_width; + } + ms_queue_put(f->outputs[0],om); + } + }else{ + ms_warning("theora decoding error"); + } +} + +static void dec_process(MSFilter *f){ + mblk_t *im; + mblk_t *m; + ogg_packet op; + int tdt; + DecState *s=(DecState*)f->data; + while( (im=ms_queue_get(f->inputs[0]))!=0) { + m=dec_unpacketize(f,s,im,&tdt); + if (m!=NULL){ + /* now in im we have only the theora data*/ + op.packet=(uint8_t*)m->b_rptr; + op.bytes=m->b_wptr-m->b_rptr; + op.b_o_s=0; + op.e_o_s=0; + op.granulepos=0; + op.packetno=0; + if (tdt!=THEORA_RAW_DATA) /*packed conf*/ { + if (!s->ready){ + if (dec_init_theora(s,&op)) + s->ready=TRUE; + } + }else{ + if (s->ready){ + dec_process_frame(f,s,&op); + }else{ + ms_warning("skipping theora packet because decoder was not initialized yet with theora header and tables"); + } + } + freemsg(m); + } + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_theora_dec_desc={ + MS_THEORA_DEC_ID, + "MSTheoraDec", + "The theora video decoder from xiph.org", + MS_FILTER_DECODER, + "theora", + 1, + 1, + dec_init, + NULL, + dec_process, + NULL, + dec_uninit, + NULL +}; + +#else + +MSFilterDesc ms_theora_dec_desc={ + .id=MS_THEORA_DEC_ID, + .name="MSTheoraDec", + .text="The theora video decoder from xiph.org", + .category=MS_FILTER_DECODER, + .enc_fmt="theora", + .ninputs=1, + .noutputs=1, + .init=dec_init, + .process=dec_process, + .uninit=dec_uninit +}; + +#endif +MS_FILTER_DESC_EXPORT(ms_theora_dec_desc) diff --git a/linphone/mediastreamer2/src/ulaw.c b/linphone/mediastreamer2/src/ulaw.c new file mode 100644 index 000000000..de1c6788e --- /dev/null +++ b/linphone/mediastreamer2/src/ulaw.c @@ -0,0 +1,227 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msfilter.h" +#include "g711common.h" + +typedef struct _UlawEncData{ + MSBufferizer *bz; + int ptime; + uint32_t ts; +} UlawEncData; + +static UlawEncData * ulaw_enc_data_new(){ + UlawEncData *obj=(UlawEncData *)ms_new(UlawEncData,1); + obj->bz=ms_bufferizer_new(); + obj->ptime=0; + obj->ts=0; + return obj; +} + +static void ulaw_enc_data_destroy(UlawEncData *obj){ + ms_bufferizer_destroy(obj->bz); + ms_free(obj); +} + +static void ulaw_enc_init(MSFilter *obj){ + obj->data=ulaw_enc_data_new(); +} + +static void ulaw_enc_uninit(MSFilter *obj){ + ulaw_enc_data_destroy((UlawEncData*)obj->data); +} + +static void ulaw_enc_process(MSFilter *obj){ + UlawEncData *dt=(UlawEncData*)obj->data; + MSBufferizer *bz=dt->bz; + uint8_t buffer[2240]; + int frame_per_packet=2; + int size_of_pcm=320; + + mblk_t *m; + + if (dt->ptime>=10) + { + frame_per_packet = dt->ptime/10; + } + + if (frame_per_packet<=0) + frame_per_packet=1; + if (frame_per_packet>14) /* 7*20 == 140 ms max */ + frame_per_packet=14; + + size_of_pcm = 160*frame_per_packet; /* ex: for 20ms -> 160*2==320 */ + + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + ms_bufferizer_put(bz,m); + } + + while (ms_bufferizer_read(bz,buffer,size_of_pcm)==size_of_pcm){ + mblk_t *o=allocb(size_of_pcm/2,0); + int i; + for (i=0;ib_wptr=s16_to_ulaw(((int16_t*)buffer)[i]); + o->b_wptr++; + } + mblk_set_timestamp_info(o,dt->ts); + dt->ts+=size_of_pcm/2; + ms_queue_put(obj->outputs[0],o); + } +} + +static int enc_add_fmtp(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + UlawEncData *s=(UlawEncData*)f->data; + char val[30]; + if (fmtp_get_value(fmtp,"ptime",val,sizeof(val))){ + s->ptime=atoi(val); + ms_message("MSUlawEnc: got ptime=%i",s->ptime); + } + return 0; +} + + +static int enc_add_attr(MSFilter *f, void *arg){ + const char *fmtp=(const char *)arg; + UlawEncData *s=(UlawEncData*)f->data; + if (strstr(fmtp,"ptime:10")!=NULL){ + s->ptime=10; + }else if (strstr(fmtp,"ptime:20")!=NULL){ + s->ptime=20; + }else if (strstr(fmtp,"ptime:30")!=NULL){ + s->ptime=30; + }else if (strstr(fmtp,"ptime:40")!=NULL){ + s->ptime=40; + }else if (strstr(fmtp,"ptime:50")!=NULL){ + s->ptime=50; + }else if (strstr(fmtp,"ptime:60")!=NULL){ + s->ptime=60; + }else if (strstr(fmtp,"ptime:70")!=NULL){ + s->ptime=70; + }else if (strstr(fmtp,"ptime:80")!=NULL){ + s->ptime=80; + }else if (strstr(fmtp,"ptime:90")!=NULL){ + s->ptime=90; + }else if (strstr(fmtp,"ptime:100")!=NULL){ + s->ptime=100; + }else if (strstr(fmtp,"ptime:110")!=NULL){ + s->ptime=110; + }else if (strstr(fmtp,"ptime:120")!=NULL){ + s->ptime=120; + }else if (strstr(fmtp,"ptime:130")!=NULL){ + s->ptime=130; + }else if (strstr(fmtp,"ptime:140")!=NULL){ + s->ptime=140; + } + return 0; +} + +static MSFilterMethod enc_methods[]={ + { MS_FILTER_ADD_ATTR , enc_add_attr}, + { MS_FILTER_ADD_FMTP , enc_add_fmtp}, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_ulaw_enc_desc={ + MS_ULAW_ENC_ID, + "MSUlawEnc", + "ITU-G.711 ulaw encoder", + MS_FILTER_ENCODER, + "pcmu", + 1, + 1, + ulaw_enc_init, + NULL, + ulaw_enc_process, + NULL, + ulaw_enc_uninit, + enc_methods +}; + +#else + +MSFilterDesc ms_ulaw_enc_desc={ + .id=MS_ULAW_ENC_ID, + .name="MSUlawEnc", + .text="ITU-G.711 ulaw encoder", + .category=MS_FILTER_ENCODER, + .enc_fmt="pcmu", + .ninputs=1, + .noutputs=1, + .init=ulaw_enc_init, + .process=ulaw_enc_process, + .uninit=ulaw_enc_uninit, + .methods=enc_methods +}; + +#endif + +static void ulaw_dec_process(MSFilter *obj){ + mblk_t *m; + while((m=ms_queue_get(obj->inputs[0]))!=NULL){ + mblk_t *o; + msgpullup(m,-1); + o=allocb((m->b_wptr-m->b_rptr)*2,0); + for(;m->b_rptrb_wptr;m->b_rptr++,o->b_wptr+=2){ + *((int16_t*)(o->b_wptr))=ulaw_to_s16(*m->b_rptr); + } + freemsg(m); + ms_queue_put(obj->outputs[0],o); + } +} + +#ifdef _MSC_VER + +MSFilterDesc ms_ulaw_dec_desc={ + MS_ULAW_DEC_ID, + "MSUlawDec", + "ITU-G.711 ulaw decoder", + MS_FILTER_DECODER, + "pcmu", + 1, + 1, + NULL, + NULL, + ulaw_dec_process, + NULL, + NULL, + NULL +}; + +#else + +MSFilterDesc ms_ulaw_dec_desc={ + .id=MS_ULAW_DEC_ID, + .name="MSUlawDec", + .text="ITU-G.711 ulaw decoder", + .category=MS_FILTER_DECODER, + .enc_fmt="pcmu", + .ninputs=1, + .noutputs=1, + .process=ulaw_dec_process, +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_ulaw_dec_desc) +MS_FILTER_DESC_EXPORT(ms_ulaw_enc_desc) + + diff --git a/linphone/mediastreamer2/src/vfw-missing.h b/linphone/mediastreamer2/src/vfw-missing.h new file mode 100755 index 000000000..155cd0cc1 --- /dev/null +++ b/linphone/mediastreamer2/src/vfw-missing.h @@ -0,0 +1,264 @@ +#ifndef vfw_missing_h +#define vfw_missing_h + +typedef struct videohdr_tag { + LPBYTE lpData; /* pointer to locked data buffer */ + DWORD dwBufferLength; /* Length of data buffer */ + DWORD dwBytesUsed; /* Bytes actually used */ + DWORD dwTimeCaptured; /* Milliseconds from start of stream */ + DWORD_PTR dwUser; /* for client's use */ + DWORD dwFlags; /* assorted flags (see defines) */ + DWORD_PTR dwReserved[4]; /* reserved for driver */ +} VIDEOHDR, NEAR *PVIDEOHDR, FAR * LPVIDEOHDR; + +typedef struct tagCaptureParms { + DWORD dwRequestMicroSecPerFrame; // Requested capture rate + BOOL fMakeUserHitOKToCapture; // Show "Hit OK to cap" dlg? + UINT wPercentDropForError; // Give error msg if > (10%) + BOOL fYield; // Capture via background task? + DWORD dwIndexSize; // Max index size in frames (32K) + UINT wChunkGranularity; // Junk chunk granularity (2K) + BOOL fUsingDOSMemory; // Use DOS buffers? + UINT wNumVideoRequested; // # video buffers, If 0, autocalc + BOOL fCaptureAudio; // Capture audio? + UINT wNumAudioRequested; // # audio buffers, If 0, autocalc + UINT vKeyAbort; // Virtual key causing abort + BOOL fAbortLeftMouse; // Abort on left mouse? + BOOL fAbortRightMouse; // Abort on right mouse? + BOOL fLimitEnabled; // Use wTimeLimit? + UINT wTimeLimit; // Seconds to capture + BOOL fMCIControl; // Use MCI video source? + BOOL fStepMCIDevice; // Step MCI device? + DWORD dwMCIStartTime; // Time to start in MS + DWORD dwMCIStopTime; // Time to stop in MS + BOOL fStepCaptureAt2x; // Perform spatial averaging 2x + UINT wStepCaptureAverageFrames; // Temporal average n Frames + DWORD dwAudioBufferSize; // Size of audio bufs (0 = default) + BOOL fDisableWriteCache; // Attempt to disable write cache + UINT AVStreamMaster; // Which stream controls length? +} CAPTUREPARMS, *PCAPTUREPARMS, FAR *LPCAPTUREPARMS; + +#ifdef __cplusplus +/* SendMessage in C++*/ +#define AVICapSM(hwnd,m,w,l) ( (::IsWindow(hwnd)) ? ::SendMessage(hwnd,m,w,l) : 0) +#else +/* SendMessage in C */ +#define AVICapSM(hwnd,m,w,l) ( (IsWindow(hwnd)) ? SendMessage(hwnd,m,w,l) : 0) +#endif /* __cplusplus */ + +#define WM_CAP_START WM_USER + +// start of unicode messages +#define WM_CAP_UNICODE_START WM_USER+100 + +#define WM_CAP_GET_CAPSTREAMPTR (WM_CAP_START+ 1) + +#define WM_CAP_SET_CALLBACK_ERRORW (WM_CAP_UNICODE_START+ 2) +#define WM_CAP_SET_CALLBACK_STATUSW (WM_CAP_UNICODE_START+ 3) +#define WM_CAP_SET_CALLBACK_ERRORA (WM_CAP_START+ 2) +#define WM_CAP_SET_CALLBACK_STATUSA (WM_CAP_START+ 3) +#ifdef UNICODE +#define WM_CAP_SET_CALLBACK_ERROR WM_CAP_SET_CALLBACK_ERRORW +#define WM_CAP_SET_CALLBACK_STATUS WM_CAP_SET_CALLBACK_STATUSW +#else +#define WM_CAP_SET_CALLBACK_ERROR WM_CAP_SET_CALLBACK_ERRORA +#define WM_CAP_SET_CALLBACK_STATUS WM_CAP_SET_CALLBACK_STATUSA +#endif + + +#define WM_CAP_SET_CALLBACK_YIELD (WM_CAP_START+ 4) +#define WM_CAP_SET_CALLBACK_FRAME (WM_CAP_START+ 5) +#define WM_CAP_SET_CALLBACK_VIDEOSTREAM (WM_CAP_START+ 6) +#define WM_CAP_SET_CALLBACK_WAVESTREAM (WM_CAP_START+ 7) +#define WM_CAP_GET_USER_DATA (WM_CAP_START+ 8) +#define WM_CAP_SET_USER_DATA (WM_CAP_START+ 9) + +#define WM_CAP_DRIVER_CONNECT (WM_CAP_START+ 10) +#define WM_CAP_DRIVER_DISCONNECT (WM_CAP_START+ 11) + +#define WM_CAP_DRIVER_GET_NAMEA (WM_CAP_START+ 12) +#define WM_CAP_DRIVER_GET_VERSIONA (WM_CAP_START+ 13) +#define WM_CAP_DRIVER_GET_NAMEW (WM_CAP_UNICODE_START+ 12) +#define WM_CAP_DRIVER_GET_VERSIONW (WM_CAP_UNICODE_START+ 13) +#ifdef UNICODE +#define WM_CAP_DRIVER_GET_NAME WM_CAP_DRIVER_GET_NAMEW +#define WM_CAP_DRIVER_GET_VERSION WM_CAP_DRIVER_GET_VERSIONW +#else +#define WM_CAP_DRIVER_GET_NAME WM_CAP_DRIVER_GET_NAMEA +#define WM_CAP_DRIVER_GET_VERSION WM_CAP_DRIVER_GET_VERSIONA +#endif + +#define WM_CAP_DRIVER_GET_CAPS (WM_CAP_START+ 14) + +#define WM_CAP_FILE_SET_CAPTURE_FILEA (WM_CAP_START+ 20) +#define WM_CAP_FILE_GET_CAPTURE_FILEA (WM_CAP_START+ 21) +#define WM_CAP_FILE_SAVEASA (WM_CAP_START+ 23) +#define WM_CAP_FILE_SAVEDIBA (WM_CAP_START+ 25) +#define WM_CAP_FILE_SET_CAPTURE_FILEW (WM_CAP_UNICODE_START+ 20) +#define WM_CAP_FILE_GET_CAPTURE_FILEW (WM_CAP_UNICODE_START+ 21) +#define WM_CAP_FILE_SAVEASW (WM_CAP_UNICODE_START+ 23) +#define WM_CAP_FILE_SAVEDIBW (WM_CAP_UNICODE_START+ 25) +#ifdef UNICODE +#define WM_CAP_FILE_SET_CAPTURE_FILE WM_CAP_FILE_SET_CAPTURE_FILEW +#define WM_CAP_FILE_GET_CAPTURE_FILE WM_CAP_FILE_GET_CAPTURE_FILEW +#define WM_CAP_FILE_SAVEAS WM_CAP_FILE_SAVEASW +#define WM_CAP_FILE_SAVEDIB WM_CAP_FILE_SAVEDIBW +#else +#define WM_CAP_FILE_SET_CAPTURE_FILE WM_CAP_FILE_SET_CAPTURE_FILEA +#define WM_CAP_FILE_GET_CAPTURE_FILE WM_CAP_FILE_GET_CAPTURE_FILEA +#define WM_CAP_FILE_SAVEAS WM_CAP_FILE_SAVEASA +#define WM_CAP_FILE_SAVEDIB WM_CAP_FILE_SAVEDIBA +#endif + +// out of order to save on ifdefs +#define WM_CAP_FILE_ALLOCATE (WM_CAP_START+ 22) +#define WM_CAP_FILE_SET_INFOCHUNK (WM_CAP_START+ 24) + +#define WM_CAP_EDIT_COPY (WM_CAP_START+ 30) + +#define WM_CAP_SET_AUDIOFORMAT (WM_CAP_START+ 35) +#define WM_CAP_GET_AUDIOFORMAT (WM_CAP_START+ 36) + +#define WM_CAP_DLG_VIDEOFORMAT (WM_CAP_START+ 41) +#define WM_CAP_DLG_VIDEOSOURCE (WM_CAP_START+ 42) +#define WM_CAP_DLG_VIDEODISPLAY (WM_CAP_START+ 43) +#define WM_CAP_GET_VIDEOFORMAT (WM_CAP_START+ 44) +#define WM_CAP_SET_VIDEOFORMAT (WM_CAP_START+ 45) +#define WM_CAP_DLG_VIDEOCOMPRESSION (WM_CAP_START+ 46) + +#define WM_CAP_SET_PREVIEW (WM_CAP_START+ 50) +#define WM_CAP_SET_OVERLAY (WM_CAP_START+ 51) +#define WM_CAP_SET_PREVIEWRATE (WM_CAP_START+ 52) +#define WM_CAP_SET_SCALE (WM_CAP_START+ 53) +#define WM_CAP_GET_STATUS (WM_CAP_START+ 54) +#define WM_CAP_SET_SCROLL (WM_CAP_START+ 55) + +#define WM_CAP_GRAB_FRAME (WM_CAP_START+ 60) +#define WM_CAP_GRAB_FRAME_NOSTOP (WM_CAP_START+ 61) + +#define WM_CAP_SEQUENCE (WM_CAP_START+ 62) +#define WM_CAP_SEQUENCE_NOFILE (WM_CAP_START+ 63) +#define WM_CAP_SET_SEQUENCE_SETUP (WM_CAP_START+ 64) +#define WM_CAP_GET_SEQUENCE_SETUP (WM_CAP_START+ 65) + +#define WM_CAP_SET_MCI_DEVICEA (WM_CAP_START+ 66) +#define WM_CAP_GET_MCI_DEVICEA (WM_CAP_START+ 67) +#define WM_CAP_SET_MCI_DEVICEW (WM_CAP_UNICODE_START+ 66) +#define WM_CAP_GET_MCI_DEVICEW (WM_CAP_UNICODE_START+ 67) +#ifdef UNICODE +#define WM_CAP_SET_MCI_DEVICE WM_CAP_SET_MCI_DEVICEW +#define WM_CAP_GET_MCI_DEVICE WM_CAP_GET_MCI_DEVICEW +#else +#define WM_CAP_SET_MCI_DEVICE WM_CAP_SET_MCI_DEVICEA +#define WM_CAP_GET_MCI_DEVICE WM_CAP_GET_MCI_DEVICEA +#endif + + + +#define WM_CAP_STOP (WM_CAP_START+ 68) +#define WM_CAP_ABORT (WM_CAP_START+ 69) + +#define WM_CAP_SINGLE_FRAME_OPEN (WM_CAP_START+ 70) +#define WM_CAP_SINGLE_FRAME_CLOSE (WM_CAP_START+ 71) +#define WM_CAP_SINGLE_FRAME (WM_CAP_START+ 72) + +#define WM_CAP_PAL_OPENA (WM_CAP_START+ 80) +#define WM_CAP_PAL_SAVEA (WM_CAP_START+ 81) +#define WM_CAP_PAL_OPENW (WM_CAP_UNICODE_START+ 80) +#define WM_CAP_PAL_SAVEW (WM_CAP_UNICODE_START+ 81) +#ifdef UNICODE +#define WM_CAP_PAL_OPEN WM_CAP_PAL_OPENW +#define WM_CAP_PAL_SAVE WM_CAP_PAL_SAVEW +#else +#define WM_CAP_PAL_OPEN WM_CAP_PAL_OPENA +#define WM_CAP_PAL_SAVE WM_CAP_PAL_SAVEA +#endif + +#define WM_CAP_PAL_PASTE (WM_CAP_START+ 82) +#define WM_CAP_PAL_AUTOCREATE (WM_CAP_START+ 83) +#define WM_CAP_PAL_MANUALCREATE (WM_CAP_START+ 84) + +// Following added post VFW 1.1 +#define WM_CAP_SET_CALLBACK_CAPCONTROL (WM_CAP_START+ 85) + + +// Defines end of the message range +#define WM_CAP_UNICODE_END WM_CAP_PAL_SAVEW +#define WM_CAP_END WM_CAP_UNICODE_END + +#define capSetCallbackOnError(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_ERROR, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnStatus(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_STATUS, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnYield(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_YIELD, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnFrame(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_FRAME, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnVideoStream(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnWaveStream(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_WAVESTREAM, 0, (LPARAM)(LPVOID)(fpProc))) +#define capSetCallbackOnCapControl(hwnd, fpProc) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_CALLBACK_CAPCONTROL, 0, (LPARAM)(LPVOID)(fpProc))) + +#define capSetUserData(hwnd, lUser) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_USER_DATA, 0, (LPARAM)lUser)) +#define capGetUserData(hwnd) (AVICapSM(hwnd, WM_CAP_GET_USER_DATA, 0, 0)) + +#define capDriverConnect(hwnd, i) ((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_CONNECT, (WPARAM)(i), 0L)) +#define capDriverDisconnect(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_DISCONNECT, (WPARAM)0, 0L)) +#define capDriverGetName(hwnd, szName, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_NAME, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capDriverGetVersion(hwnd, szVer, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_VERSION, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPTSTR)(szVer))) +#define capDriverGetCaps(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_CAPS, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPCAPDRIVERCAPS)(s))) + +#define capFileSetCaptureFile(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SET_CAPTURE_FILE, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capFileGetCaptureFile(hwnd, szName, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_GET_CAPTURE_FILE, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capFileAlloc(hwnd, dwSize) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_ALLOCATE, 0, (LPARAM)(DWORD)(dwSize))) +#define capFileSaveAs(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SAVEAS, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capFileSetInfoChunk(hwnd, lpInfoChunk) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SET_INFOCHUNK, (WPARAM)0, (LPARAM)(LPCAPINFOCHUNK)(lpInfoChunk))) +#define capFileSaveDIB(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SAVEDIB, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) + +#define capEditCopy(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_EDIT_COPY, 0, 0L)) + +#define capSetAudioFormat(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_AUDIOFORMAT, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPWAVEFORMATEX)(s))) +#define capGetAudioFormat(hwnd, s, wSize) ((DWORD)AVICapSM(hwnd, WM_CAP_GET_AUDIOFORMAT, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPWAVEFORMATEX)(s))) +#define capGetAudioFormatSize(hwnd) ((DWORD)AVICapSM(hwnd, WM_CAP_GET_AUDIOFORMAT, (WPARAM)0, (LPARAM)0L)) + +#define capDlgVideoFormat(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0L)) +#define capDlgVideoSource(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0L)) +#define capDlgVideoDisplay(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEODISPLAY, 0, 0L)) +#define capDlgVideoCompression(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0L)) + +#define capGetVideoFormat(hwnd, s, wSize) ((DWORD)AVICapSM(hwnd, WM_CAP_GET_VIDEOFORMAT, (WPARAM)(wSize), (LPARAM)(LPVOID)(s))) +#define capGetVideoFormatSize(hwnd) ((DWORD)AVICapSM(hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0L)) +#define capSetVideoFormat(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_VIDEOFORMAT, (WPARAM)(wSize), (LPARAM)(LPVOID)(s))) + +#define capPreview(hwnd, f) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_PREVIEW, (WPARAM)(BOOL)(f), 0L)) +#define capPreviewRate(hwnd, wMS) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_PREVIEWRATE, (WPARAM)(wMS), 0)) +#define capOverlay(hwnd, f) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_OVERLAY, (WPARAM)(BOOL)(f), 0L)) +#define capPreviewScale(hwnd, f) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_SCALE, (WPARAM)(BOOL)f, 0L)) +#define capGetStatus(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_GET_STATUS, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPCAPSTATUS)(s))) +#define capSetScrollPos(hwnd, lpP) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_SCROLL, (WPARAM)0, (LPARAM)(LPPOINT)(lpP))) + +#define capGrabFrame(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_GRAB_FRAME, (WPARAM)0, (LPARAM)0L)) +#define capGrabFrameNoStop(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_GRAB_FRAME_NOSTOP, (WPARAM)0, (LPARAM)0L)) + +#define capCaptureSequence(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_SEQUENCE, (WPARAM)0, (LPARAM)0L)) +#define capCaptureSequenceNoFile(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_SEQUENCE_NOFILE, (WPARAM)0, (LPARAM)0L)) +#define capCaptureStop(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_STOP, (WPARAM)0, (LPARAM)0L)) +#define capCaptureAbort(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_ABORT, (WPARAM)0, (LPARAM)0L)) + +#define capCaptureSingleFrameOpen(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME_OPEN, (WPARAM)0, (LPARAM)0L)) +#define capCaptureSingleFrameClose(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME_CLOSE, (WPARAM)0, (LPARAM)0L)) +#define capCaptureSingleFrame(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME, (WPARAM)0, (LPARAM)0L)) + +#define capCaptureGetSetup(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_GET_SEQUENCE_SETUP, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPCAPTUREPARMS)(s))) +#define capCaptureSetSetup(hwnd, s, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_SEQUENCE_SETUP, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPCAPTUREPARMS)(s))) + +#define capSetMCIDeviceName(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_SET_MCI_DEVICE, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capGetMCIDeviceName(hwnd, szName, wSize) ((BOOL)AVICapSM(hwnd, WM_CAP_GET_MCI_DEVICE, (WPARAM)(wSize), (LPARAM)(LPVOID)(LPTSTR)(szName))) + +#define capPaletteOpen(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_PAL_OPEN, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capPaletteSave(hwnd, szName) ((BOOL)AVICapSM(hwnd, WM_CAP_PAL_SAVE, 0, (LPARAM)(LPVOID)(LPTSTR)(szName))) +#define capPalettePaste(hwnd) ((BOOL)AVICapSM(hwnd, WM_CAP_PAL_PASTE, (WPARAM) 0, (LPARAM)0L)) +#define capPaletteAuto(hwnd, iFrames, iColors) ((BOOL)AVICapSM(hwnd, WM_CAP_PAL_AUTOCREATE, (WPARAM)(iFrames), (LPARAM)(DWORD)(iColors))) +#define capPaletteManual(hwnd, fGrab, iColors) ((BOOL)AVICapSM(hwnd, WM_CAP_PAL_MANUALCREATE, (WPARAM)(fGrab), (LPARAM)(DWORD)(iColors))) + +#define AVSTREAMMASTER_AUDIO 0 /* Audio master (VFW 1.0, 1.1) */ +#define AVSTREAMMASTER_NONE 1 /* No master */ + + +#endif + diff --git a/linphone/mediastreamer2/src/videodec.c b/linphone/mediastreamer2/src/videodec.c new file mode 100644 index 000000000..2793ffef1 --- /dev/null +++ b/linphone/mediastreamer2/src/videodec.c @@ -0,0 +1,464 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "ffmpeg-priv.h" + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" +#include "rfc2429.h" + + +extern void ms_ffmpeg_check_init(); + +typedef struct DecState{ + AVCodecContext av_context; + AVCodec *av_codec; + enum CodecID codec; + mblk_t *input; + YuvBuf outbuf; + mblk_t *yuv_msg; + struct SwsContext *sws_ctx; + int output_pix_fmt; + uint8_t dci[512]; + int dci_size; + bool_t snow_initialized; +}DecState; + + +static void dec_init(MSFilter *f, enum CodecID cid){ + DecState *s=(DecState *)ms_new0(DecState,1); + ms_ffmpeg_check_init(); + + avcodec_get_context_defaults(&s->av_context); + s->av_codec=NULL; + s->codec=cid; + s->input=NULL; + s->yuv_msg=NULL; + s->output_pix_fmt=PIX_FMT_YUV420P; + s->snow_initialized=FALSE; + s->outbuf.w=0; + s->outbuf.h=0; + s->sws_ctx=NULL; + f->data=s; + + s->av_codec=avcodec_find_decoder(s->codec); + if (s->av_codec==NULL){ + ms_error("Could not find decoder %i!",s->codec); + } + /* + s->av_context.width=MS_VIDEO_SIZE_QCIF_W; + s->av_context.height=MS_VIDEO_SIZE_QCIF_H; + */ +} + +static void dec_h263_init(MSFilter *f){ + dec_init(f,CODEC_ID_H263); +} + +static void dec_mpeg4_init(MSFilter *f){ + dec_init(f,CODEC_ID_MPEG4); +} + +static void dec_mjpeg_init(MSFilter *f){ + dec_init(f,CODEC_ID_MJPEG); +} + +static void dec_snow_init(MSFilter *f){ + dec_init(f,CODEC_ID_SNOW); +} + +static void dec_uninit(MSFilter *f){ + DecState *s=(DecState*)f->data; + if (s->input!=NULL) freemsg(s->input); + if (s->yuv_msg!=NULL) freemsg(s->yuv_msg); + if (s->sws_ctx!=NULL){ + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + ms_free(s); +} + +static int dec_add_fmtp(MSFilter *f, void *data){ + const char *fmtp=(const char*)data; + DecState *s=(DecState*)f->data; + char config[512]; + if (fmtp_get_value(fmtp,"config",config,sizeof(config))){ + /*convert hexa decimal config string into a bitstream */ + int i,j,max=strlen(config); + char octet[3]; + octet[2]=0; + for(i=0,j=0;idci[j]=strtol(octet,NULL,16); + } + s->dci_size=j; + ms_message("Got mpeg4 config string: %s",config); + } + return 0; +} + +static void dec_preprocess(MSFilter *f){ + DecState *s=(DecState*)f->data; + int error; + /* we must know picture size before initializing snow decoder*/ + if (s->codec!=CODEC_ID_SNOW){ + error=avcodec_open(&s->av_context, s->av_codec); + if (error!=0) ms_error("avcodec_open() failed: %i",error); + if (s->codec==CODEC_ID_MPEG4 && s->dci_size>0){ + s->av_context.extradata=s->dci; + s->av_context.extradata_size=s->dci_size; + } + } +} + +static void dec_postprocess(MSFilter *f){ + DecState *s=(DecState*)f->data; + if (s->av_context.codec!=NULL){ + avcodec_close(&s->av_context); + s->av_context.codec=NULL; + } +} + +static mblk_t * skip_rfc2190_header(mblk_t *inm){ + if (msgdsize(inm) >= 4) { + uint8_t *ph = inm->b_rptr; + int F = (ph[0]>>7) & 0x1; + int P = (ph[0]>>6) & 0x1; + if (F == 0) inm->b_rptr += 4; // mode A + else if (P == 0) inm->b_rptr += 8; // mode B + else inm->b_rptr += 12; // mode C + } else { + freemsg(inm); + inm=NULL; + } + return inm; +} + +static mblk_t * skip_rfc2429_header(mblk_t *inm){ + if (msgdsize(inm) >= 2){ + uint32_t *p = (uint32_t*)inm->b_rptr; + uint8_t *ph=inm->b_rptr; + int PLEN; + int gob_num; + bool_t P; + + P=rfc2429_get_P(ph); + PLEN=rfc2429_get_PLEN(ph); + /*printf("receiving new packet; P=%i; V=%i; PLEN=%i; PEBIT=%i\n",P,rfc2429_get_V(ph),PLEN,rfc2429_get_PEBIT(ph)); + */ + gob_num = (ntohl(*p) >> 10) & 0x1f; + /*ms_message("gob %i, size %i", gob_num, msgdsize(inm)); + ms_message("ms_AVdecoder_process: received %08x %08x", ntohl(p[0]), ntohl(p[1]));*/ + + /* remove H.263 Payload Header */ + if (PLEN>0){ + /* we ignore the redundant picture header and + directly go to the bitstream */ + inm->b_rptr+=PLEN; + } + if (P){ + inm->b_rptr[0]=inm->b_rptr[1]=0; + }else{ + /* no PSC omitted */ + inm->b_rptr+=2; + } + return inm; + }else freemsg(inm); + return NULL; +} + +static mblk_t * parse_snow_header(DecState *s,mblk_t *inm){ + if (msgdsize(inm) >= 4){ + uint32_t h = ntohl(*(uint32_t*)inm->b_rptr); + if (!s->snow_initialized){ + int error; + s->av_context.width=h>>16; + s->av_context.height=h&0xffff; + error=avcodec_open(&s->av_context, s->av_codec); + if (error!=0) ms_error("avcodec_open() failed for snow: %i",error); + else { + s->snow_initialized=TRUE; + ms_message("Snow decoder initialized,size=%ix%i", + s->av_context.width, + s->av_context.height); + } + } + inm->b_rptr+=4; + return inm; + }else { + freemsg(inm); + return NULL; + } +} + +static mblk_t *get_as_yuvmsg(MSFilter *f, DecState *s, AVFrame *orig){ + AVCodecContext *ctx=&s->av_context; + + if (s->outbuf.w!=ctx->width || s->outbuf.h!=ctx->height){ + if (s->sws_ctx!=NULL){ + sws_freeContext(s->sws_ctx); + s->sws_ctx=NULL; + } + s->yuv_msg=yuv_buf_alloc(&s->outbuf,ctx->width,ctx->height); + s->outbuf.w=ctx->width; + s->outbuf.h=ctx->height; + s->sws_ctx=sws_getContext(ctx->width,ctx->height,ctx->pix_fmt, + ctx->width,ctx->height,s->output_pix_fmt,SWS_FAST_BILINEAR, + NULL, NULL, NULL); + } + if (sws_scale(s->sws_ctx,orig->data,orig->linesize, 0, + ctx->height, s->outbuf.planes, s->outbuf.strides)<0){ + ms_error("%s: error in sws_scale().",f->desc->name); + } + return dupmsg(s->yuv_msg); +} + +static void dec_process_frame(MSFilter *f, mblk_t *inm){ + DecState *s=(DecState*)f->data; + AVFrame orig; + int got_picture; + /* get a picture from the input queue */ + + if (f->desc->id==MS_H263_DEC_ID) inm=skip_rfc2429_header(inm); + else if (f->desc->id==MS_H263_OLD_DEC_ID) inm=skip_rfc2190_header(inm); + else if (s->codec==CODEC_ID_SNOW && s->input==NULL) inm=parse_snow_header(s,inm); + if (inm){ + /* accumulate the video packet until we have the rtp markbit*/ + if (s->input==NULL){ + s->input=inm; + }else{ + concatb(s->input,inm); + } + + if (mblk_get_marker_info(inm)){ + mblk_t *frame; + int remain,len; + /*ms_message("got marker bit !");*/ + /*append some padding bytes for ffmpeg to safely + read extra bytes...*/ + msgpullup(s->input,msgdsize(s->input)+8); + frame=s->input; + s->input=NULL; + while ( (remain=frame->b_wptr-frame->b_rptr)> 0) { + len=avcodec_decode_video(&s->av_context,&orig,&got_picture,(uint8_t*)frame->b_rptr,remain ); + if (len<=0) { + ms_warning("ms_AVdecoder_process: error %i.",len); + break; + } + if (got_picture) { + ms_queue_put(f->outputs[0],get_as_yuvmsg(f,s,&orig)); + } + frame->b_rptr+=len; + } + freemsg(frame); + } + } +} + +static void dec_process(MSFilter *f){ + mblk_t *inm; + while((inm=ms_queue_get(f->inputs[0]))!=0){ + dec_process_frame(f,inm); + } +} + + +static MSFilterMethod methods[]={ + { MS_FILTER_ADD_FMTP , dec_add_fmtp }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_h263_dec_desc={ + MS_H263_DEC_ID, + "MSH263Dec", + "A H.263 decoder using ffmpeg library", + MS_FILTER_DECODER, + "H263-1998", + 1, + 1, + dec_h263_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + methods +}; + +MSFilterDesc ms_h263_old_dec_desc={ + MS_H263_DEC_ID, + "MSH263OldDec", + "A H.263 decoder using ffmpeg library", + MS_FILTER_DECODER, + "H263", + 1, + 1, + dec_h263_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + methods +}; + + +MSFilterDesc ms_mpeg4_dec_desc={ + MS_MPEG4_DEC_ID, + "MSMpeg4Dec", + "A MPEG4 decoder using ffmpeg library", + MS_FILTER_DECODER, + "MP4V-ES", + 1, + 1, + dec_mpeg4_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + methods +}; + +MSFilterDesc ms_mjpeg_dec_desc={ + MS_MJPEG_DEC_ID, + "MSMJpegDec", + "A MJPEG decoder using ffmpeg library", + MS_FILTER_DECODER, + "MJPEG", + 1, + 1, + dec_mjpeg_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + methods +}; + +MSFilterDesc ms_snow_dec_desc={ + MS_SNOW_DEC_ID, + "MSSnowDec", + "A snow decoder using ffmpeg library", + MS_FILTER_DECODER, + "snow", + 1, + 1, + dec_snow_init, + dec_preprocess, + dec_process, + dec_postprocess, + dec_uninit, + methods +}; + +#else + +MSFilterDesc ms_h263_dec_desc={ + .id=MS_H263_DEC_ID, + .name="MSH263Dec", + .text="A H.263 decoder using ffmpeg library", + .category=MS_FILTER_DECODER, + .enc_fmt="H263-1998", + .ninputs=1, + .noutputs=1, + .init=dec_h263_init, + .preprocess=dec_preprocess, + .process=dec_process, + .postprocess=dec_postprocess, + .uninit=dec_uninit, + .methods= methods +}; + +MSFilterDesc ms_h263_old_dec_desc={ + .id=MS_H263_OLD_DEC_ID, + .name="MSH263OldDec", + .text="A H.263 decoder using ffmpeg library", + .category=MS_FILTER_DECODER, + .enc_fmt="H263", + .ninputs=1, + .noutputs=1, + .init=dec_h263_init, + .preprocess=dec_preprocess, + .process=dec_process, + .postprocess=dec_postprocess, + .uninit=dec_uninit, + .methods= methods +}; + + +MSFilterDesc ms_mpeg4_dec_desc={ + .id=MS_MPEG4_DEC_ID, + .name="MSMpeg4Dec", + .text="A MPEG4 decoder using ffmpeg library", + .category=MS_FILTER_DECODER, + .enc_fmt="MP4V-ES", + .ninputs=1, + .noutputs=1, + .init=dec_mpeg4_init, + .preprocess=dec_preprocess, + .process=dec_process, + .postprocess=dec_postprocess, + .uninit=dec_uninit, + .methods= methods +}; + +MSFilterDesc ms_mjpeg_dec_desc={ + .id=MS_MJPEG_DEC_ID, + .name="MSMJpegDec", + .text="A MJEPG decoder using ffmpeg library", + .category=MS_FILTER_DECODER, + .enc_fmt="MJPEG", + .ninputs=1, + .noutputs=1, + .init=dec_mjpeg_init, + .preprocess=dec_preprocess, + .process=dec_process, + .postprocess=dec_postprocess, + .uninit=dec_uninit, + .methods= methods +}; + +MSFilterDesc ms_snow_dec_desc={ + .id=MS_SNOW_DEC_ID, + .name="MSSnowDec", + .text="A snow decoder using ffmpeg library", + .category=MS_FILTER_DECODER, + .enc_fmt="x-snow", + .ninputs=1, + .noutputs=1, + .init=dec_snow_init, + .preprocess=dec_preprocess, + .process=dec_process, + .postprocess=dec_postprocess, + .uninit=dec_uninit, + .methods= methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_mpeg4_dec_desc) +MS_FILTER_DESC_EXPORT(ms_h263_dec_desc) +MS_FILTER_DESC_EXPORT(ms_h263_old_dec_desc) +MS_FILTER_DESC_EXPORT(ms_mjpeg_dec_desc) +MS_FILTER_DESC_EXPORT(ms_snow_dec_desc) diff --git a/linphone/mediastreamer2/src/videoenc.c b/linphone/mediastreamer2/src/videoenc.c new file mode 100644 index 000000000..0b1004762 --- /dev/null +++ b/linphone/mediastreamer2/src/videoenc.c @@ -0,0 +1,703 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#ifdef HAVE_LIBAVCODEC_AVCODEC_H +#include +#else +#include +#endif +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" + +#ifdef _WIN32 +#include +#else +#include /* ntohl(3) */ +#endif + +#include "rfc2429.h" + +static bool_t avcodec_initialized=FALSE; + +void ms_ffmpeg_check_init(){ + if(!avcodec_initialized){ + avcodec_init(); + avcodec_register_all(); + avcodec_initialized=TRUE; + } +} + +typedef struct EncState{ + AVCodecContext av_context; + AVCodec *av_codec; + enum CodecID codec; + mblk_t *comp_buf; + MSVideoSize vsize; + int mtu; /* network maximum transmission unit in bytes */ + int profile; + float fps; + int maxbr; + int qmin; + bool_t req_vfu; +}EncState; + +static int enc_set_fps(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + s->fps=*(float*)arg; + return 0; +} + +static int enc_get_fps(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + *(float*)arg=s->fps; + return 0; +} + +static int enc_set_vsize(MSFilter *f,void *arg){ + EncState *s=(EncState*)f->data; + s->vsize=*(MSVideoSize*)arg; + return 0; +} + +static int enc_get_vsize(MSFilter *f,void *arg){ + EncState *s=(EncState*)f->data; + *(MSVideoSize*)arg=s->vsize; + return 0; +} + +static int enc_set_mtu(MSFilter *f,void *arg){ + EncState *s=(EncState*)f->data; + s->mtu=*(int*)arg; + return 0; +} + +static bool_t parse_video_fmtp(const char *fmtp, float *fps, MSVideoSize *vsize){ + char *tmp=ms_strdup(fmtp); + char *semicolon; + char *equal; + bool_t ret=TRUE; + + ms_message("parsing %s",fmtp); + /*extract fisrt pair */ + if ((semicolon=strchr(tmp,';'))!=NULL){ + *semicolon='\0'; + } + if ((equal=strchr(tmp,'='))!=NULL){ + int divider; + *equal='\0'; + if (strcasecmp(tmp,"CIF")==0){ + if (vsize->width>=MS_VIDEO_SIZE_CIF_W){ + vsize->width=MS_VIDEO_SIZE_CIF_W; + vsize->height=MS_VIDEO_SIZE_CIF_H; + } + }else if (strcasecmp(tmp,"QCIF")==0){ + vsize->width=MS_VIDEO_SIZE_QCIF_W; + vsize->height=MS_VIDEO_SIZE_QCIF_H; + }else{ + ms_warning("unsupported video size %s",tmp); + ret=FALSE; + } + divider=atoi(equal+1); + if (divider!=0){ + float newfps=29.97/divider; + if (*fps>newfps) *fps=newfps; + }else{ + ms_warning("Could not find video fps"); + ret=FALSE; + } + }else ret=FALSE; + ms_free(tmp); + return ret; +} + +static int enc_add_fmtp(MSFilter *f,void *arg){ + EncState *s=(EncState*)f->data; + const char *fmtp=(const char*)arg; + char val[10]; + if (fmtp_get_value(fmtp,"profile",val,sizeof(val))){ + s->profile=atoi(val); + }else parse_video_fmtp(fmtp,&s->fps,&s->vsize); + return 0; +} + +static int enc_req_vfu(MSFilter *f, void *unused){ + EncState *s=(EncState*)f->data; + s->req_vfu=TRUE; + return 0; +} + +static void enc_init(MSFilter *f, enum CodecID codec) +{ + EncState *s=(EncState *)ms_new(EncState,1); + f->data=s; + ms_ffmpeg_check_init(); + s->profile=0;/*always default to profile 0*/ + s->comp_buf=allocb(32000,0); + s->fps=15; + s->mtu=ms_get_payload_max_size()-2;/*-2 for the H263 payload header*/ + s->maxbr=500000; + s->codec=codec; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->qmin=2; + s->req_vfu=FALSE; + s->av_context.codec=NULL; +} + +static void enc_h263_init(MSFilter *f){ + enc_init(f,CODEC_ID_H263P); +} + +static void enc_mpeg4_init(MSFilter *f){ + enc_init(f,CODEC_ID_MPEG4); +} + +static void enc_snow_init(MSFilter *f){ + enc_init(f,CODEC_ID_SNOW); +} + +static void prepare(EncState *s){ + AVCodecContext *c=&s->av_context; + avcodec_get_context_defaults(c); + /* put codec parameters */ + c->bit_rate=(float)s->maxbr*0.7; + c->bit_rate_tolerance=(float)c->bit_rate/(s->fps-1); + + if (s->codec!=CODEC_ID_SNOW && s->maxbr<256000){ + /*snow does not like 1st pass rate control*/ + /*and rate control eats too much cpu with CIF high fps pictures*/ + c->rc_max_rate=(float)s->maxbr*0.8; + c->rc_min_rate=c->bit_rate; + c->rc_buffer_size=c->rc_max_rate; + }else{ + /*use qmin instead*/ + c->qmin=s->qmin; + } + + ms_message("Codec bitrate set to %i",c->bit_rate); + c->width = s->vsize.width; + c->height = s->vsize.height; + c->time_base.num = 1; + c->time_base.den = (int)s->fps; + c->gop_size=(int)s->fps*5; /*emit I frame every 5 seconds*/ + c->pix_fmt=PIX_FMT_YUV420P; + + if (s->codec==CODEC_ID_SNOW){ + c->strict_std_compliance=-2; + } + +} + +static void prepare_h263(EncState *s){ + AVCodecContext *c=&s->av_context; + /* we don't use the rtp_callback but use rtp_mode that forces ffmpeg to insert + Start Codes as much as possible in the bitstream */ + c->rtp_mode = 1; + c->rtp_payload_size = s->mtu/2; + if (s->profile==0){ + s->codec=CODEC_ID_H263; + }else{ + c->flags|=CODEC_FLAG_H263P_UMV; + c->flags|=CODEC_FLAG_AC_PRED; + c->flags|=CODEC_FLAG_H263P_SLICE_STRUCT; + /* + c->flags|=CODEC_FLAG_OBMC; + c->flags|=CODEC_FLAG_AC_PRED; + */ + s->codec=CODEC_ID_H263P; + } +} + +static void prepare_mpeg4(EncState *s){ + AVCodecContext *c=&s->av_context; + c->max_b_frames=0; /*don't use b frames*/ + c->flags|=CODEC_FLAG_AC_PRED; + c->flags|=CODEC_FLAG_H263P_UMV; + /*c->flags|=CODEC_FLAG_QPEL;*/ /*don't enable this one: this forces profile_level to advanced simple profile */ + c->flags|=CODEC_FLAG_4MV; + c->flags|=CODEC_FLAG_GMC; + c->flags|=CODEC_FLAG_LOOP_FILTER; + c->flags|=CODEC_FLAG_H263P_SLICE_STRUCT; +} + +static void enc_uninit(MSFilter *f){ + EncState *s=(EncState*)f->data; + if (s->comp_buf!=NULL) freemsg(s->comp_buf); + ms_free(s); +} +#if 0 +static void enc_set_rc(EncState *s, AVCodecContext *c){ + int factor=c->width/MS_VIDEO_SIZE_QCIF_W; + c->rc_min_rate=0; + c->bit_rate=400; /* this value makes around 100kbit/s at QCIF=2 */ + c->rc_max_rate=c->bit_rate+1; + c->rc_buffer_size=20000*factor; /* food recipe */ +} +#endif + +static void enc_preprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + int error; + prepare(s); + if (s->codec==CODEC_ID_H263P || s->codec==CODEC_ID_H263) + prepare_h263(s); + else if (s->codec==CODEC_ID_MPEG4) + prepare_mpeg4(s); + else if (s->codec==CODEC_ID_SNOW){ + /**/ + }else { + ms_error("Unsupported codec id %i",s->codec); + return; + } + s->av_codec=avcodec_find_encoder(s->codec); + if (s->av_codec==NULL){ + ms_error("could not find encoder for codec id %i",s->codec); + return; + } + error=avcodec_open(&s->av_context, s->av_codec); + if (error!=0) { + ms_error("avcodec_open() failed: %i",error); + return; + } + ms_debug("image format is %i.",s->av_context.pix_fmt); + ms_message("qmin=%i qmax=%i",s->av_context.qmin,s->av_context.qmax); +} + +static void enc_postprocess(MSFilter *f){ + EncState *s=(EncState*)f->data; + if (s->av_context.codec!=NULL){ + avcodec_close(&s->av_context); + s->av_context.codec=NULL; + } +} + +static void add_rfc2190_header(mblk_t **packet, AVCodecContext *context){ + mblk_t *header; + header = allocb(4, 0); + memset(header->b_wptr, 0, 4); + // assume video size is CIF or QCIF + if (context->width == 352 && context->height == 288) header->b_wptr[1] = 0x60; + else header->b_wptr[1] = 0x40; + if (context->coded_frame->pict_type != FF_I_TYPE) header->b_wptr[1] |= 0x10; + header->b_wptr += 4; + header->b_cont = *packet; + *packet = header; +} + +static int get_gbsc(uint8_t *psc, uint8_t *end) +{ + int len = end-psc; + uint32_t buf; + int i, j, k; + k = len; + for (i = 2; i < len-4; i++) { + buf = *((uint32_t *)(psc+i)); + for (j = 0; j < 8; j++) { + if (((buf >> j) & 0x00FCFFFF) == 0x00800000) {/*PSC*/ + i += 2; + k=i; + break; + } else if (((buf >> j) & 0x0080FFFF) == 0x00800000) {/*GBSC*/ + i += 2; + k = i; + break; + } + } + } + return k; +} + +static void rfc2190_generate_packets(MSFilter *f, EncState *s, mblk_t *frame, uint32_t timestamp){ + mblk_t *packet=NULL; + + while (frame->b_rptrb_wptr){ + packet=dupb(frame); + frame->b_rptr=packet->b_wptr=packet->b_rptr+get_gbsc(packet->b_rptr, MIN(packet->b_rptr+s->mtu,frame->b_wptr)); + add_rfc2190_header(&packet, &s->av_context); + mblk_set_timestamp_info(packet,timestamp); + ms_queue_put(f->outputs[0],packet); + } + /* the marker bit is set on the last packet, if any.*/ + mblk_set_marker_info(packet,TRUE); +} + +static void mpeg4_fragment_and_send(MSFilter *f,EncState *s,mblk_t *frame, uint32_t timestamp){ + uint8_t *rptr; + mblk_t *packet=NULL; + int len; + for (rptr=frame->b_rptr;rptrb_wptr;){ + len=MIN(s->mtu,(frame->b_wptr-rptr)); + packet=dupb(frame); + packet->b_rptr=rptr; + packet->b_wptr=rptr+len; + mblk_set_timestamp_info(packet,timestamp); + ms_queue_put(f->outputs[0],packet); + rptr+=len; + } + /*set marker bit on last packet*/ + mblk_set_marker_info(packet,TRUE); +} + +static void rfc4629_generate_follow_on_packets(MSFilter *f, EncState *s, mblk_t *frame, uint32_t timestamp, uint8_t *psc, uint8_t *end, bool_t last_packet){ + mblk_t *packet; + int len=end-psc; + + packet=dupb(frame); + packet->b_rptr=psc; + packet->b_wptr=end; + /*ms_message("generating packet of size %i",end-psc);*/ + rfc2429_set_P(psc,1); + mblk_set_timestamp_info(packet,timestamp); + + + if (len>s->mtu){ + /*need to slit the packet using "follow-on" packets */ + /*compute the number of packets need (rounded up)*/ + int num=(len+s->mtu-1)/s->mtu; + int i; + uint8_t *pos; + /*adjust the first packet generated*/ + pos=packet->b_wptr=packet->b_rptr+s->mtu; + ms_queue_put(f->outputs[0],packet); + ms_debug("generating %i follow-on packets",num); + for (i=1;ib_rptr=pos; + pos=packet->b_wptr=MIN(pos+s->mtu,end); + header=allocb(2,0); + header->b_wptr[0]=0; + header->b_wptr[1]=0; + header->b_wptr+=2; + /*no P bit is set */ + header->b_cont=packet; + packet=header; + mblk_set_timestamp_info(packet,timestamp); + ms_queue_put(f->outputs[0],packet); + } + }else ms_queue_put(f->outputs[0],packet); + /* the marker bit is set on the last packet, if any.*/ + mblk_set_marker_info(packet,last_packet); +} + +/* returns the last psc position just below packet_size */ +static uint8_t *get_psc(uint8_t *begin,uint8_t *end, int packet_size){ + int i; + uint8_t *ret=NULL; + uint8_t *p; + if (begin==end) return NULL; + for(i=1,p=begin+1;pticker->time*90LL; + + if (s->codec==CODEC_ID_MPEG4 || s->codec==CODEC_ID_SNOW) + { + mpeg4_fragment_and_send(f,s,frame,timestamp); + return; + } + + ms_debug("processing frame of size %i",frame->b_wptr-frame->b_rptr); + if (f->desc->id==MS_H263_ENC_ID){ + lastpsc=frame->b_rptr; + while(1){ + psc=get_psc(lastpsc+2,frame->b_wptr,s->mtu); + if (psc!=NULL){ + rfc4629_generate_follow_on_packets(f,s,frame,timestamp,lastpsc,psc,FALSE); + lastpsc=psc; + }else break; + } + /* send the end of frame */ + rfc4629_generate_follow_on_packets(f,s,frame, timestamp,lastpsc,frame->b_wptr,TRUE); + }else if (f->desc->id==MS_H263_OLD_ENC_ID){ + rfc2190_generate_packets(f,s,frame,timestamp); + }else{ + ms_fatal("Ca va tres mal."); + } +} + +static void process_frame(MSFilter *f, mblk_t *inm){ + EncState *s=(EncState*)f->data; + AVFrame pict; + AVCodecContext *c=&s->av_context; + int error; + mblk_t *comp_buf=s->comp_buf; + int comp_buf_sz=comp_buf->b_datap->db_lim-comp_buf->b_datap->db_base; + + /* convert image if necessary */ + avcodec_get_frame_defaults(&pict); + avpicture_fill((AVPicture*)&pict,(uint8_t*)inm->b_rptr,c->pix_fmt,c->width,c->height); + + /* timestamp used by ffmpeg, unset here */ + pict.pts=AV_NOPTS_VALUE; + if (s->req_vfu){ + pict.pict_type=FF_I_TYPE; + s->req_vfu=FALSE; + } + comp_buf->b_rptr=comp_buf->b_wptr=comp_buf->b_datap->db_base; + if (s->codec==CODEC_ID_SNOW){ + //prepend picture size + uint32_t header=((s->vsize.width&0xffff)<<16) | (s->vsize.height&0xffff); + *(uint32_t*)comp_buf->b_wptr=htonl(header); + comp_buf->b_wptr+=4; + comp_buf_sz-=4; + } + error=avcodec_encode_video(c, (uint8_t*)comp_buf->b_wptr,comp_buf_sz, &pict); + if (error<=0) ms_warning("ms_AVencoder_process: error %i.",error); + else{ + if (c->coded_frame->pict_type==FF_I_TYPE){ + ms_message("Emitting I-frame"); + } + comp_buf->b_wptr+=error; + split_and_send(f,s,comp_buf); + } + freemsg(inm); +} + +static void enc_process(MSFilter *f){ + mblk_t *inm; + EncState *s=(EncState*)f->data; + if (s->av_context.codec==NULL) { + ms_queue_flush(f->inputs[0]); + return; + } + ms_filter_lock(f); + while((inm=ms_queue_get(f->inputs[0]))!=0){ + process_frame(f,inm); + } + ms_filter_unlock(f); +} + + +static int enc_get_br(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + *(int*)arg=s->maxbr; + return 0; +} + +static int enc_set_br(MSFilter *f, void *arg){ + EncState *s=(EncState*)f->data; + bool_t snow=s->codec==CODEC_ID_SNOW; + s->maxbr=*(int*)arg; + if (s->maxbr>=512000){ + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->fps=17; + }else if (s->maxbr>=256000){ + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->fps=10; + s->qmin=3; + }else if (s->maxbr>=128000){ + s->vsize.width=MS_VIDEO_SIZE_QCIF_W; + s->vsize.height=MS_VIDEO_SIZE_QCIF_H; + s->fps=10; + s->qmin=3; + }else if (s->maxbr>=64000){ + s->vsize.width=MS_VIDEO_SIZE_QCIF_W; + s->vsize.height=MS_VIDEO_SIZE_QCIF_H; + s->fps=snow ? 7 : 5; + s->qmin=snow ? 4 : 5; + }else{ + s->vsize.width=MS_VIDEO_SIZE_QCIF_W; + s->vsize.height=MS_VIDEO_SIZE_QCIF_H; + s->fps=5; + s->qmin=5; + } + if (s->av_context.codec!=NULL){ + /*apply new settings dynamically*/ + ms_filter_lock(f); + enc_postprocess(f); + enc_preprocess(f); + ms_filter_lock(f); + } + return 0; +} + + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , enc_set_fps }, + { MS_FILTER_GET_FPS , enc_get_fps }, + { MS_FILTER_SET_VIDEO_SIZE , enc_set_vsize }, + { MS_FILTER_GET_VIDEO_SIZE , enc_get_vsize }, + { MS_FILTER_ADD_FMTP , enc_add_fmtp }, + { MS_FILTER_SET_BITRATE , enc_set_br }, + { MS_FILTER_GET_BITRATE , enc_get_br }, + { MS_FILTER_SET_MTU , enc_set_mtu }, + { MS_FILTER_REQ_VFU , enc_req_vfu }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_h263_enc_desc={ + MS_H263_ENC_ID, + "MSH263Enc", + "A video H.263 encoder using ffmpeg library.", + MS_FILTER_ENCODER, + "H263-1998", + 1, /*MS_YUV420P is assumed on this input */ + 1, + enc_h263_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + methods +}; + +MSFilterDesc ms_h263_old_enc_desc={ + MS_H263_OLD_ENC_ID, + "MSH263OldEnc", + "A video H.263 encoder using ffmpeg library. It is compliant with old RFC2190 spec.", + MS_FILTER_ENCODER, + "H263", + 1, /*MS_YUV420P is assumed on this input */ + 1, + enc_h263_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + methods +}; + +MSFilterDesc ms_mpeg4_enc_desc={ + MS_MPEG4_ENC_ID, + "MSMpeg4Enc", + "A video MPEG4 encoder using ffmpeg library.", + MS_FILTER_ENCODER, + "MP4V-ES", + 1, /*MS_YUV420P is assumed on this input */ + 1, + enc_mpeg4_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + methods +}; + +MSFilterDesc ms_snow_enc_desc={ + MS_SNOW_ENC_ID, + "MSSnowEnc", + "A video snow encoder using ffmpeg library.", + MS_FILTER_ENCODER, + "x-snow", + 1, /*MS_YUV420P is assumed on this input */ + 1, + enc_snow_init, + enc_preprocess, + enc_process, + enc_postprocess, + enc_uninit, + methods +}; + +#else + +MSFilterDesc ms_h263_enc_desc={ + .id=MS_H263_ENC_ID, + .name="MSH263Enc", + .text="A video H.263 encoder using ffmpeg library.", + .category=MS_FILTER_ENCODER, + .enc_fmt="H263-1998", + .ninputs=1, /*MS_YUV420P is assumed on this input */ + .noutputs=1, + .init=enc_h263_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=methods +}; + +MSFilterDesc ms_h263_old_enc_desc={ + .id=MS_H263_OLD_ENC_ID, + .name="MSH263Enc", + .text="A video H.263 encoder using ffmpeg library, compliant with old RFC2190 spec.", + .category=MS_FILTER_ENCODER, + .enc_fmt="H263", + .ninputs=1, /*MS_YUV420P is assumed on this input */ + .noutputs=1, + .init=enc_h263_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=methods +}; + +MSFilterDesc ms_mpeg4_enc_desc={ + .id=MS_MPEG4_ENC_ID, + .name="MSMpeg4Enc", + .text="A video MPEG4 encoder using ffmpeg library.", + .category=MS_FILTER_ENCODER, + .enc_fmt="MP4V-ES", + .ninputs=1, /*MS_YUV420P is assumed on this input */ + .noutputs=1, + .init=enc_mpeg4_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=methods +}; + +MSFilterDesc ms_snow_enc_desc={ + .id=MS_SNOW_ENC_ID, + .name="MSSnowEnc", + .text="The snow codec is royalty-free and is open-source. \n" + "It uses innovative techniques that makes it one of the best video " + "codec. It is implemented within the ffmpeg project.\n" + "However it is under development and compatibility with other versions " + "cannot be guaranteed.", + .category=MS_FILTER_ENCODER, + .enc_fmt="x-snow", + .ninputs=1, /*MS_YUV420P is assumed on this input */ + .noutputs=1, + .init=enc_snow_init, + .preprocess=enc_preprocess, + .process=enc_process, + .postprocess=enc_postprocess, + .uninit=enc_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_mpeg4_enc_desc) +MS_FILTER_DESC_EXPORT(ms_h263_enc_desc) +MS_FILTER_DESC_EXPORT(ms_h263_old_enc_desc) +MS_FILTER_DESC_EXPORT(ms_snow_enc_desc) + diff --git a/linphone/mediastreamer2/src/videoout.c b/linphone/mediastreamer2/src/videoout.c new file mode 100644 index 000000000..bee29a67a --- /dev/null +++ b/linphone/mediastreamer2/src/videoout.c @@ -0,0 +1,884 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msvideoout.h" + +#include "ffmpeg-priv.h" + +static int video_out_handle_resize(MSFilter *f, void *arg); + +bool_t ms_display_poll_event(MSDisplay *d, MSDisplayEvent *ev){ + if (d->desc->pollevent) + return d->desc->pollevent(d,ev); + else return FALSE; +} + +#ifndef WIN32 + +#include +#include + +static bool_t sdl_initialized=FALSE; + +static ms_mutex_t sdl_mutex; + +static SDL_Surface *sdl_screen=0; + +#ifdef HAVE_X11_XLIB_H + +#include + +static void sdl_show_window(bool_t show){ + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if ( SDL_GetWMInfo(&info) ) { + if ( info.subsystem == SDL_SYSWM_X11 ) { + Display *display; + Window window; + + info.info.x11.lock_func(); + display = info.info.x11.display; + window = info.info.x11.wmwindow; + if (show) + XMapWindow(display,window); + else + XUnmapWindow(display,window); + info.info.x11.unlock_func(); + } + } +} + +#else + +static void sdl_show_window(bool_t show){ + ms_warning("SDL window show/hide not implemented"); +} + +#endif + +static SDL_Overlay * sdl_create_window(int w, int h){ + SDL_Overlay *lay; + sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_SWSURFACE|SDL_RESIZABLE); + if (sdl_screen == NULL ) { + ms_warning("Couldn't set video mode: %s\n", + SDL_GetError()); + return NULL; + } + if (sdl_screen->flags & SDL_HWSURFACE) ms_message("SDL surface created in hardware"); + SDL_WM_SetCaption("Linphone Video", NULL); + ms_message("Using yuv overlay."); + lay=SDL_CreateYUVOverlay(w,h,SDL_YV12_OVERLAY,sdl_screen); + if (lay==NULL){ + ms_warning("Couldn't create yuv overlay: %s\n", + SDL_GetError()); + return NULL; + }else{ + if (lay->hw_overlay) ms_message("YUV overlay using hardware acceleration."); + } + return lay; +} + +static bool_t sdl_display_init(MSDisplay *obj, MSPicture *fbuf){ + SDL_Overlay *lay; + if (!sdl_initialized){ + /* Initialize the SDL library */ + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + ms_error("Couldn't initialize SDL: %s", SDL_GetError()); + return FALSE; + } + /* Clean up on exit */ + atexit(SDL_Quit); + sdl_initialized=TRUE; + ms_mutex_init(&sdl_mutex,NULL); + } + if (obj->data!=NULL) + SDL_FreeYUVOverlay((SDL_Overlay*)obj->data); + + lay=sdl_create_window(fbuf->w, fbuf->h); + if (lay){ + fbuf->planes[0]=lay->pixels[0]; + fbuf->planes[1]=lay->pixels[2]; + fbuf->planes[2]=lay->pixels[1]; + fbuf->strides[0]=lay->pitches[0]; + fbuf->strides[1]=lay->pitches[2]; + fbuf->strides[2]=lay->pitches[1]; + obj->data=lay; + sdl_show_window(TRUE); + return TRUE; + } + return FALSE; +} + +static void sdl_display_lock(MSDisplay *obj){ + ms_mutex_lock(&sdl_mutex); + SDL_LockYUVOverlay((SDL_Overlay*)obj->data); + ms_mutex_unlock(&sdl_mutex); +} + +static void sdl_display_unlock(MSDisplay *obj){ + SDL_Overlay *lay=(SDL_Overlay*)obj->data; + ms_mutex_lock(&sdl_mutex); + SDL_UnlockYUVOverlay(lay); + ms_mutex_unlock(&sdl_mutex); +} + +static void sdl_display_update(MSDisplay *obj){ + SDL_Rect rect; + SDL_Overlay *lay=(SDL_Overlay*)obj->data; + rect.x=0; + rect.y=0; + rect.w=lay->w; + rect.h=lay->h; + ms_mutex_lock(&sdl_mutex); + SDL_DisplayYUVOverlay(lay,&rect); + ms_mutex_unlock(&sdl_mutex); +} + +static bool_t sdl_poll_event(MSDisplay *obj, MSDisplayEvent *ev){ + SDL_Event event; + static MSDisplayEvent last_ev; + static struct timeval tv; + static bool_t got_rs_ev=FALSE; + struct timeval cur; + int elapsed; + bool_t ret=FALSE; + ms_mutex_lock(&sdl_mutex); + if (SDL_PollEvent(&event)){ + ms_mutex_unlock(&sdl_mutex); + switch(event.type){ + case SDL_VIDEORESIZE: + last_ev.evtype=MS_DISPLAY_RESIZE_EVENT; + last_ev.w=event.resize.w; + last_ev.h=event.resize.h; + got_rs_ev=TRUE; + gettimeofday(&tv,NULL); + break; + default: + break; + } + }else ms_mutex_unlock(&sdl_mutex); + if (got_rs_ev){ + gettimeofday(&cur,NULL); + elapsed=((cur.tv_sec-tv.tv_sec)*1000) + ((cur.tv_usec-tv.tv_usec)/1000); + if (elapsed>1000){ + got_rs_ev=FALSE; + *ev=last_ev; + ret=TRUE; + } + } + return ret; +} + +static void sdl_display_uninit(MSDisplay *obj){ + SDL_Overlay *lay=(SDL_Overlay*)obj->data; + if (lay==NULL) + return; + if (lay!=NULL) + SDL_FreeYUVOverlay(lay); + if (sdl_screen!=NULL){ + SDL_FreeSurface(sdl_screen); + sdl_screen=NULL; + } + sdl_show_window(FALSE); +} + +MSDisplayDesc ms_sdl_display_desc={ + .init=sdl_display_init, + .lock=sdl_display_lock, + .unlock=sdl_display_unlock, + .update=sdl_display_update, + .uninit=sdl_display_uninit, + .pollevent=sdl_poll_event +}; + +#else + +#include + + +typedef struct _WinDisplay{ + HWND window; + HDRAWDIB ddh; + MSPicture fb; + MSDisplayEvent last_rsz; + uint8_t *rgb; + int rgb_len; + bool_t new_ev; +}WinDisplay; + +static LRESULT CALLBACK window_proc( + HWND hwnd, // handle to window + UINT uMsg, // message identifier + WPARAM wParam, // first message parameter + LPARAM lParam) // second message parameter +{ + switch(uMsg){ + case WM_DESTROY: + break; + case WM_SIZE: + if (wParam==SIZE_RESTORED){ + int h=(lParam>>16) & 0xffff; + int w=lParam & 0xffff; + MSDisplay *obj; + WinDisplay *wd; + ms_message("Resized to %i,%i",w,h); + obj=(MSDisplay*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + if (obj!=NULL){ + wd=(WinDisplay*)obj->data; + wd->last_rsz.evtype=MS_DISPLAY_RESIZE_EVENT; + wd->last_rsz.w=w; + wd->last_rsz.h=h; + wd->new_ev=TRUE; + }else{ + ms_error("Could not retrieve MSDisplay from window !"); + } + } + break; + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; +} + +static HWND create_window(int w, int h) +{ + WNDCLASS wc; + HINSTANCE hInstance = GetModuleHandle(NULL); + HWND hwnd; + RECT rect; + wc.style = 0 ; + wc.lpfnWndProc = window_proc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = NULL; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(hInstance, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "Video Window"; + + if(!RegisterClass(&wc)) + { + /* already registred! */ + } + rect.left=100; + rect.top=100; + rect.right=rect.left+w; + rect.bottom=rect.top+h; + if (!AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW|WS_VISIBLE /*WS_CAPTION WS_TILED|WS_BORDER*/,FALSE)){ + ms_error("AdjustWindowRect failed."); + } + ms_message("AdjustWindowRect: %li,%li %li,%li",rect.left,rect.top,rect.right,rect.bottom); + hwnd=CreateWindow("Video Window", "Video window", WS_OVERLAPPEDWINDOW|WS_VISIBLE , + CW_USEDEFAULT, CW_USEDEFAULT, rect.right-rect.left,rect.bottom-rect.top, + NULL, NULL, hInstance, NULL); + if (hwnd==NULL){ + ms_error("Fail to create video window"); + } + return hwnd; +} + +static bool_t win_display_init(MSDisplay *obj, MSPicture *fbuf){ + WinDisplay *wd=(WinDisplay*)obj->data; + int ysize,usize; + + if (wd!=NULL) + { + if (wd->ddh) DrawDibClose(wd->ddh); + wd->ddh=NULL; + if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]); + wd->fb.planes[0]=NULL; + wd->fb.planes[1]=NULL; + wd->fb.planes[2]=NULL; + if (wd->rgb) ms_free(wd->rgb); + wd->rgb=NULL; + wd->rgb_len=0; + } + else + wd=(WinDisplay*)ms_new0(WinDisplay,1); + + obj->data=wd; + + wd->fb.w=fbuf->w; + wd->fb.h=fbuf->h; + + if (wd->window==NULL){ + if (obj->window_id!=0){ + void *p; + wd->window=(HWND)obj->window_id; + p=(void*)GetWindowLongPtr(wd->window,GWLP_USERDATA); + if (p!=NULL){ + ms_error("Gulp: this externally supplied windows seems to " + "already have a userdata ! resizing will crash !"); + }else SetWindowLongPtr(wd->window,GWLP_USERDATA,(LONG_PTR)obj); + }else{ + wd->window=create_window(wd->fb.w,wd->fb.h); + if (wd->window!=NULL) SetWindowLongPtr(wd->window,GWLP_USERDATA,(LONG_PTR)obj); + else return FALSE; + } + } + + if (wd->ddh==NULL) wd->ddh=DrawDibOpen(); + if (wd->ddh==NULL){ + ms_error("DrawDibOpen() failed."); + return FALSE; + } + /*allocate yuv and rgb buffers*/ + if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]); + if (wd->rgb) ms_free(wd->rgb); + ysize=wd->fb.w*wd->fb.h; + usize=ysize/4; + fbuf->planes[0]=wd->fb.planes[0]=(uint8_t*)ms_malloc0(ysize+2*usize); + fbuf->planes[1]=wd->fb.planes[1]=wd->fb.planes[0]+ysize; + fbuf->planes[2]=wd->fb.planes[2]=wd->fb.planes[1]+usize; + fbuf->strides[0]=wd->fb.strides[0]=wd->fb.w; + fbuf->strides[1]=wd->fb.strides[1]=wd->fb.w/2; + fbuf->strides[2]=wd->fb.strides[2]=wd->fb.w/2; + + wd->rgb_len=ysize*3; + wd->rgb=(uint8_t*)ms_malloc0(wd->rgb_len); + return TRUE; +} + +typedef struct rgb{ + uint8_t r,g,b; +} rgb_t; + +typedef struct yuv{ + uint8_t y,u,v; +} yuv_t; + + + +static void yuv420p_to_rgb(MSPicture *src, uint8_t *rgb){ + struct SwsContext *sws; + int rgb_stride=-src->w*3; + uint8_t *p; + + p=rgb+(src->w*3*(src->h-1)); + sws=sws_getContext(src->w,src->h,PIX_FMT_YUV420P, + src->w,src->h,PIX_FMT_RGB24, + 0, NULL, NULL, NULL); + if (sws_scale(sws,src->planes,src->strides, 0, + 0, &p, &rgb_stride)<0){ + ms_error("Error in 420->rgb sws_scale()."); + } + sws_freeContext(sws); + + /*revert colors*/ + { + int i,j,stride; + rgb_t pix; + stride=src->w*3; + p=rgb; + for(i=0;ih;++i){ + for(j=0;jdata; + HDC hdc; + BITMAPINFOHEADER bi; + RECT rect; + bool_t ret; + if (wd->window==NULL) return; + hdc=GetDC(wd->window); + if (hdc==NULL) { + ms_error("Could not get window dc"); + return; + } + yuv420p_to_rgb(&wd->fb, wd->rgb); + memset(&bi,0,sizeof(bi)); + bi.biSize=sizeof(bi); + GetClientRect(wd->window,&rect); + /* + bi.biWidth=wd->fb.w; + bi.biHeight=wd->fb.h; + bi.biPlanes=3; + bi.biBitCount=12; + bi.biCompression=MAKEFOURCC('I','4','2','0'); + bi.biSizeImage=(wd->fb.w*wd->fb.h*3)/2; + */ + bi.biWidth=wd->fb.w; + bi.biHeight=wd->fb.h; + bi.biPlanes=1; + bi.biBitCount=24; + bi.biCompression=BI_RGB; + bi.biSizeImage=wd->rgb_len; + + //if (bi.biHeight>rect.bottom) + // bi.biHeight=rect.bottom; + //bi.biSizeImage=(bi.biWidth*bi.biHeight)*3; + + ret=DrawDibDraw(wd->ddh,hdc,0,0, + //bi.biWidth,bi.biHeight, + rect.right,rect.bottom, + &bi,wd->rgb, + //0,0,rect.right,rect.bottom,0); + 0,0,bi.biWidth,bi.biHeight,0); + + if (!ret) ms_error("DrawDibDraw failed."); + ReleaseDC(NULL,hdc); +} + +static void win_display_uninit(MSDisplay *obj){ + WinDisplay *wd=(WinDisplay*)obj->data; + if (wd==NULL) + return; + if (wd->window && !obj->window_id) DestroyWindow(wd->window); + if (wd->ddh) DrawDibClose(wd->ddh); + if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]); + if (wd->rgb) ms_free(wd->rgb); + ms_free(wd); +} + +bool_t win_display_pollevent(MSDisplay *d, MSDisplayEvent *ev){ + WinDisplay *wd=(WinDisplay*)d->data; + if (wd->new_ev){ + wd->new_ev=FALSE; + *ev=wd->last_rsz; + return TRUE; + } + return FALSE; +} + +#ifdef _MSC_VER + +extern MSDisplayDesc ms_win_display_desc={ + win_display_init, + NULL, + NULL, + win_display_update, + win_display_uninit, + win_display_pollevent +}; + +#else + +MSDisplayDesc ms_win_display_desc={ + .init=win_display_init, + .update=win_display_update, + .uninit=win_display_uninit, + .pollevent=win_display_pollevent +}; + +#endif + +#endif + +MSDisplay *ms_display_new(MSDisplayDesc *desc){ + MSDisplay *obj=(MSDisplay *)ms_new0(MSDisplay,1); + obj->desc=desc; + obj->data=NULL; + return obj; +} + +void ms_display_set_window_id(MSDisplay *d, long id){ + d->window_id=id; +} + +void ms_display_destroy(MSDisplay *obj){ + obj->desc->uninit(obj); + ms_free(obj); +} + +typedef struct VideoOut +{ + AVRational ratio; + MSPicture fbuf; + MSPicture local_pic; + MSRect local_rect; + mblk_t *local_msg; + MSPicture tmp_local_pic; + mblk_t *tmp_local_msg; + int corner; + struct SwsContext *sws1; + struct SwsContext *sws2; + MSDisplay *display; + bool_t own_display; + bool_t ready; +} VideoOut; + + +#define SCALE_FACTOR 6 + +static void set_corner(VideoOut *s, int corner) +{ + s->corner=corner; + s->local_pic.w=s->fbuf.w/SCALE_FACTOR; + s->local_pic.h=s->fbuf.h/SCALE_FACTOR; + s->tmp_local_pic.h = s->local_pic.h; + s->tmp_local_pic.w = s->local_pic.w; + if (corner==1) + { + /* top left corner */ + s->local_rect.x=0; + s->local_rect.y=0; + s->local_rect.w=s->local_pic.w; + s->local_rect.h=s->local_pic.h; + } + else if (corner==2) + { + /* top right corner */ + s->local_rect.x=s->fbuf.w-s->local_pic.w; + s->local_rect.y=0; + s->local_rect.w=s->local_pic.w; + s->local_rect.h=s->local_pic.h; + } + else if (corner==3) + { + /* bottom left corner */ + s->local_rect.x=0; + s->local_rect.y=s->fbuf.h-s->local_pic.h; + s->local_rect.w=s->local_pic.w; + s->local_rect.h=s->local_pic.h; + } + else + { + /* default: bottom right corner */ + /* corner can be set to -1: to disable the self view... */ + s->local_rect.x=s->fbuf.w-s->local_pic.w; + s->local_rect.y=s->fbuf.h-s->local_pic.h; + s->local_rect.w=s->local_pic.w; + s->local_rect.h=s->local_pic.h; + } +} + +static void set_vsize(VideoOut *s, MSVideoSize *sz){ + if (s->ratio.num!=0){ + sz->width=sz->width & (~0x1); + sz->height=sz->width*s->ratio.den/s->ratio.num; + } + s->fbuf.w=sz->width; + s->fbuf.h=sz->height; + set_corner(s, s->corner); +} + +static void video_out_init(MSFilter *f){ + VideoOut *obj=(VideoOut*)ms_new(VideoOut,1); + MSVideoSize def_size; + obj->ratio.num=11; + obj->ratio.den=9; + def_size.width=MS_VIDEO_SIZE_CIF_W; + def_size.height=MS_VIDEO_SIZE_CIF_H; + obj->local_msg=NULL; + obj->tmp_local_msg=NULL; + obj->corner=0; + obj->sws1=NULL; + obj->sws2=NULL; + obj->display=NULL; + obj->own_display=FALSE; + obj->ready=FALSE; + set_vsize(obj,&def_size); + f->data=obj; +} + + +static void video_out_uninit(MSFilter *f){ + VideoOut *obj=(VideoOut*)f->data; + if (obj->display!=NULL && obj->own_display) + ms_display_destroy(obj->display); + if (obj->sws1!=NULL){ + sws_freeContext(obj->sws1); + obj->sws1=NULL; + } + if (obj->sws2!=NULL){ + sws_freeContext(obj->sws2); + obj->sws2=NULL; + } + ms_free(obj); +} + + +static void video_out_preprocess(MSFilter *f){ + VideoOut *obj=(VideoOut*)f->data; + if (obj->display==NULL){ +#ifndef WIN32 + obj->display=ms_display_new(&ms_sdl_display_desc); +#else + obj->display=ms_display_new(&ms_win_display_desc); +#endif + obj->own_display=TRUE; + } + if (!ms_display_init(obj->display,&obj->fbuf)){ + if (obj->own_display) ms_display_destroy(obj->display); + obj->display=NULL; + } + if (obj->sws1!=NULL){ + sws_freeContext(obj->sws1); + obj->sws1=NULL; + } + if (obj->sws2!=NULL){ + sws_freeContext(obj->sws2); + obj->sws2=NULL; + } + if (obj->local_msg!=NULL) { + freemsg(obj->local_msg); + obj->local_msg=NULL; + } + if (obj->tmp_local_msg!=NULL) { + freemsg(obj->tmp_local_msg); + obj->tmp_local_msg=NULL; + } + obj->ready=TRUE; +} + +static void video_out_postprocess(MSFilter *f){ +} + +static void mirror(unsigned char* dst,unsigned char* src,int dststride,int srcstride,int w,int h){ + int y; + for(y=0;ydata; + mblk_t *inm; + +#ifdef WIN32 + video_out_handle_resize(f, NULL); +#endif + + ms_filter_lock(f); + if (obj->display==NULL){ + ms_filter_unlock(f); + if (f->inputs[0]!=NULL) + ms_queue_flush(f->inputs[0]); + if (f->inputs[1]!=NULL) + ms_queue_flush(f->inputs[1]); + return; + } + /*get most recent message and draw it*/ + if (f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) { + + if (obj->corner==-1) + { + if (obj->tmp_local_msg!=NULL) { + freemsg(obj->tmp_local_msg); + obj->tmp_local_msg=NULL; + } + if (obj->local_msg!=NULL) { + freemsg(obj->local_msg); + obj->local_msg=NULL; + } + } + else + { + MSPicture src; + if (yuv_buf_init_from_mblk(&src,inm)==0){ + + if (obj->sws2==NULL){ + obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P, + obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + } + obj->tmp_local_pic.h = obj->local_pic.h; + obj->tmp_local_pic.w = obj->local_pic.w; + if (obj->tmp_local_msg==NULL){ + obj->tmp_local_msg=yuv_buf_alloc(&obj->tmp_local_pic, + obj->tmp_local_pic.w,obj->tmp_local_pic.h); + } + if (obj->local_msg==NULL){ + obj->local_msg=yuv_buf_alloc(&obj->local_pic, + obj->local_pic.w,obj->local_pic.h); + } + if (sws_scale(obj->sws2,src.planes,src.strides, 0, + src.h, obj->tmp_local_pic.planes, obj->tmp_local_pic.strides)<0){ + ms_error("Error in sws_scale()."); + } + + mirror(obj->local_pic.planes[0],obj->tmp_local_pic.planes[0], + obj->local_pic.strides[0],obj->tmp_local_pic.strides[0], + obj->local_pic.w,obj->local_pic.h); + mirror(obj->local_pic.planes[1],obj->tmp_local_pic.planes[1], + obj->local_pic.strides[1],obj->tmp_local_pic.strides[1], + obj->local_pic.w>>1,obj->local_pic.h>>1); + mirror(obj->local_pic.planes[2],obj->tmp_local_pic.planes[2], + obj->local_pic.strides[2],obj->tmp_local_pic.strides[2], + obj->local_pic.w>>1,obj->local_pic.h>>1); + } + } + ms_queue_flush(f->inputs[1]); + } + + if (f->inputs[0]!=NULL && (inm=ms_queue_peek_last(f->inputs[0]))!=0) { + MSPicture src; + if (yuv_buf_init_from_mblk(&src,inm)==0){ + if (obj->sws1==NULL){ + obj->sws1=sws_getContext(src.w,src.h,PIX_FMT_YUV420P, + obj->fbuf.w,obj->fbuf.h,PIX_FMT_YUV420P, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + } + ms_display_lock(obj->display); + if (sws_scale(obj->sws1,src.planes,src.strides, 0, + src.h, obj->fbuf.planes, obj->fbuf.strides)<0){ + ms_error("Error in sws_scale()."); + } + ms_display_unlock(obj->display); + } + ms_queue_flush(f->inputs[0]); + } + /*copy resized local view into main buffer, at bottom left corner:*/ + if (obj->local_msg!=NULL){ + MSPicture corner=obj->fbuf; + MSVideoSize roi; + roi.width=obj->local_pic.w; + roi.height=obj->local_pic.h; + corner.w=obj->local_pic.w; + corner.h=obj->local_pic.h; + corner.planes[0]+=obj->local_rect.x+(obj->local_rect.y*corner.strides[0]); + corner.planes[1]+=(obj->local_rect.x/2)+((obj->local_rect.y/2)*corner.strides[1]); + corner.planes[2]+=(obj->local_rect.x/2)+((obj->local_rect.y/2)*corner.strides[2]); + ms_display_lock(obj->display); + yuv_buf_copy(obj->local_pic.planes,obj->local_pic.strides, + corner.planes,corner.strides,roi); + ms_display_unlock(obj->display); + } + + ms_display_update(obj->display); + ms_filter_unlock(f); +} + +static int video_out_set_vsize(MSFilter *f,void *arg){ + VideoOut *s=(VideoOut*)f->data; + bool_t reconfigure; + ms_filter_lock(f); + reconfigure=s->ready; + set_vsize(s,(MSVideoSize*)arg); + if (reconfigure) video_out_preprocess(f); + ms_filter_unlock(f); + return 0; +} + +static int video_out_set_display(MSFilter *f,void *arg){ + VideoOut *s=(VideoOut*)f->data; + s->display=(MSDisplay*)arg; + return 0; +} + +static int video_out_handle_resize(MSFilter *f, void *arg){ + VideoOut *s=(VideoOut*)f->data; + MSDisplay *disp=s->display; + if (disp!=NULL){ + MSDisplayEvent ev; + if (ms_display_poll_event(disp,&ev)){ + if (ev.evtype==MS_DISPLAY_RESIZE_EVENT){ + MSVideoSize sz; + sz.width=ev.w; + sz.height=ev.h; +#ifndef WIN32 + video_out_set_vsize(f,&sz); +#endif + } + } + } + return 0; +} + +static int video_out_set_corner(MSFilter *f,void *arg){ + VideoOut *s=(VideoOut*)f->data; + set_corner(s, *(int*)arg); +#if 1 + ms_filter_lock(f); + ms_display_lock(s->display); + { + int w=s->fbuf.w; + int h=s->fbuf.h; + int ysize=w*h; + int usize=ysize/4; + + memset(s->fbuf.planes[0], 0, ysize); + memset(s->fbuf.planes[1], 0, usize); + memset(s->fbuf.planes[2], 0, usize); + } + ms_display_unlock(s->display); + ms_filter_unlock(f); +#endif + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_VIDEO_SIZE , video_out_set_vsize }, + { MS_VIDEO_OUT_SET_DISPLAY , video_out_set_display}, + { MS_VIDEO_OUT_HANDLE_RESIZING , video_out_handle_resize}, + { MS_VIDEO_OUT_SET_CORNER , video_out_set_corner}, + { 0 ,NULL} +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_video_out_desc={ + MS_VIDEO_OUT_ID, + "MSVideoOut", + "A generic video display", + MS_FILTER_OTHER, + NULL, + 2, + 0, + video_out_init, + video_out_preprocess, + video_out_process, + video_out_postprocess, + video_out_uninit, + methods +}; + +#else + +MSFilterDesc ms_video_out_desc={ + .id=MS_VIDEO_OUT_ID, + .name="MSVideoOut", + .text="A generic video display", + .category=MS_FILTER_OTHER, + .ninputs=2, + .noutputs=0, + .init=video_out_init, + .preprocess=video_out_preprocess, + .process=video_out_process, + .postprocess=video_out_postprocess, + .uninit=video_out_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_video_out_desc) diff --git a/linphone/mediastreamer2/src/videostream.c b/linphone/mediastreamer2/src/videostream.c new file mode 100644 index 000000000..30a1df479 --- /dev/null +++ b/linphone/mediastreamer2/src/videostream.c @@ -0,0 +1,520 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mediastream.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msrtp.h" + + +#if (defined(WIN32) || defined(_WIN32_WCE)) +/* avoid double declaration of ms_win_display_desc */ +#define MS_VIDEO_OUT_HANDLE_RESIZING MS_FILTER_METHOD_NO_ARG(MS_VIDEO_OUT_ID,1) +#else +#include "mediastreamer2/msvideoout.h" +#endif + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +extern RtpSession * create_duplex_rtpsession( int locport, bool_t ipv6); + +#define MAX_RTP_SIZE UDP_MAX_SIZE + +/* this code is not part of the library itself, it is part of the mediastream program */ +void video_stream_free (VideoStream * stream) +{ + if (stream->session!=NULL){ + rtp_session_unregister_event_queue(stream->session,stream->evq); + rtp_session_destroy(stream->session); + } + if (stream->rtprecv != NULL) + ms_filter_destroy (stream->rtprecv); + if (stream->rtpsend!=NULL) + ms_filter_destroy (stream->rtpsend); + if (stream->source != NULL) + ms_filter_destroy (stream->source); + if (stream->output != NULL) + ms_filter_destroy (stream->output); + if (stream->decoder != NULL) + ms_filter_destroy (stream->decoder); + if (stream->encoder != NULL) + ms_filter_destroy (stream->encoder); + if (stream->pixconv!=NULL) + ms_filter_destroy(stream->pixconv); + if (stream->tee!=NULL) + ms_filter_destroy(stream->tee); + if (stream->ticker != NULL) + ms_ticker_destroy (stream->ticker); + if (stream->evq!=NULL) + ortp_ev_queue_destroy(stream->evq); + ms_free (stream); +} + +/*this function must be called from the MSTicker thread: +it replaces one filter by another one. +This is a dirty hack that works anyway. +It would be interesting to have something that does the job +simplier within the MSTicker api +*/ +void video_stream_change_decoder(VideoStream *stream, int payload){ + RtpSession *session=stream->session; + RtpProfile *prof=rtp_session_get_profile(session); + PayloadType *pt=rtp_profile_get_payload(prof,payload); + if (pt!=NULL){ + MSFilter *dec=ms_filter_create_decoder(pt->mime_type); + if (dec!=NULL){ + ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); + ms_filter_unlink(stream->decoder,0,stream->output,0); + ms_filter_postprocess(stream->decoder); + ms_filter_destroy(stream->decoder); + stream->decoder=dec; + if (pt->recv_fmtp!=NULL) + ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); + ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); + ms_filter_link (stream->decoder,0 , stream->output, 0); + ms_filter_preprocess(stream->decoder,stream->ticker); + + }else{ + ms_warning("No decoder found for %s",pt->mime_type); + } + }else{ + ms_warning("No payload defined with number %i",payload); + } +} + +static void video_stream_adapt_bitrate(VideoStream *stream, int jitter, float lost){ + if (stream->encoder!=NULL){ + if (lost>10){ + int bitrate=0; + int new_bitrate; + ms_warning("Remote reports bad receiving experience, trying to reduce bitrate of video encoder."); + + ms_filter_call_method(stream->encoder,MS_FILTER_GET_BITRATE,&bitrate); + if (bitrate==0){ + ms_error("Video encoder does not implement MS_FILTER_GET_BITRATE."); + return; + } + if (bitrate>=20000){ + new_bitrate=bitrate-10000; + ms_warning("Encoder bitrate reduced from %i to %i b/s.",bitrate,new_bitrate); + ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&new_bitrate); + }else{ + ms_warning("Video encoder bitrate already at minimum."); + } + + } + } +} + +static void video_steam_process_rtcp(VideoStream *stream, mblk_t *m){ + do{ + if (rtcp_is_SR(m)){ + const report_block_t *rb; + ms_message("video_steam_process_rtcp: receiving RTCP SR"); + rb=rtcp_SR_get_report_block(m,0); + if (rb){ + unsigned int ij; + float flost; + ij=report_block_get_interarrival_jitter(rb); + flost=100.0*report_block_get_fraction_lost(rb)/256.0; + ms_message("interarrival jitter=%u , lost packets percentage since last report=%f ",ij,flost); + if (stream->adapt_bitrate) video_stream_adapt_bitrate(stream,ij,flost); + } + } + }while(rtcp_next_packet(m)); +} + +void video_stream_iterate(VideoStream *stream){ + if (stream->output!=NULL) + ms_filter_call_method_noarg(stream->output, + MS_VIDEO_OUT_HANDLE_RESIZING); + if (stream->evq){ + OrtpEvent *ev=ortp_ev_queue_get(stream->evq); + if (ev!=NULL){ + if (ortp_event_get_type(ev)==ORTP_EVENT_RTCP_PACKET_RECEIVED){ + OrtpEventData *evd=ortp_event_get_data(ev); + video_steam_process_rtcp(stream,evd->packet); + } + ortp_event_destroy(ev); + } + } +} + +static void payload_type_changed(RtpSession *session, unsigned long data){ + VideoStream *stream=(VideoStream*)data; + int pt=rtp_session_get_recv_payload_type(stream->session); + video_stream_change_decoder(stream,pt); +} + +VideoStream *video_stream_new(int locport, bool_t use_ipv6){ + VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1); + stream->session=create_duplex_rtpsession(locport,use_ipv6); + stream->evq=ortp_ev_queue_new(); + stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID); + rtp_session_register_event_queue(stream->session,stream->evq); + return stream; +} + +void video_stream_set_relay_session_id(VideoStream *stream, const char *id){ + ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id); +} + + +void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno){ + s->adapt_bitrate=yesno; +} + +int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport, + int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam) +{ + PayloadType *pt; + RtpSession *rtps=stream->session; + MSPixFmt format; + MSVideoSize vsize; + float fps=15; + + vsize.height=MS_VIDEO_SIZE_CIF_H; + vsize.width=MS_VIDEO_SIZE_CIF_W; + + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + ms_error("videostream.c: undefined payload type."); + return -1; + } + stream->encoder=ms_filter_create_encoder(pt->mime_type); + stream->decoder=ms_filter_create_decoder(pt->mime_type); + if ((stream->encoder==NULL) || (stream->decoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_type); + return -1; + } + + rtp_session_set_profile(rtps,profile); + if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + rtp_session_signal_connect(stream->session,"payload_type_changed", + (RtpCallback)payload_type_changed,(unsigned long)stream); + + rtp_session_set_recv_buf_size(stream->session,MAX_RTP_SIZE); + + /* creates two rtp filters to recv send streams (remote part) */ + if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session); + + stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID); + ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session); + + /* creates the filters */ + stream->source = ms_web_cam_create_reader(cam); + stream->tee = ms_filter_new(MS_TEE_ID); + stream->output=ms_filter_new(MS_VIDEO_OUT_ID); + + + + if (pt->normal_bitrate>0){ + ms_message("Limiting bitrate of video encoder to %i bits/s",pt->normal_bitrate); + ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate); + } + /* set parameters to the encoder and decoder*/ + if (pt->send_fmtp){ + ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); + ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); + } + ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize); + ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps); + ms_message("Setting vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps); + /* configure the filters */ + ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps); + ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize); + + /* get the output format for webcam reader */ + ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format); + if (format==MS_MJPEG){ + stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID); + }else{ + stream->pixconv = ms_filter_new(MS_PIX_CONV_ID); + /*set it to the pixconv */ + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize); + } + /*force the decoder to output YUV420P */ + format=MS_YUV420P; + ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format); + + + /*ask the video display to always output CIF */ + vsize.height=MS_VIDEO_SIZE_CIF_H; + vsize.width=MS_VIDEO_SIZE_CIF_W; + + ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize); + ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); + + if (pt->recv_fmtp!=NULL) + ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); + + /* and then connect all */ + ms_filter_link (stream->source, 0, stream->pixconv, 0); + ms_filter_link (stream->pixconv, 0, stream->tee, 0); + ms_filter_link (stream->tee, 0 ,stream->encoder, 0 ); + ms_filter_link (stream->encoder,0, stream->rtpsend,0); + + ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); + ms_filter_link (stream->decoder,0 , stream->output, 0); + /* the source video must be send for preview */ + ms_filter_link(stream->tee,1,stream->output,1); + + /* create the ticker */ + stream->ticker = ms_ticker_new(); + /* attach it the graph */ + ms_ticker_attach (stream->ticker, stream->source); + return 0; +} + +void video_stream_send_vfu(VideoStream *stream){ + if (stream->encoder) + ms_filter_call_method_noarg(stream->encoder,MS_FILTER_REQ_VFU); +} + +void +video_stream_stop (VideoStream * stream) +{ + if (stream->ticker){ + ms_ticker_detach(stream->ticker,stream->source); + + rtp_stats_display(rtp_session_get_stats(stream->session),"Video session's RTP statistics"); + + ms_filter_unlink(stream->source,0,stream->pixconv,0); + ms_filter_unlink(stream->pixconv,0,stream->tee,0); + ms_filter_unlink(stream->tee,0,stream->encoder,0); + ms_filter_unlink(stream->encoder, 0, stream->rtpsend,0); + ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); + ms_filter_unlink(stream->decoder,0,stream->output,0); + ms_filter_unlink(stream->tee,1,stream->output,1); + } + video_stream_free (stream); +} + + +void video_stream_set_rtcp_information(VideoStream *st, const char *cname, const char *tool){ + if (st->session!=NULL){ + rtp_session_set_source_description(st->session,cname,NULL,NULL,NULL,NULL,tool, + "This is free software (GPL) !"); + } +} + + + +VideoStream * video_preview_start(MSWebCam *device){ + VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1); + MSPixFmt format; + MSVideoSize vsize; + vsize.width=MS_VIDEO_SIZE_CIF_W; + vsize.height=MS_VIDEO_SIZE_CIF_H; + + /* creates the filters */ + stream->source = ms_web_cam_create_reader(device); + stream->output = ms_filter_new(MS_VIDEO_OUT_ID); + + /* configure the filters */ + ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format); + ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize); + + if (format==MS_MJPEG){ + stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID); + }else{ + stream->pixconv=ms_filter_new(MS_PIX_CONV_ID); + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize); + } + format=MS_YUV420P; + ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize); + /* and then connect all */ + ms_filter_link(stream->source,0, stream->pixconv,0); + ms_filter_link(stream->pixconv,0,stream->output,0); + /* create the ticker */ + stream->ticker = ms_ticker_new(); + ms_ticker_attach (stream->ticker, stream->source); + return stream; +} + +void video_preview_stop(VideoStream *stream){ + ms_ticker_detach(stream->ticker, stream->source); + ms_filter_unlink(stream->source,0,stream->pixconv,0); + ms_filter_unlink(stream->pixconv,0,stream->output,0); + + video_stream_free(stream); +} + + +int video_stream_send_only_start(VideoStream* stream, RtpProfile *profile, const char *remip, int remport, + int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *device){ + PayloadType *pt; + MSPixFmt format; + MSVideoSize vsize; + RtpSession *rtps=stream->session; + float fps=15; + + vsize.width=MS_VIDEO_SIZE_CIF_W; + vsize.height=MS_VIDEO_SIZE_CIF_H; + + rtp_session_set_profile(rtps,profile); + if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + /* creates rtp filter to send streams (remote part) */ + rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE); + stream->rtpsend =ms_filter_new(MS_RTP_SEND_ID); + if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session); + + /* creates the filters */ + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + video_stream_free(stream); + ms_error("videostream.c: undefined payload type."); + return -1; + } + stream->encoder=ms_filter_create_encoder(pt->mime_type); + if ((stream->encoder==NULL)){ + /* big problem: we have not a registered codec for this payload...*/ + video_stream_free(stream); + ms_error("videostream.c: No codecs available for payload %i.",payload); + return -1; + } + + /* creates the filters */ + stream->source = ms_web_cam_create_reader(device); + stream->pixconv= ms_filter_new(MS_PIX_CONV_ID); + + + /* configure the filters */ + if (pt->send_fmtp) + ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); + ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate); + ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps); + ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize); + + ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps); + ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize); + + /* get the output format for webcam reader */ + ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format); + /*set it to the pixconv */ + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize); + + ms_message("vsize=%ix%i, fps=%f, send format: %s, capture format: %d, bitrate: %d", + vsize.width,vsize.height,fps,pt->send_fmtp,format, pt->normal_bitrate); + + /* and then connect all */ + ms_filter_link (stream->source, 0, stream->pixconv, 0); + ms_filter_link (stream->pixconv, 0, stream->encoder, 0); + ms_filter_link (stream->encoder,0, stream->rtpsend,0); + + /* create the ticker */ + stream->ticker = ms_ticker_new(); + /* attach it the graph */ + ms_ticker_attach (stream->ticker, stream->source); + return 0; +} + +void video_stream_send_only_stop(VideoStream *stream){ + if (stream->ticker){ + ms_ticker_detach (stream->ticker, stream->source); + ms_filter_unlink(stream->source,0,stream->pixconv,0); + ms_filter_unlink(stream->pixconv,0,stream->encoder,0); + ms_filter_unlink(stream->encoder,0,stream->rtpsend,0); + } + video_stream_free(stream); +} + +int video_stream_recv_only_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport,int payload, int jitt_comp){ + PayloadType *pt; + MSPixFmt format; + MSVideoSize vsize; + RtpSession *rtps=stream->session; + + vsize.width=MS_VIDEO_SIZE_CIF_W; + vsize.height=MS_VIDEO_SIZE_CIF_H; + + rtp_session_set_profile(rtps,profile); + if (remport>0) rtp_session_set_remote_addr(rtps,remip,remport); + rtp_session_set_payload_type(rtps,payload); + rtp_session_set_jitter_compensation(rtps,jitt_comp); + + /* creates rtp filters to recv streams */ + rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE); + stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID); + ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps); + + /* creates the filters */ + pt=rtp_profile_get_payload(profile,payload); + if (pt==NULL){ + ms_error("videostream.c: undefined payload type."); + return -1; + } + stream->decoder=ms_filter_create_decoder(pt->mime_type); + if (stream->decoder==NULL){ + /* big problem: we have not a registered codec for this payload...*/ + ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_type); + return -1; + } + stream->output=ms_filter_new(MS_VIDEO_OUT_ID); + + /*force the decoder to output YUV420P */ + format=MS_YUV420P; + /*ask the size-converter to always output CIF */ + vsize.width=MS_VIDEO_SIZE_CIF_W; + vsize.height=MS_VIDEO_SIZE_CIF_H; + ms_message("Setting output vsize=%ix%i",vsize.width,vsize.height); + + ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); + ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize); + + if (pt->recv_fmtp!=NULL) { + ms_message("pt->recv_fmtp: %s", pt->recv_fmtp); + ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); + } + + /* and then connect all */ + ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); + ms_filter_link (stream->decoder,0 , stream->output, 0); + + /* create the ticker */ + stream->ticker = ms_ticker_new(); + /* attach it the graph */ + ms_ticker_attach (stream->ticker, stream->rtprecv); + return 0; +} + +void video_stream_recv_only_stop (VideoStream * stream){ + if (stream->ticker!=NULL){ + ms_ticker_detach(stream->ticker, stream->rtprecv); + rtp_stats_display(rtp_session_get_stats(stream->session),"Video session's RTP statistics"); + ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); + ms_filter_unlink(stream->decoder,0,stream->output,0); + } + video_stream_free (stream); +} + diff --git a/linphone/mediastreamer2/src/wincevideods.c b/linphone/mediastreamer2/src/wincevideods.c new file mode 100644 index 000000000..160cbb6ee --- /dev/null +++ b/linphone/mediastreamer2/src/wincevideods.c @@ -0,0 +1,998 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +//#define AYMERIC_TEST +#define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msv4l.h" + +#include +#include "nowebcam.h" +#if 0 +#include +#endif + +#include +#include +#include + +#include +//#include +#include "dxfilter.h" +#if 0 +#include +#endif +#include +#include + +typedef struct V4wState{ + + char dev[512]; + int devidx; + + CComPtr m_pGraph; + CComPtr m_pBuilder; + CComPtr m_pControl; + CDXFilter *m_pDXFilter; + CComPtr m_pIDXFilter; + CComPtr m_pNullRenderer; + CComPtr m_pDeviceFilter; + DWORD rotregvalue; + + MSVideoSize vsize; + int pix_fmt; + mblk_t *mire[10]; + queue_t rq; + ms_mutex_t mutex; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + bool_t running; + bool_t startwith_yuv_bug; /* avoid bug with USB vimicro cards. */ +}V4wState; + +static V4wState *s_callback=NULL; + +static void dummy(void*p){ +} + +HRESULT ( Callback)(IMediaSample* pSample, REFERENCE_TIME* sTime, REFERENCE_TIME* eTime, BOOL changed) +{ + BYTE *byte_buf=NULL; + mblk_t *buf; + + V4wState *s = s_callback; + if (s==NULL) + return S_OK; + + HRESULT hr = pSample->GetPointer(&byte_buf); + if (FAILED(hr)) + { + return S_OK; + } + + int size = pSample->GetActualDataLength(); + if (size>+1000) + { + buf=allocb(size,0); + memcpy(buf->b_wptr, byte_buf, size); + if (s->pix_fmt==MS_RGB24) + { + /* Conversion from top down bottom up (BGR to RGB and flip) */ + unsigned long Index,nPixels; + unsigned char *blue; + unsigned char tmp; + short iPixelSize; + + blue=buf->b_wptr; + + nPixels=s->vsize.width*s->vsize.height; + iPixelSize=24/8; + + for(Index=0;Index!=nPixels;Index++) // For each pixel + { + tmp=*blue; + *blue=*(blue+2); + *(blue+2)=tmp; + blue+=iPixelSize; + } + + unsigned char *pLine1, *pLine2; + int iLineLen,iIndex; + + iLineLen=s->vsize.width*iPixelSize; + pLine1=buf->b_wptr; + pLine2=&(buf->b_wptr)[iLineLen * (s->vsize.height - 1)]; + + for( ;pLine1b_wptr+=size; + + ms_mutex_lock(&s->mutex); + putq(&s->rq, buf); + ms_mutex_unlock(&s->mutex); + + } + return S_OK; +} + +HRESULT GetFirstCameraDriver( WCHAR *pwzName ) { + HRESULT hr = S_OK; + HANDLE handle = NULL; + DEVMGR_DEVICE_INFORMATION di; + GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, + 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 }; + + if( pwzName == NULL ) { + return E_POINTER; + } + + di.dwSize = sizeof(di); + + handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); + if(( handle == NULL ) || ( di.hDevice == NULL )) { + return S_FALSE; + } + + StringCchCopy( pwzName, MAX_PATH, di.szLegacyName ); + + FindClose( handle ); + return hr; +} + +struct VAR_LIST +{ + VARIANT var; + VAR_LIST *pNext; + BSTR pBSTRName; +}; + +class CPropertyBag : public IPropertyBag +{ +public: + CPropertyBag(); + ~CPropertyBag(); + + HRESULT STDMETHODCALLTYPE + Read( + LPCOLESTR pszPropName, + VARIANT *pVar, + IErrorLog *pErrorLog + ); + + + HRESULT STDMETHODCALLTYPE + Write( + LPCOLESTR pszPropName, + VARIANT *pVar + ); + + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); + +private: + ULONG _refCount; + VAR_LIST *pVar; +}; + +CPropertyBag::CPropertyBag() : _refCount(1), pVar(0) +{ +} + +CPropertyBag::~CPropertyBag() +{ + VAR_LIST *pTemp = pVar; + HRESULT hr = S_OK; + + while(pTemp) + { + VAR_LIST *pDel = pTemp; + VariantClear(&pTemp->var); + SysFreeString(pTemp->pBSTRName); + pTemp = pTemp->pNext; + delete pDel; + } + +} + +HRESULT STDMETHODCALLTYPE +CPropertyBag::Read(LPCOLESTR pszPropName, + VARIANT *_pVar, + IErrorLog *pErrorLog) +{ + VAR_LIST *pTemp = pVar; + HRESULT hr = S_OK; + + while(pTemp) + { + if(0 == wcscmp(pszPropName, pTemp->pBSTRName)) + { + hr = VariantCopy(_pVar, &pTemp->var); + break; + } + pTemp = pTemp->pNext; + } + return hr; +} + + +HRESULT STDMETHODCALLTYPE +CPropertyBag::Write(LPCOLESTR pszPropName, + VARIANT *_pVar) +{ + HRESULT hr = S_OK; + VAR_LIST *pTemp = new VAR_LIST(); + ASSERT(pTemp); + + if( !pTemp ) + { + return E_OUTOFMEMORY; + } + + VariantInit(&pTemp->var); + pTemp->pBSTRName = SysAllocString(pszPropName); + pTemp->pNext = pVar; + pVar = pTemp; + return VariantCopy(&pTemp->var, _pVar); +} + +ULONG STDMETHODCALLTYPE +CPropertyBag::AddRef() +{ + return InterlockedIncrement((LONG *)&_refCount); +} + +ULONG STDMETHODCALLTYPE +CPropertyBag::Release() +{ + ASSERT(_refCount != 0xFFFFFFFF); + ULONG ret = InterlockedDecrement((LONG *)&_refCount); + if(!ret) + delete this; + return ret; +} + +HRESULT STDMETHODCALLTYPE +CPropertyBag::QueryInterface(REFIID riid, void** ppv) +{ + if(!ppv) + return E_POINTER; + if(riid == IID_IPropertyBag) + *ppv = static_cast(this); + else + return *ppv = 0, E_NOINTERFACE; + + return AddRef(), S_OK; +} + +static int v4w_open_videodevice(V4wState *s, int format, MSVideoSize *vsize) +{ + // Initialize COM + CoInitialize(NULL); + + // get a Graph + HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph); + if(FAILED(hr)) + { + return -1; + } + + // get a CaptureGraphBuilder2 +#if !defined(_WIN32_WCE) + hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2); +#else + hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder); +#endif + if(FAILED(hr)) + { + return -2; + } + + // connect capture graph builder with the graph + s->m_pBuilder->SetFiltergraph(s->m_pGraph); + + // get mediacontrol so we can start and stop the filter graph + hr=s->m_pGraph.QueryInterface(&(s->m_pControl)); + if(FAILED(hr)) + { + return -3; + } + + // get DXFilter + s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); + if(s->m_pDXFilter==NULL) + { + return -4; + } + s->m_pDXFilter->AddRef(); + if(FAILED(hr)) + { + return -4; + } + + CMediaType mt; + mt.SetType(&MEDIATYPE_Video); + + if (format==MS_YUV420P) + { + GUID m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); + mt.SetSubtype(&m); + mt.SetSubtype(&MEDIASUBTYPE_YV12); + } + else //if (format==MS_RGB24) + { + mt.SetSubtype(&MEDIASUBTYPE_RGB24); + } + + //mt.SetSubtype(&MEDIASUBTYPE_IYUV); + //mt.SetSubtype(&MEDIASUBTYPE_YUYV); + //mt.SetSubtype(&MEDIASUBTYPE_RGB24); + //mt.SetSampleSize(); + mt.formattype = FORMAT_VideoInfo; + mt.SetTemporalCompression(FALSE); + + VIDEOINFO *pvi = (VIDEOINFO *) + mt.AllocFormatBuffer(sizeof(VIDEOINFO)); + if (NULL == pvi) + return E_OUTOFMEMORY; + ZeroMemory(pvi, sizeof(VIDEOINFO)); + if (format==MS_YUV420P) + { + pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); + pvi->bmiHeader.biCompression = MAKEFOURCC('Y','V','1','2'); + pvi->bmiHeader.biBitCount = 12; + } + else + { + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 24; + } + pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pvi->bmiHeader.biWidth = vsize->width; + pvi->bmiHeader.biHeight = vsize->height; + pvi->bmiHeader.biPlanes = 1; + pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); + pvi->bmiHeader.biClrImportant = 0; + mt.SetSampleSize(pvi->bmiHeader.biSizeImage); + mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); + + hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); + if(FAILED(hr)) + { + return -5; + } + + hr = s->m_pDXFilter->SetCallback(Callback); + if(FAILED(hr)) + { + return -6; + } + + hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, + (LPVOID *)&s->m_pIDXFilter); + if(FAILED(hr)) + { + return -7; + } + + hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); + if(FAILED(hr)) + { + return -8; + } + +#ifdef WM6 + ICreateDevEnum *pCreateDevEnum = NULL; + IEnumMoniker *pEnumMoniker = NULL; + IMoniker *pMoniker = NULL; + + ULONG nFetched = 0; + + hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); + if(FAILED(hr)) + { + return -9; + } + + hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, + &pEnumMoniker, 0); + if (FAILED(hr) || pEnumMoniker == NULL) { + //printf("no device\n"); + return -10; + } + + pEnumMoniker->Reset(); + + hr = pEnumMoniker->Next(1, &pMoniker, &nFetched); + if(FAILED(hr) || pMoniker==NULL) + { + return -11; + } + + hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); + if(FAILED(hr)) + { + return -12; + } + + s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); + + pMoniker->Release(); + pEnumMoniker->Release(); + pCreateDevEnum->Release(); +#else + WCHAR wzDeviceName[ MAX_PATH + 1 ]; + CComVariant varCamName; + CPropertyBag PropBag; + CComPtr pPropertyBag; + GetFirstCameraDriver(wzDeviceName); + + hr = s->m_pDeviceFilter.CoCreateInstance( CLSID_VideoCapture ); + if (FAILED(hr)) + { + return -8; + } + + s->m_pDeviceFilter.QueryInterface( &pPropertyBag ); + varCamName = wzDeviceName; + if(( varCamName.vt == VT_BSTR ) == NULL ) { + return E_OUTOFMEMORY; + } + PropBag.Write( L"VCapName", &varCamName ); + pPropertyBag->Load( &PropBag, NULL ); + pPropertyBag.Release(); + + hr = s->m_pGraph->AddFilter( s->m_pDeviceFilter, L"Video capture source" ); +#endif + + if (FAILED(hr)) + { + return -8; + } + + // get null renderer + s->m_pNullRenderer = NULL; +#if 0 + hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer); + if(FAILED(hr)) + { + return -13; + } +#endif + if (s->m_pNullRenderer!=NULL) + { + s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); + } + + hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, + &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); + if (FAILED(hr)) + { + //hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, + // &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); + if (FAILED(hr)) + { + return -14; + } + } + + //m_pDXFilter->SetBufferSamples(TRUE); + + + // Create the System Device Enumerator. +IFilterMapper *pMapper = NULL; +//IEnumMoniker *pEnum = NULL; +IEnumRegFilters *pEnum = NULL; + +hr = CoCreateInstance(CLSID_FilterMapper, + NULL, CLSCTX_INPROC, IID_IFilterMapper, + (void **) &pMapper); + +if (FAILED(hr)) +{ + // Error handling omitted for clarity. +} + +GUID arrayInTypes[2]; +arrayInTypes[0] = MEDIATYPE_Video; +arrayInTypes[1] = MEDIASUBTYPE_dvsd; + +hr = pMapper->EnumMatchingFilters( + &pEnum, + MERIT_HW_COMPRESSOR, // Minimum merit. + FALSE, // At least one input pin? + MEDIATYPE_NULL, + MEDIASUBTYPE_NULL, + FALSE, // Must be a renderer? + FALSE, // At least one output pin? + MEDIATYPE_NULL, + MEDIASUBTYPE_NULL); + +// Enumerate the monikers. +//IMoniker *pMoniker; +REGFILTER *pMoniker; +ULONG cFetched; +while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK) +{ + IPropertyBag *pPropBag = NULL; +#if 0 + hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, + (void **)&pPropBag); + + if (SUCCEEDED(hr)) + { + // To retrieve the friendly name of the filter, do the following: + VARIANT varName; + VariantInit(&varName); + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + if (SUCCEEDED(hr)) + { + // Display the name in your UI somehow. + } + VariantClear(&varName); + + // To create an instance of the filter, do the following: + IBaseFilter *pFilter; + hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter); + // Now add the filter to the graph. Remember to release pFilter later. + + // Clean up. + pPropBag->Release(); + } + pMoniker->Release(); +#endif + +} + +// Clean up. +pMapper->Release(); +pEnum->Release(); + + + + + s_callback = s; + hr = s->m_pControl->Run(); + if(FAILED(hr)) + { + return -15; + } + + s->rotregvalue=1; + s->pix_fmt = format; + s->vsize.height = vsize->height; + s->vsize.width = vsize->width; + return 0; +} + +static void v4w_init(MSFilter *f){ + V4wState *s=(V4wState *)ms_new0(V4wState,1); + int idx; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + //s->pix_fmt=MS_RGB24; + s->pix_fmt=MS_YUV420P; + + s->rotregvalue = 0; + s->m_pGraph=NULL; + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pDXFilter=NULL; + s->m_pIDXFilter=NULL; + s->m_pDeviceFilter=NULL; + + qinit(&s->rq); + for (idx=0;idx<10;idx++) + { + s->mire[idx]=NULL; + } + ms_mutex_init(&s->mutex,NULL); + s->start_time=0; + s->frame_count=-1; + s->fps=15; + + f->data=s; +} + +static int try_format(V4wState *s, int format, MSVideoSize *vsize) +{ + int i = v4w_open_videodevice(s, format, vsize); + if (i==-14) + { + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + } + return i; +} + +static int _v4w_start(V4wState *s, void *arg) +{ + MSVideoSize try_vsize; + int tryformat; + int i; + s->frame_count=-1; + + if (s->pix_fmt==MS_YUV420P) + tryformat = MS_RGB24; + else if (s->pix_fmt==MS_RGB24) + tryformat = MS_YUV420P; + + try_vsize.height = s->vsize.height; + try_vsize.width = s->vsize.width; + i = try_format(s, s->pix_fmt, &try_vsize); + if (i==-14) + { + /* try second format with same size */ + i = try_format(s, tryformat, &try_vsize); + } + + /* try both format with CIF size */ + if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_CIF_H) + { + try_vsize.height = MS_VIDEO_SIZE_CIF_H; + try_vsize.width = MS_VIDEO_SIZE_CIF_W; + i = try_format(s, s->pix_fmt, &try_vsize); + if (i==-14) + { + i = try_format(s, tryformat, &try_vsize); + } + } + if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_QCIF_H) + { + try_vsize.height = MS_VIDEO_SIZE_QCIF_H; + try_vsize.width = MS_VIDEO_SIZE_QCIF_W; + i = try_format(s, s->pix_fmt, &try_vsize); + if (i==-14) + { + i = try_format(s, tryformat, &try_vsize); + } + } + if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_VGA_H) + { + try_vsize.height = MS_VIDEO_SIZE_VGA_H; + try_vsize.width = MS_VIDEO_SIZE_VGA_W; + i = try_format(s, s->pix_fmt, &try_vsize); + if (i==-14) + { + i = try_format(s, tryformat, &try_vsize); + } + } + + if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_QVGA_H) + { + try_vsize.height = MS_VIDEO_SIZE_QVGA_H; + try_vsize.width = MS_VIDEO_SIZE_QVGA_W; + i = try_format(s, s->pix_fmt, &try_vsize); + if (i==-14) + { + i = try_format(s, tryformat, &try_vsize); + } + } + + if (i==0) + { + if (s->pix_fmt==MS_YUV420P) + ms_message("Using YUV420P"); + else if (s->pix_fmt==MS_RGB24) + ms_message("Using RGB24"); + } + + if (s->rotregvalue==0){ + //RemoveGraphFromRot(s->rotregvalue); + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph not started (err=%i)", i); + s->rotregvalue=0; + } + return i; +} + +static int _v4w_stop(V4wState *s, void *arg){ + s->frame_count=-1; + if (s->rotregvalue>0){ + HRESULT hr = s->m_pControl->Stop(); + if(FAILED(hr)) + { + ms_message("v4w: could not stop graph"); + } + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + //RemoveGraphFromRot(s->rotregvalue); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph destroyed"); + s->rotregvalue=0; + } + return 0; +} + + +static int v4w_start(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_start(s, NULL); + return 0; +} + +static int v4w_stop(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_stop(s, NULL); + return 0; +} + + +static void v4w_uninit(MSFilter *f){ + V4wState *s=(V4wState*)f->data; + int idx; + flushq(&s->rq,0); + ms_mutex_destroy(&s->mutex); + for (idx=0;idx<10;idx++) + { + if (s->mire[idx]==NULL) + break; + freemsg(s->mire[idx]); + } + if (s->rotregvalue>0){ + HRESULT hr = s->m_pControl->Stop(); + if(FAILED(hr)) + { + ms_message("v4w: could not stop graph"); + } + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + //RemoveGraphFromRot(s->rotregvalue); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph destroyed"); + s->rotregvalue=0; + } + ms_free(s); +} + +static mblk_t * v4w_make_nowebcam(V4wState *s){ +#if defined(_WIN32_WCE) + return NULL; +#else + int idx; + int count; + if (s->mire[0]==NULL && s->frame_ind==0){ + /* load several images to fake a movie */ + for (idx=0;idx<10;idx++) + { + s->mire[idx]=ms_load_nowebcam(&s->vsize, idx); + if (s->mire[idx]==NULL) + break; + } + if (idx==0) + s->mire[0]=ms_load_nowebcam(&s->vsize, -1); + } + for (count=0;count<10;count++) + { + if (s->mire[count]==NULL) + break; + } + + s->frame_ind++; + if (count==0) + return NULL; + + idx = s->frame_ind%count; + if (s->mire[idx]!=NULL) + return s->mire[idx]; + return s->mire[0]; +#endif +} + +static void v4w_preprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + s->running=TRUE; + if (s->rotregvalue==0) + s->fps=1; +} + +static void v4w_postprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + s->running=FALSE; +} + +static void v4w_process(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + mblk_t *m; + uint32_t timestamp; + int cur_frame; + + if (s->frame_count==-1){ + s->start_time=obj->ticker->time; + s->frame_count=0; + } + + + cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame>s->frame_count){ + mblk_t *om=NULL; + ms_mutex_lock(&s->mutex); + /*keep the most recent frame if several frames have been captured */ + if (s->rotregvalue!=0){ + while((m=getq(&s->rq))!=NULL){ + if (om!=NULL) freemsg(om); + om=m; + } + }else { + mblk_t *nowebcam = v4w_make_nowebcam(s); + if (nowebcam!=NULL) + om=dupmsg(nowebcam); + } + ms_mutex_unlock(&s->mutex); + if (om!=NULL){ + timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/ + mblk_set_timestamp_info(om,timestamp); + ms_queue_put(obj->outputs[0],om); + /*ms_message("picture sent");*/ + } + s->frame_count++; + } +} + + + +static int v4w_set_fps(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->fps=*((float*)arg); + return 0; +} + +static int v4w_get_pix_fmt(MSFilter *f,void *arg){ + V4wState *s=(V4wState*)f->data; + *((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt; + return 0; +} + +static int v4w_set_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->vsize=*((MSVideoSize*)arg); + return 0; +} + +static int v4w_get_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + MSVideoSize *vs=(MSVideoSize*)arg; + vs->width=s->vsize.width; + vs->height=s->vsize.height; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , v4w_set_fps }, + { MS_FILTER_GET_PIX_FMT , v4w_get_pix_fmt }, + { MS_FILTER_SET_VIDEO_SIZE, v4w_set_vsize }, + { MS_FILTER_GET_VIDEO_SIZE, v4w_get_vsize }, + { MS_V4L_START , v4w_start }, + { MS_V4L_STOP , v4w_stop }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_v4w_desc={ + MS_V4L_ID, + "MSV4w", + "A video4windows compatible source filter to stream pictures.", + MS_FILTER_OTHER, + NULL, + 0, + 1, + v4w_init, + v4w_preprocess, + v4w_process, + v4w_postprocess, + v4w_uninit, + methods +}; + +#else + +MSFilterDesc ms_v4w_desc={ + .id=MS_V4L_ID, + .name="MSV4w", + .text="A video4windows compatible source filter to stream pictures.", + .ninputs=0, + .noutputs=1, + .category=MS_FILTER_OTHER, + .init=v4w_init, + .preprocess=v4w_preprocess, + .process=v4w_process, + .postprocess=v4w_postprocess, + .uninit=v4w_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_v4w_desc) diff --git a/linphone/mediastreamer2/src/winsnd.c b/linphone/mediastreamer2/src/winsnd.c new file mode 100644 index 000000000..c4c1e6b7e --- /dev/null +++ b/linphone/mediastreamer2/src/winsnd.c @@ -0,0 +1,970 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#if defined(_WIN32_WCE) +#define DISABLE_SPEEX +#endif + +#ifndef WINSND_BUFLEN +#define WINSND_BUFLEN 320 +#endif + +#ifndef MAX_WAVEHDR +#define MAX_WAVEHDR 6 +#endif + +#ifndef DISABLE_SPEEX +#include +#endif + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" + +#ifdef WIN32 +#include /* for alloca */ +#endif + +#include +#ifdef _MSC_VER +#include +#endif +#include + +MSFilter *ms_winsnd_read_new(MSSndCard *card); +MSFilter *ms_winsnd_write_new(MSSndCard *card); + +typedef struct WinSndData{ + char *pcmdev; + char *mixdev; + int devid; + + int sound_err; + WAVEFORMATEX wfx; +#ifdef CONTROLVOLUME + DWORD dwOldVolume; +#endif + WAVEHDR waveouthdr[30]; + char waveoutbuffer[30][3200]; + HWAVEOUT waveoutdev; + int buffer_playing; + int pos_whdr; + + WAVEHDR waveinhdr[30]; + HWAVEIN waveindev; + char waveinbuffer[30][3200]; + + int rate; + int bits; + ms_thread_t thread; + ms_mutex_t mutex; + queue_t rq; + MSBufferizer * bufferizer; + bool_t read_started; + bool_t write_started; + bool_t stereo; + +#ifndef DISABLE_SPEEX + SpeexPreprocessState *pst; +#endif + + uint64_t bytes_read; + int32_t stat_input; + int32_t stat_output; + int32_t stat_notplayed; +} WinSndData; + +static uint64_t winsnd_get_cur_time( void *data){ + WinSndData *d=(WinSndData*)data; + uint64_t curtime=(d->bytes_read*1000)/(d->rate*(d->bits/8)*((d->stereo==FALSE) ? 1 : 2)); + ms_debug("winsnd_get_cur_time: bytes_read=%lu, rate=%i, bits=%i, stereo=%i return %lu\n", + (unsigned long)d->bytes_read,d->rate,d->bits,d->stereo,(unsigned long)curtime); + return curtime; +} + +static void CALLBACK +SpeakerCallback (HWAVEOUT _waveoutdev, UINT uMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) +{ + WAVEHDR *wHdr; + WinSndData *device; + + switch (uMsg) + { + case WOM_OPEN: + ms_message("SpeakerCallback : WOM_OPEN"); + break; + case WOM_CLOSE: + ms_message("SpeakerCallback : WOM_CLOSE"); + break; + case WOM_DONE: + wHdr = (WAVEHDR *) dwParam1; + device = (WinSndData *)dwInstance; + device->buffer_playing--; + if (device->stat_output==0) + { + device->stat_input=1; /* reset */ + device->stat_notplayed=0; + } + device->stat_output++; + break; + default: + break; + } +} + +static void CALLBACK +WaveInCallback (HWAVEIN waveindev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, + DWORD dwParam2) +{ + WAVEHDR *wHdr; + MMRESULT mr = NOERROR; + WinSndData *device; + + device = (WinSndData *)dwInstance; + + switch (uMsg) + { + case MM_WOM_DONE: + wHdr = (WAVEHDR *) dwParam1; + /* A waveform-audio data block has been played and + can now be freed. */ + ms_message("WaveInCallback : MM_WOM_DONE"); + waveInUnprepareHeader (waveindev, (LPWAVEHDR) wHdr, sizeof (WAVEHDR)); + break; + + case WIM_OPEN: + ms_message("WaveInCallback : WIM_OPEN"); + break; + case WIM_CLOSE: + ms_message("WaveInCallback : WIM_CLOSE"); + break; + case WIM_DATA: + wHdr = (WAVEHDR *) dwParam1; + + device->bytes_read+=wHdr->dwBytesRecorded; + + if (!device->read_started && !device->write_started) + { + mr = waveInUnprepareHeader (device->waveindev, (LPWAVEHDR) wHdr, sizeof (WAVEHDR)); + ms_warning("WaveInCallback : unprepare header (waveInUnprepareHeader:0x%i)", mr); + return; + } + + if (wHdr->dwBufferLength!=wHdr->dwBytesRecorded) + { + mr = waveInAddBuffer (device->waveindev, + wHdr, + sizeof (device->waveinhdr[wHdr->dwUser])); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("WaveInCallback : error adding buffer to sound card (waveInAddBuffer:0x%i)", mr); + } + return; + } + ms_mutex_lock(&device->mutex); + if (device->read_started) + { + mblk_t *rm=NULL; + if (rm==NULL) rm=allocb(wHdr->dwBufferLength,0); + memcpy(rm->b_wptr,wHdr->lpData, wHdr->dwBufferLength); + +#ifndef DISABLE_SPEEX + if (device->pst!=NULL) + { + int vad; + //memset(rm->b_wptr,0, wHdr->dwBufferLength); + + vad = speex_preprocess(device->pst, (short*)rm->b_wptr, NULL); +#if 0 + if (vad!=1) + ms_message("WaveInCallback : %d", vad); +#endif + } + +#endif + rm->b_wptr+=wHdr->dwBufferLength; + putq(&device->rq,rm); + device->stat_input++; + rm=NULL; + } + ms_mutex_unlock(&device->mutex); + + mr = waveInAddBuffer (device->waveindev, + wHdr, + sizeof (device->waveinhdr[wHdr->dwUser])); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("WaveInCallback : error adding buffer to sound card (waveInAddBuffer:0x%i)", mr); + return; + } + } +} + +static int winsnd_open(WinSndData *device, int devnumber, int bits,int stereo, int rate, int *minsz) +{ + MMRESULT mr = NOERROR; + DWORD dwFlag; + int i; + int channel = 1; + if (stereo>0) + channel = stereo; + device->wfx.wFormatTag = WAVE_FORMAT_PCM; + device->wfx.cbSize = 0; + device->wfx.nAvgBytesPerSec = 16000; + device->wfx.nBlockAlign = 2; + device->wfx.nChannels = channel; + device->wfx.nSamplesPerSec = rate; /* 8000; */ + device->wfx.wBitsPerSample = bits; + + + dwFlag = CALLBACK_FUNCTION; + if (devnumber != WAVE_MAPPER) + dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION; + mr = waveOutOpen (&(device->waveoutdev), devnumber, &(device->wfx), (DWORD) SpeakerCallback, + (DWORD)device, dwFlag); + if (mr != NOERROR) + { + ms_warning("Failed to open device: trying default device. (waveOutOpen:0x%i)", mr); + dwFlag = CALLBACK_FUNCTION; + mr = waveOutOpen (&(device->waveoutdev), WAVE_MAPPER, &(device->wfx), (DWORD) SpeakerCallback, + (DWORD)device, dwFlag); + } + if (mr != NOERROR) + { + ms_warning("Failed to open windows sound device. (waveOutOpen:0x%i)", mr); + return -1; + } + +#if 0 +#define MM_WOM_SETSECONDARYGAINCLASS (WM_USER) +#define MM_WOM_SETSECONDARYGAINLIMIT (WM_USER+1) +#define MM_WOM_FORCESPEAKER (WM_USER+2) + + bool bSpeaker=TRUE; + mr = waveOutMessage(device->waveoutdev, MM_WOM_FORCESPEAKER, bSpeaker, 0); + if (mr != NOERROR) + { + ms_warning("Failed to use earphone. (waveOutMessage:0x%i)", mr); + return -1; + } + + typedef HRESULT (* _SetSpeakerMode)(DWORD mode); + _SetSpeakerMode pfnSetSpeakerMode; + + HINSTANCE hDll = LoadLibrary(L"\\windows\\ossvcs.dll"); + //_debug(L"ossvcs.dll h=%X",hDll); + pfnSetSpeakerMode = (_SetSpeakerMode)GetProcAddress(hDll,(LPCTSTR)218); + if (pfnSetSpeakerMode) + { + //_debug(L"SetSpeakerMode imported."); + DWORD sm = 0; + //_debug(L"SpeakerMode set to %d", sm); + pfnSetSpeakerMode(sm); + } + //else + //_debug(L"pfnSetSpeakerMode import failed."); + FreeLibrary(hDll); +#endif + +#ifdef CONTROLVOLUME + mr = waveOutGetVolume(device->waveoutdev, &device->dwOldVolume); + if (mr != NOERROR) + { + ms_warning("Failed to get volume device. (waveOutGetVolume:0x%i)", mr); + } + + mr = waveOutSetVolume(device->waveoutdev, 0xFFFFFFFF); + if (mr != NOERROR) + { + ms_warning("Failed to set volume device. (waveOutSetVolume:0x%i)", mr); + } +#endif + + /* prepare windows buffers */ + + for (i = 0; i < MAX_WAVEHDR; i++) + { + memset (&(device->waveouthdr[i]), 0, sizeof (device->waveouthdr[i])); + device->waveouthdr[i].lpData = device->waveoutbuffer[i]; + /* BUG: on ne connait pas la taille des frames a recevoir... + on utilise enc_frame_per_packet au lien de dec_frame_per_packet */ + + device->waveouthdr[i].dwBufferLength = device->rate/8000 * WINSND_BUFLEN; + /* 480 pour 98 (speex) */ + device->waveouthdr[i].dwFlags = 0; + device->waveouthdr[i].dwUser = i; + + mr = waveOutPrepareHeader (device->waveoutdev, &(device->waveouthdr[i]), + sizeof (device->waveouthdr[i])); + if (mr != MMSYSERR_NOERROR){ + ms_warning("Failed to prepare windows sound device. (waveOutPrepareHeader:0x%i)", mr); + } + else + { + ms_message("Sound Header prepared %i for windows sound device. (waveOutPrepareHeader)", i); + } + } + + + /* Init Microphone device */ + dwFlag = CALLBACK_FUNCTION; + if (devnumber != WAVE_MAPPER) + dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION; + mr = waveInOpen (&(device->waveindev), devnumber, &(device->wfx), + (DWORD) WaveInCallback, (DWORD)device, dwFlag); + if (mr != NOERROR) + { + ms_warning("Failed to open device: trying default device. (waveInOpen:0x%i)", mr); + dwFlag = CALLBACK_FUNCTION; + mr = waveInOpen (&(device->waveindev), WAVE_MAPPER, &(device->wfx), + (DWORD) WaveInCallback, (DWORD)device, dwFlag); + } + + if (mr != NOERROR) + { + ms_warning("Failed to prepare windows sound device. (waveInOpen:0x%i)", mr); + return -1; + } + + + + for (i = 0; i < MAX_WAVEHDR; i++) + { + memset (&(device->waveinhdr[i]), 0, sizeof (device->waveinhdr[i])); + device->waveinhdr[i].lpData = device->waveinbuffer[i]; + /* frameSize */ + device->waveinhdr[i].dwBufferLength = device->rate/8000 * WINSND_BUFLEN; + device->waveinhdr[i].dwFlags = 0; + device->waveinhdr[i].dwUser = i; + mr = waveInPrepareHeader (device->waveindev, &(device->waveinhdr[i]), + sizeof (device->waveinhdr[i])); + if (mr == MMSYSERR_NOERROR){ + mr = waveInAddBuffer (device->waveindev, &(device->waveinhdr[i]), + sizeof (device->waveinhdr[i])); + if (mr == MMSYSERR_NOERROR) + { + ms_message("Sound Header prepared %i for windows sound device. (waveInAddBuffer)", i); + } + else + { + ms_warning("Failed to prepare windows sound device. (waveInAddBuffer:0x%i)", mr); + } + } + else + { + ms_warning("Failed to prepare windows sound device. (waveInPrepareHeader:0x%i)", mr); + } + } + +#ifndef DISABLE_SPEEX +#if 0 + device->pst = speex_preprocess_state_init((device->rate/8000 * 320)/2, device->rate); + if (device->pst!=NULL) { + float f; + i=1; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_VAD, &i); + i=1; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=0; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_AGC, &i); + f=8000; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); + i=0; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB, &i); + f=.4; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=.3; + speex_preprocess_ctl(device->pst, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + } +#endif +#endif + + mr = waveInStart (device->waveindev); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("Failed to start recording on windows sound device. (waveInStart:0x%i)", mr); + return -1; + } + + *minsz=device->rate/8000 * 320; + return 0; +} + +static void winsnd_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent) +{ + WinSndData *d=(WinSndData*)card->data; + MMRESULT mr = NOERROR; + DWORD dwVolume = 0xFFFF; + dwVolume = ((0xFFFF) * percent) / 100; + + if (d->mixdev==NULL) return; + switch(e){ + case MS_SND_CARD_MASTER: + mr = waveOutSetVolume(d->waveoutdev, dwVolume); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("Failed to set master volume. (waveOutSetVolume:0x%i)", mr); + return; + } + return; + break; +#if 0 + case MS_SND_CARD_CAPTURE: + wincmd=SOUND_MIXER_IGAIN; + break; + case MS_SND_CARD_PLAYBACK: + wincmd=SOUND_MIXER_PCM; + break; +#endif + default: + ms_warning("winsnd_card_set_level: unsupported command."); + return; + } +} + +static int winsnd_get_level(MSSndCard *card, MSSndCardMixerElem e) +{ + WinSndData *d=(WinSndData*)card->data; + MMRESULT mr = NOERROR; + DWORD dwVolume = 0x0000; + + if (d->mixdev==NULL) return -1; + switch(e){ + case MS_SND_CARD_MASTER: + mr=waveOutGetVolume(d->waveoutdev, &dwVolume); + // Transform to 0 to 100 scale + //dwVolume = (dwVolume *100) / (0xFFFF); + return 60; + break; +#if 0 + case MS_SND_CARD_CAPTURE: + osscmd=SOUND_MIXER_IGAIN; + break; + case MS_SND_CARD_PLAYBACK: + osscmd=SOUND_MIXER_PCM; + break; +#endif + default: + ms_warning("winsnd_card_get_level: unsupported command."); + return -1; + } + return -1; +} + +static void winsnd_set_source(MSSndCard *card, MSSndCardCapture source) +{ + WinSndData *d=(WinSndData*)card->data; + if (d->mixdev==NULL) return; + + switch(source){ + case MS_SND_CARD_MIC: + break; + case MS_SND_CARD_LINE: + break; + } +} + +static void winsnd_init(MSSndCard *card){ + WinSndData *d=(WinSndData*)ms_new(WinSndData,1); + memset(d, 0, sizeof(WinSndData)); + d->bytes_read=0; + d->pcmdev=NULL; + d->mixdev=NULL; + d->sound_err=-1; /* not opened */ + d->read_started=FALSE; + d->write_started=FALSE; + d->bits=16; + d->rate=8000; + d->stereo=FALSE; + qinit(&d->rq); + d->bufferizer=ms_bufferizer_new(); + ms_mutex_init(&d->mutex,NULL); + card->data=d; +#ifndef DISABLE_SPEEX + d->pst=0; +#endif + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; +} + +static void winsnd_uninit(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + if (d==NULL) + return; + if (d->pcmdev!=NULL) ms_free(d->pcmdev); + if (d->mixdev!=NULL) ms_free(d->mixdev); + ms_bufferizer_destroy(d->bufferizer); + flushq(&d->rq,0); + + ms_mutex_destroy(&d->mutex); + +#ifndef DISABLE_SPEEX + if (d->pst!=NULL) + speex_preprocess_state_destroy(d->pst); +#endif + + ms_free(d); +} + +#define DSP_NAME "/dev/dsp" +#define MIXER_NAME "/dev/mixer" + +static void winsnd_detect(MSSndCardManager *m); +static MSSndCard *winsnd_dup(MSSndCard *obj); + +MSSndCardDesc winsnd_card_desc={ + "WINSND", + winsnd_detect, + winsnd_init, + winsnd_set_level, + winsnd_get_level, + winsnd_set_source, + ms_winsnd_read_new, + ms_winsnd_write_new, + winsnd_uninit, + winsnd_dup +}; + +static MSSndCard *winsnd_dup(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&winsnd_card_desc); + WinSndData *dcard=(WinSndData*)card->data; + WinSndData *dobj=(WinSndData*)obj->data; + dcard->pcmdev=ms_strdup(dobj->pcmdev); + dcard->mixdev=ms_strdup(dobj->mixdev); + dcard->devid=dobj->devid; + card->name=ms_strdup(obj->name); + return card; +} + +static MSSndCard *winsnd_card_new(const char *pcmdev, const char *mixdev, int id){ + MSSndCard *card=ms_snd_card_new(&winsnd_card_desc); + WinSndData *d=(WinSndData*)card->data; + d->pcmdev=ms_strdup(pcmdev); + d->mixdev=ms_strdup(mixdev); + card->name=ms_strdup(pcmdev); + d->devid=id; + return card; +} + +static void winsnd_detect(MSSndCardManager *m){ + MMRESULT mr = NOERROR; + unsigned int nInDevices = waveInGetNumDevs (); + unsigned int item; + char pcmdev[1024]; + char mixdev[1024]; + + for (item = 0; item < nInDevices; item++) + { + WAVEINCAPS caps; + mr = waveInGetDevCaps (item, &caps, sizeof (WAVEINCAPS)); + if (mr == MMSYSERR_NOERROR) + { + MSSndCard *card; + snprintf(pcmdev,sizeof(pcmdev),"%s",caps.szPname); + snprintf(mixdev,sizeof(mixdev),"%s",caps.szPname); + if (item == 0) + { + card=winsnd_card_new(pcmdev,mixdev, item-1); + ms_snd_card_manager_add_card(m,card); + } + card=winsnd_card_new(pcmdev,mixdev, item); + ms_snd_card_manager_add_card(m,card); + } + } +#if 0 + nInDevices = mixerGetNumDevs (); + for (item = 0; item < nInDevices; item++) + { + MIXERCAPS caps; + mr = mixerGetDevCaps (item, &caps, sizeof (MIXERCAPS)); + if (mr == MMSYSERR_NOERROR) + { + snprintf(pcmdev,sizeof(pcmdev),"%s",caps.szPname); + snprintf(mixdev,sizeof(mixdev),"%s",caps.szPname); + } + } +#endif +} + +static void * winsnd_thread(void *p){ + MSSndCard *card=(MSSndCard*)p; + WinSndData *d=(WinSndData*)card->data; + int bsize=d->rate/8000 * 320; + uint8_t *rtmpbuff=NULL; + uint8_t *wtmpbuff=NULL; + int err; + + MMRESULT mr = NOERROR; + int pos_whdr=0; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->sound_err=winsnd_open(d, d->devid, d->bits,d->stereo,d->rate,&bsize); + if (d->sound_err==0){ + rtmpbuff=(uint8_t*)alloca(bsize); + wtmpbuff=(uint8_t*)alloca(bsize); + } + while(d->read_started || d->write_started){ + if (d->sound_err==0){ + if (d->write_started){ +#if 0 + if (d->stat_output>0 && d->buffer_playing==0) + { + ms_error("No data currently playing in sound card" ); + } + if (d->stat_output>0 && (d->stat_input-d->stat_output>10 || d->stat_input-d->stat_output<-10)) + ms_error("Not perfectly synchronized (input-output=%i)", d->stat_input-d->stat_output); +#endif + + while (d->buffer_playing<6 && d->buffer_playingmutex); + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + ms_mutex_unlock(&d->mutex); + if (err!=bsize) + break; + + ms_mutex_lock(&d->mutex); + /* write to sound devide! */ + memcpy (d->waveouthdr[pos_whdr].lpData, wtmpbuff, bsize); + + mr = waveOutWrite (d->waveoutdev, + &(d->waveouthdr[pos_whdr]), + sizeof (d->waveouthdr[pos_whdr])); + + if (mr != MMSYSERR_NOERROR) + { + if (mr == WAVERR_STILLPLAYING) + { + /* retry later */ + /* data should go back to queue */ + /* TODO */ + ms_warning("sound device write STILL_PLAYING (waveOutWrite:0x%i)", mr); + } + else + { + ms_warning("sound device write returned (waveOutWrite:0x%i)", mr); + } + } + else + { + d->buffer_playing++; + pos_whdr++; + if (pos_whdr == MAX_WAVEHDR) + pos_whdr = 0; /* loop over the prepared blocks */ + } + ms_mutex_unlock(&d->mutex); + + + if (err<0){ +#if !defined(_WIN32_WCE) + ms_warning("Fail to write %i bytes from soundcard: %s", + bsize,strerror(errno)); +#else + ms_warning("Fail to write %i bytes from soundcard: %i", + bsize,WSAGetLastError()); +#endif + } + } + + if (d->buffer_playing==6 || d->buffer_playing==MAX_WAVEHDR) + { + int discarded=0; + ms_mutex_lock(&d->mutex); + while (d->bufferizer->size>=bsize){ + discarded++; + d->stat_notplayed++; + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + } + ms_mutex_unlock(&d->mutex); + if (discarded>0) + ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20*320)/320, d->buffer_playing, d->stat_input - d->stat_output); + } +#if !defined(_WIN32_WCE) + Sleep(5); +#endif +#if defined(_WIN32_WCE) + Sleep(10); +#endif + }else { + int discarded=0; + /* don't think this is usefull, anyway... */ + ms_mutex_lock(&d->mutex); + while (d->bufferizer->size>=bsize){ + discarded++; + err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize); + } + ms_mutex_unlock(&d->mutex); + if (discarded>0) + ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20)/320, d->buffer_playing, d->stat_input - d->stat_output); + Sleep(10); + } + }else Sleep(10); + } + if (d->sound_err==0) { + int i; + int count=0; + /* close sound card */ + ms_error("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->buffer_playing, d->stat_input - d->stat_output, d->stat_notplayed); + + /* unprepare buffer */ + for (i = 0; i < MAX_WAVEHDR; i++) + { + int counttry=0; + for (counttry=0;counttry<10;counttry++) + { + mr = waveInUnprepareHeader (d->waveindev, + &(d->waveinhdr[i]), + sizeof (d->waveinhdr[i])); + if (mr != MMSYSERR_NOERROR) + { + ms_error("Failed to unprepared %i buffer from sound card (waveInUnprepareHeader:0x%i", count, mr); + Sleep (20); + } else + { + count++; + ms_message("successfully unprepared %i buffer from sound card.", count); + break; + } + } + } + ms_warning("unprepared %i buffer from sound card.", count); + + mr = waveInStop (d->waveindev); + if (mr != MMSYSERR_NOERROR) + { + ms_error("failed to stop recording sound card (waveInStop:0x%i)", mr); + } else + { + ms_message("successfully stopped recording sound card"); + } + + mr = waveInReset (d->waveindev); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("failed to reset recording sound card (waveInReset:0x%i)", mr); + } else + { + ms_message("successful reset of recording sound card"); + } + + mr = waveInClose (d->waveindev); + if (mr != MMSYSERR_NOERROR) + { + ms_warning("failed to close recording sound card (waveInClose:0x%i)", mr); + } else + { + ms_message("successfully closed recording sound card"); + } + d->sound_err=-1; + } + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + return NULL; +} + +static void winsnd_start_r(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + if (d->read_started==FALSE && d->write_started==FALSE){ + d->read_started=TRUE; + ms_thread_create(&d->thread,NULL,winsnd_thread,card); + }else d->read_started=TRUE; +} + +static void winsnd_stop_r(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + d->read_started=FALSE; + if (d->write_started==FALSE){ + ms_thread_join(d->thread,NULL); + } +} + +static void winsnd_start_w(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + if (d->read_started==FALSE && d->write_started==FALSE){ + d->write_started=TRUE; + ms_thread_create(&d->thread,NULL,winsnd_thread,card); + }else{ + d->write_started=TRUE; + } +} + +static void winsnd_stop_w(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + d->write_started=FALSE; + if (d->read_started==FALSE){ + ms_thread_join(d->thread,NULL); + } +#ifdef CONTROLVOLUME + waveOutSetVolume(d->waveoutdev, d->dwOldVolume); +#endif +} + +static mblk_t *winsnd_get(MSSndCard *card){ + WinSndData *d=(WinSndData*)card->data; + mblk_t *m; + ms_mutex_lock(&d->mutex); + m=getq(&d->rq); + ms_mutex_unlock(&d->mutex); + return m; +} + +static void winsnd_put(MSSndCard *card, mblk_t *m){ + WinSndData *d=(WinSndData*)card->data; + ms_mutex_lock(&d->mutex); + ms_bufferizer_put(d->bufferizer,m); + ms_mutex_unlock(&d->mutex); +} + + +static void winsnd_read_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + winsnd_start_r(card); + ms_ticker_set_time_func(f->ticker,winsnd_get_cur_time,card->data); +} + +static void winsnd_read_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + ms_ticker_set_time_func(f->ticker,NULL,NULL); + winsnd_stop_r(card); +} + +static void winsnd_read_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + while((m=winsnd_get(card))!=NULL){ + ms_queue_put(f->outputs[0],m); + } +} + +static void winsnd_write_preprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + winsnd_start_w(card); +} + +static void winsnd_write_postprocess(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + winsnd_stop_w(card); +} + +static void winsnd_write_process(MSFilter *f){ + MSSndCard *card=(MSSndCard*)f->data; + mblk_t *m; + + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + winsnd_put(card,m); + } +} + +static int set_rate(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + WinSndData *d=(WinSndData*)card->data; + d->rate=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + WinSndData *d=(WinSndData*)card->data; + d->stereo=(*((int*)arg)==2); + return 0; +} + +static int winsnd_get_stat_input(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + WinSndData *d=(WinSndData*)card->data; + + return d->stat_input; +} + +static int winsnd_get_stat_ouptut(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + WinSndData *d=(WinSndData*)card->data; + + return d->stat_output; +} + +static int winsnd_get_stat_discarded(MSFilter *f, void *arg){ + MSSndCard *card=(MSSndCard*)f->data; + WinSndData *d=(WinSndData*)card->data; + + return d->stat_notplayed; +} + +static MSFilterMethod winsnd_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { MS_FILTER_GET_STAT_INPUT, winsnd_get_stat_input }, + { MS_FILTER_GET_STAT_OUTPUT, winsnd_get_stat_ouptut }, + { MS_FILTER_GET_STAT_DISCARDED, winsnd_get_stat_discarded }, + { 0 , NULL } +}; + +MSFilterDesc winsnd_read_desc={ + MS_WINSND_READ_ID, + "MSWinSndRead", + "Sound capture filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 0, + 1, + NULL, + winsnd_read_preprocess, + winsnd_read_process, + winsnd_read_postprocess, + NULL, + winsnd_methods +}; + + +MSFilterDesc winsnd_write_desc={ + MS_WINSND_WRITE_ID, + "MSWinSndWrite", + "Sound playback filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 1, + 0, + NULL, + winsnd_write_preprocess, + winsnd_write_process, + winsnd_write_postprocess, + NULL, + winsnd_methods +}; + +MSFilter *ms_winsnd_read_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsnd_read_desc); + f->data=card; + return f; +} + + +MSFilter *ms_winsnd_write_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsnd_write_desc); + f->data=card; + return f; +} + +MS_FILTER_DESC_EXPORT(winsnd_read_desc) +MS_FILTER_DESC_EXPORT(winsnd_write_desc) diff --git a/linphone/mediastreamer2/src/winsnd2.c b/linphone/mediastreamer2/src/winsnd2.c new file mode 100755 index 000000000..f6eb242a6 --- /dev/null +++ b/linphone/mediastreamer2/src/winsnd2.c @@ -0,0 +1,852 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" + +#include +#ifdef _MSC_VER +#include +#endif +#include + +#if defined(_WIN32_WCE) +//#define DISABLE_SPEEX +//#define WCE_OPTICON_WORKAROUND 1000 +#endif +#ifndef DISABLE_SPEEX +#include +#endif + +#define WINSND_NBUFS 10 +#define WINSND_OUT_NBUFS 20 +#define WINSND_NSAMPLES 320 +#define WINSND_MINIMUMBUFFER 5 + +static MSFilter *ms_winsnd_read_new(MSSndCard *card); +static MSFilter *ms_winsnd_write_new(MSSndCard *card); + +typedef struct WinSndCard{ + int in_devid; + int out_devid; +}WinSndCard; + +static void winsndcard_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent){ + MMRESULT mr = MMSYSERR_NOERROR; + DWORD dwVolume = 0xFFFF; + dwVolume = ((0xFFFF) * percent) / 100; + + switch(e){ + case MS_SND_CARD_MASTER: + /*mr = waveOutSetVolume(d->waveoutdev, dwVolume); */ + if (mr != MMSYSERR_NOERROR) + { + ms_warning("Failed to set master volume. (waveOutSetVolume:0x%i)", mr); + return; + } + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("winsnd_card_set_level: unsupported command."); + } +} + +static int winsndcard_get_level(MSSndCard *card, MSSndCardMixerElem e){ + switch(e){ + case MS_SND_CARD_MASTER: + /*mr=waveOutGetVolume(d->waveoutdev, &dwVolume);*/ + /* Transform to 0 to 100 scale*/ + /*dwVolume = (dwVolume *100) / (0xFFFF);*/ + return 60; + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("winsnd_card_get_level: unsupported command."); + return -1; + } + return -1; +} + +static void winsndcard_set_source(MSSndCard *card, MSSndCardCapture source){ + + switch(source){ + case MS_SND_CARD_MIC: + break; + case MS_SND_CARD_LINE: + break; + } +} + +static void winsndcard_init(MSSndCard *card){ + WinSndCard *c=(WinSndCard *)ms_new(WinSndCard,1); + card->data=c; +} + +static void winsndcard_uninit(MSSndCard *card){ + ms_free(card->data); +} + +static void winsndcard_detect(MSSndCardManager *m); +static MSSndCard *winsndcard_dup(MSSndCard *obj); + +MSSndCardDesc winsnd_card_desc={ + "WINSND", + winsndcard_detect, + winsndcard_init, + winsndcard_set_level, + winsndcard_get_level, + winsndcard_set_source, + ms_winsnd_read_new, + ms_winsnd_write_new, + winsndcard_uninit, + winsndcard_dup +}; + +static MSSndCard *winsndcard_dup(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&winsnd_card_desc); + card->name=ms_strdup(obj->name); + card->data=ms_new(WinSndCard,1); + memcpy(card->data,obj->data,sizeof(WinSndCard)); + return card; +} + +static MSSndCard *winsndcard_new(const char *name, int in_dev, int out_dev, unsigned cap){ + MSSndCard *card=ms_snd_card_new(&winsnd_card_desc); + WinSndCard *d=(WinSndCard*)card->data; + card->name=ms_strdup(name); + d->in_devid=in_dev; + d->out_devid=out_dev; + card->capabilities=cap; + return card; +} + +static void add_or_update_card(MSSndCardManager *m, const char *name, int indev, int outdev, unsigned int capability){ + MSSndCard *card; + const MSList *elem=ms_snd_card_manager_get_list(m); + for(;elem!=NULL;elem=elem->next){ + card=(MSSndCard*)elem->data; + if (strcmp(card->name,name)==0){ + /*update already entered card */ + WinSndCard *d=(WinSndCard*)card->data; + card->capabilities|=capability; + if (indev!=-1) + d->in_devid=indev; + if (outdev!=-1) + d->out_devid=outdev; + + return; + } + } + /* add this new card:*/ + ms_snd_card_manager_add_card(m,winsndcard_new(name,indev,outdev,capability)); +} + +static void winsndcard_detect(MSSndCardManager *m){ + MMRESULT mr = NOERROR; + unsigned int nOutDevices = waveOutGetNumDevs (); + unsigned int nInDevices = waveInGetNumDevs (); + unsigned int item; + + if (nOutDevices>nInDevices) + nInDevices = nOutDevices; + + for (item = 0; item < nInDevices; item++){ + + WAVEINCAPS incaps; + WAVEOUTCAPS outcaps; + mr = waveInGetDevCaps (item, &incaps, sizeof (WAVEINCAPS)); + if (mr == MMSYSERR_NOERROR) + { +#if defined(_WIN32_WCE) + char card[256]; + snprintf(card, sizeof(card), "Input card %i", item); + add_or_update_card(m,card,item,-1,MS_SND_CARD_CAP_CAPTURE); + /* _tprintf(L"new card: %s", incaps.szPname); */ +#else + add_or_update_card(m,incaps.szPname,item,-1,MS_SND_CARD_CAP_CAPTURE); +#endif + } + mr = waveOutGetDevCaps (item, &outcaps, sizeof (WAVEOUTCAPS)); + if (mr == MMSYSERR_NOERROR) + { +#if defined(_WIN32_WCE) + char card[256]; + snprintf(card, sizeof(card), "Output card %i", item); + add_or_update_card(m,card,-1,item,MS_SND_CARD_CAP_PLAYBACK); + /* _tprintf(L"new card: %s", outcaps.szPname); */ +#else + add_or_update_card(m,outcaps.szPname,-1,item,MS_SND_CARD_CAP_PLAYBACK); +#endif + } + } +} + + +typedef struct WinSnd{ + int dev_id; + HWAVEIN indev; + HWAVEOUT outdev; + WAVEFORMATEX wfx; + WAVEHDR hdrs_read[WINSND_NBUFS]; + WAVEHDR hdrs_write[WINSND_OUT_NBUFS]; + queue_t rq; + ms_mutex_t mutex; + unsigned int bytes_read; + unsigned int nbufs_playing; + bool_t running; + + int32_t stat_input; + int32_t stat_output; + int32_t stat_notplayed; + + int32_t stat_minimumbuffer; + + queue_t write_rq; +#ifndef DISABLE_SPEEX + SpeexPreprocessState *pst; + int pst_frame_size; +#endif + int ready; + int workaround; /* workaround for opticon audio device */ +}WinSnd; + +static void winsnd_apply_settings(WinSnd *d){ + d->wfx.nBlockAlign=d->wfx.nChannels*d->wfx.wBitsPerSample/8; + d->wfx.nAvgBytesPerSec=d->wfx.nSamplesPerSec*d->wfx.nBlockAlign; +} + +static uint64_t winsnd_get_cur_time( void *data){ + WinSnd *d=(WinSnd*)data; + uint64_t curtime=((uint64_t)d->bytes_read*1000)/(uint64_t)d->wfx.nAvgBytesPerSec; + /* ms_debug("winsnd_get_cur_time: bytes_read=%u return %lu\n",d->bytes_read,(unsigned long)curtime); */ + return curtime; +} + + +static void winsnd_init(MSFilter *f){ + WinSnd *d=(WinSnd *)ms_new0(WinSnd,1); + d->wfx.wFormatTag = WAVE_FORMAT_PCM; + d->wfx.cbSize = 0; + d->wfx.nAvgBytesPerSec = 16000; + d->wfx.nBlockAlign = 2; + d->wfx.nChannels = 1; + d->wfx.nSamplesPerSec = 8000; + d->wfx.wBitsPerSample = 16; + qinit(&d->rq); + qinit(&d->write_rq); +#ifndef DISABLE_SPEEX + d->pst=NULL; + d->pst_frame_size=0; +#endif + d->ready=0; + d->workaround=0; + ms_mutex_init(&d->mutex,NULL); + f->data=d; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSND_MINIMUMBUFFER; +} + +static void winsnd_uninit(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + flushq(&d->rq,0); + flushq(&d->write_rq,0); +#ifndef DISABLE_SPEEX + if (d->pst!=NULL) + speex_preprocess_state_destroy(d->pst); + d->pst=NULL; + d->pst_frame_size=0; +#endif + d->ready=0; + d->workaround=0; + ms_mutex_destroy(&d->mutex); + ms_free(f->data); +} + +static void add_input_buffer(WinSnd *d, WAVEHDR *hdr, int buflen){ + mblk_t *m=allocb(buflen,0); + MMRESULT mr; + memset(hdr,0,sizeof(*hdr)); + if (buflen==0) ms_error("add_input_buffer: buflen=0 !"); + hdr->lpData=(LPSTR)m->b_wptr; + hdr->dwBufferLength=buflen; + hdr->dwFlags = 0; + hdr->dwUser = (DWORD)m; + mr = waveInPrepareHeader (d->indev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInPrepareHeader() error"); + return ; + } + mr=waveInAddBuffer(d->indev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInAddBuffer() error"); + return ; + } +} + +static void CALLBACK +read_callback (HWAVEIN waveindev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, + DWORD dwParam2) +{ + WAVEHDR *wHdr=(WAVEHDR *) dwParam1; + MSFilter *f=(MSFilter *)dwInstance; + WinSnd *d=(WinSnd*)f->data; + mblk_t *m; + int bsize; + switch (uMsg){ + case WIM_OPEN: + ms_debug("read_callback : WIM_OPEN"); + break; + case WIM_CLOSE: + ms_debug("read_callback : WIM_CLOSE"); + break; + case WIM_DATA: + bsize=wHdr->dwBytesRecorded; + if (bsize<=0) { +#if 0 + if (d->running==TRUE) /* avoid adding buffer back when calling waveInReset */ + { + MMRESULT mr; + mr=waveInAddBuffer(d->indev,wHdr,sizeof(*wHdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInAddBuffer() error"); + return ; + } + ms_warning("read_callback : EMPTY DATA, WIM_DATA (%p,%i)",wHdr,bsize); + } + m=(mblk_t*)wHdr->dwUser; + wHdr->dwUser=0; + freemsg(m); + return; +#endif + } + + /* ms_warning("read_callback : WIM_DATA (%p,%i)",wHdr,bsize); */ + m=(mblk_t*)wHdr->dwUser; + m->b_wptr+=bsize; + wHdr->dwUser=0; + ms_mutex_lock(&d->mutex); + putq(&d->rq,m); + ms_mutex_unlock(&d->mutex); + d->bytes_read+=wHdr->dwBufferLength; + d->stat_input++; + d->stat_input++; +#ifdef WIN32_TIMERS + if (f->ticker->TimeEvent!=NULL) + SetEvent(f->ticker->TimeEvent); +#endif + break; + } +} + + +static void winsnd_read_preprocess(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + MMRESULT mr; + int i; + int bsize; + DWORD dwFlag; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSND_MINIMUMBUFFER; + + winsnd_apply_settings(d); + /* Init Microphone device */ + dwFlag = CALLBACK_FUNCTION; + if (d->dev_id != WAVE_MAPPER) + dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION; + mr = waveInOpen (&d->indev, d->dev_id, &d->wfx, + (DWORD) read_callback, (DWORD)f, dwFlag); + if (mr != MMSYSERR_NOERROR) + { + ms_error("Failed to prepare windows sound device. (waveInOpen:0x%i)", mr); + mr = waveInOpen (&d->indev, WAVE_MAPPER, &d->wfx, + (DWORD) read_callback, (DWORD)d, CALLBACK_FUNCTION); + if (mr != MMSYSERR_NOERROR) + { + d->indev=NULL; + ms_error("Failed to prepare windows sound device. (waveInOpen:0x%i)", mr); + return ; + } + } + bsize=WINSND_NSAMPLES*d->wfx.nAvgBytesPerSec/8000; + ms_debug("Using input buffers of %i bytes",bsize); + for(i=0;ihdrs_read[i]; + add_input_buffer(d,hdr,bsize); + } + d->running=TRUE; + mr=waveInStart(d->indev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInStart() error"); + return ; + } + ms_ticker_set_time_func(f->ticker,winsnd_get_cur_time,d); +} + +static void winsnd_read_postprocess(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + MMRESULT mr; + int i; + ms_ticker_set_time_func(f->ticker,NULL,NULL); + d->running=FALSE; + mr=waveInStop(d->indev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInStop() error"); + return ; + } + mr=waveInReset(d->indev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInReset() error"); + return ; + } + for(i=0;ihdrs_read[i]; + if (hdr->dwFlags & WHDR_PREPARED) + { + mr = waveInUnprepareHeader(d->indev,hdr,sizeof (*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInUnPrepareHeader() error"); + } + } + } + mr = waveInClose(d->indev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveInClose() error"); + return ; + } + + ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed); + flushq(&d->rq,0); +} + +static void winsnd_read_process(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + mblk_t *m; + int i; + ms_mutex_lock(&d->mutex); + while((m=getq(&d->rq))!=NULL){ + ms_queue_put(f->outputs[0],m); + } + ms_mutex_unlock(&d->mutex); + for(i=0;ihdrs_read[i]; + if (hdr->dwUser==0) { + MMRESULT mr; + mr=waveInUnprepareHeader(d->indev,hdr,sizeof(*hdr)); + if (mr!=MMSYSERR_NOERROR) + ms_warning("winsnd_read_process: Fail to unprepare header!"); + add_input_buffer(d,hdr,hdr->dwBufferLength); + } + } +} + +static void CALLBACK +write_callback(HWAVEOUT outdev, UINT uMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) +{ + WAVEHDR *hdr=(WAVEHDR *) dwParam1; + WinSnd *d=(WinSnd*)dwInstance; + + switch (uMsg){ + case WOM_OPEN: + break; + case WOM_CLOSE: + case WOM_DONE: + if (hdr){ + d->nbufs_playing--; + } + if (d->stat_output==0) + { + d->stat_input=1; /* reset */ + d->stat_notplayed=0; + } + d->stat_output++; + break; + } +} + +static void winsnd_write_preprocess(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + MMRESULT mr; + DWORD dwFlag; + int i; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSND_MINIMUMBUFFER; + + winsnd_apply_settings(d); + /* Init Microphone device */ + dwFlag = CALLBACK_FUNCTION; + if (d->dev_id != WAVE_MAPPER) + dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION; + mr = waveOutOpen (&d->outdev, d->dev_id, &d->wfx, + (DWORD) write_callback, (DWORD)d, dwFlag); + if (mr != MMSYSERR_NOERROR) + { + ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr); + mr = waveOutOpen (&d->outdev, WAVE_MAPPER, &d->wfx, + (DWORD) write_callback, (DWORD)d, CALLBACK_FUNCTION); + if (mr != MMSYSERR_NOERROR) + { + ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr); + d->outdev=NULL; + return ; + } + } + for(i=0;ihdrs_write[i]; + hdr->dwFlags=0; + hdr->dwUser=0; + } +} + +static void winsnd_write_postprocess(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + MMRESULT mr; + int i; + if (d->outdev==NULL) return; + mr=waveOutReset(d->outdev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutReset() error"); + return ; + } + for(i=0;ihdrs_write[i]; + mblk_t *old; + if (hdr->dwFlags & WHDR_DONE){ + mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutUnprepareHeader error"); + } + old=(mblk_t*)hdr->dwUser; + if (old) freemsg(old); + hdr->dwUser=0; + } + } + mr=waveOutClose(d->outdev); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutClose() error"); + return ; + } + ms_message("Shutting down sound device (playing: %i) (d->write_rq.q_mcount=%i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->write_rq.q_mcount, d->stat_input - d->stat_output, d->stat_notplayed); + flushq(&d->write_rq,0); + d->ready=0; + d->workaround=0; + +#ifndef DISABLE_SPEEX + if (d->pst!=NULL) + speex_preprocess_state_destroy(d->pst); + d->pst=NULL; + d->pst_frame_size=0; +#endif +} + +static void winsnd_write_process(MSFilter *f){ + WinSnd *d=(WinSnd*)f->data; + mblk_t *m,*old; + MMRESULT mr; + int i; + int discarded=0; + int possible_size=0; + + if (d->outdev==NULL) { + ms_queue_flush(f->inputs[0]); + return; + } + + while((m=ms_queue_get(f->inputs[0]))!=NULL){ + possible_size = msgdsize(m); +#ifndef DISABLE_SPEEX + if (d->pst_frame_size==0) + { + d->pst_frame_size=possible_size; + + d->pst = speex_preprocess_state_init(d->pst_frame_size/2, d->wfx.nSamplesPerSec); + if (d->pst!=NULL) { + float f; + i=1; + speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_VAD, &i); + i=0; + speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=0; + speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_AGC, &i); + f=8000; + speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f); + i=0; + speex_preprocess_ctl(d->pst, SPEEX_PREPROCESS_SET_DEREVERB, &i); + } + } +#endif + + putq(&d->write_rq,m); + } + +#ifdef AMD_HACK + /* too many sound card are crappy on windows... */ + d->stat_minimumbuffer=15; + if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */ + d->stat_minimumbuffer=8; +#endif + + if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */ + { + if (d->nbufs_playing+d->write_rq.q_mcount<4) + { + d->ready=0; + } + } + else + { + if (d->nbufs_playing+d->write_rq.q_mcount<7) + { + d->ready=0; + } + } +#if defined(WCE_OPTICON_WORKAROUND) + if (d->workaround==0) + { + d->workaround=1; + Sleep(WCE_OPTICON_WORKAROUND); + } +#endif + + while((m=peekq(&d->write_rq))!=NULL){ + +#ifndef DISABLE_SPEEX + int vad=1; + if (d->pst!=NULL && msgdsize(m)==d->pst_frame_size && d->pst_frame_size<=4096) + { + char tmp[4096]; + memcpy(tmp, m->b_rptr, msgdsize(m)); + vad = speex_preprocess(d->pst, (short*)tmp, NULL); + + if (d->ready==0) + { + if (vad==0) + { + int missing; + missing = 10 - d->write_rq.q_mcount - d->nbufs_playing; + if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */ + missing = 6 - d->write_rq.q_mcount - d->nbufs_playing; + + ms_message("WINSND trouble: inserting %i silence", missing); + while(missing>0) + { + old=dupb(m); + putq(&d->write_rq,old); + missing--; + } + } + d->ready=1; + } + } +#else + if (d->ready==0) + { + int missing; + missing = 10 - d->write_rq.q_mcount - d->nbufs_playing; + if (d->wfx.nSamplesPerSec>=32000) /* better results for high rates */ + missing = 6 - d->write_rq.q_mcount - d->nbufs_playing; + ms_message("WINSND trouble: inserting %i silence", missing); + while(missing>0) + { + old=dupb(m); + putq(&d->write_rq,old); + missing--; + } + d->ready=1; + } +#endif + + for(i=0;istat_minimumbuffer;++i){ + WAVEHDR *hdr=&d->hdrs_write[i]; + if (hdr->dwFlags & WHDR_DONE){ + old=(mblk_t*)hdr->dwUser; + mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutUnprepareHeader error"); + } + freemsg(old); + hdr->dwUser=0; + } + if (hdr->dwUser==0){ + hdr->lpData=(LPSTR)m->b_rptr; + hdr->dwBufferLength=msgdsize(m); + hdr->dwFlags = 0; + hdr->dwUser = (DWORD)m; + mr = waveOutPrepareHeader(d->outdev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutPrepareHeader() error"); + getq(&d->write_rq); + freemsg(m); + discarded++; + d->stat_notplayed++; + break; + } + mr=waveOutWrite(d->outdev,hdr,sizeof(*hdr)); + if (mr != MMSYSERR_NOERROR){ + ms_error("waveOutWrite() error"); + getq(&d->write_rq); + freemsg(m); + discarded++; + d->stat_notplayed++; + break; + }else { + getq(&d->write_rq); + d->nbufs_playing++; + /* ms_debug("waveOutWrite() done"); */ + } + break; + } + } + if (i==d->stat_minimumbuffer){ + //ms_error("winsnd_write_process: All buffers are busy."); +#ifndef DISABLE_SPEEX + if (d->pst==NULL) + { + /* initial behavior (detection in process?) */ + getq(&d->write_rq); + freemsg(m); + } + else + { + if (vad==0) + { + getq(&d->write_rq); + freemsg(m); + ms_message("WINSND trouble: silence removed"); + } + } +#else + getq(&d->write_rq); + freemsg(m); +#endif + + discarded++; + d->stat_notplayed++; + + break; + } + } +} + +static int set_rate(MSFilter *f, void *arg){ + WinSnd *d=(WinSnd*)f->data; + d->wfx.nSamplesPerSec=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + WinSnd *d=(WinSnd*)f->data; + d->wfx.nChannels=*((int*)arg); + return 0; +} + +static int winsnd_get_stat_input(MSFilter *f, void *arg){ + WinSnd *d=(WinSnd*)f->data; + return d->stat_input; +} + +static int winsnd_get_stat_ouptut(MSFilter *f, void *arg){ + WinSnd *d=(WinSnd*)f->data; + + return d->stat_output; +} + +static int winsnd_get_stat_discarded(MSFilter *f, void *arg){ + WinSnd *d=(WinSnd*)f->data; + + return d->stat_notplayed; +} + +static MSFilterMethod winsnd_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { MS_FILTER_GET_STAT_INPUT, winsnd_get_stat_input }, + { MS_FILTER_GET_STAT_OUTPUT, winsnd_get_stat_ouptut }, + { MS_FILTER_GET_STAT_DISCARDED, winsnd_get_stat_discarded }, + { 0 , NULL } +}; + +MSFilterDesc winsnd_read_desc={ + MS_WINSND_READ_ID, + "MSWinSndRead", + "Sound capture filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 0, + 1, + winsnd_init, + winsnd_read_preprocess, + winsnd_read_process, + winsnd_read_postprocess, + winsnd_uninit, + winsnd_methods +}; + + +MSFilterDesc winsnd_write_desc={ + MS_WINSND_WRITE_ID, + "MSWinSndWrite", + "Sound playback filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 1, + 0, + winsnd_init, + winsnd_write_preprocess, + winsnd_write_process, + winsnd_write_postprocess, + winsnd_uninit, + winsnd_methods +}; + +MSFilter *ms_winsnd_read_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsnd_read_desc); + WinSndCard *wc=(WinSndCard*)card->data; + WinSnd *d=(WinSnd*)f->data; + d->dev_id=wc->in_devid; + return f; +} + + +MSFilter *ms_winsnd_write_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsnd_write_desc); + WinSndCard *wc=(WinSndCard*)card->data; + WinSnd *d=(WinSnd*)f->data; + d->dev_id=wc->out_devid; + return f; +} + +MS_FILTER_DESC_EXPORT(winsnd_read_desc) +MS_FILTER_DESC_EXPORT(winsnd_write_desc) diff --git a/linphone/mediastreamer2/src/winsndds.cpp b/linphone/mediastreamer2/src/winsndds.cpp new file mode 100644 index 000000000..e5bf576e8 --- /dev/null +++ b/linphone/mediastreamer2/src/winsndds.cpp @@ -0,0 +1,845 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef __DIRECTSOUND_ENABLED__ + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" + +#include +#ifdef _MSC_VER +#include +#endif +#include + +#include + +#define WINSNDDS_NBUFS 10 +#define WINSNDDS_NSAMPLES 160 +#define WINSNDDS_MINIMUMBUFFER 5 + +static MSFilter *ms_winsndds_read_new(MSSndCard *card); +static MSFilter *ms_winsndds_write_new(MSSndCard *card); + +static HMODULE ms_lib_instance=NULL; +static HRESULT (WINAPI *ms_DllGetClassObject)(REFCLSID , REFIID , LPVOID *); + +static HRESULT (WINAPI *ms_DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); +static HRESULT (WINAPI *ms_DirectSoundEnumerate)(LPDSENUMCALLBACKA, LPVOID); + +static HRESULT (WINAPI *ms_DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); +static HRESULT (WINAPI *ms_DirectSoundCaptureEnumerate)(LPDSENUMCALLBACKA, LPVOID); + +typedef struct WinSndDsCard{ + int in_devid; + int out_devid; + GUID in_guid; + GUID out_guid; +}WinSndDsCard; + + +static void winsnddscard_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent){ + MMRESULT mr = MMSYSERR_NOERROR; + DWORD dwVolume = 0xFFFF; + dwVolume = ((0xFFFF) * percent) / 100; + + switch(e){ + case MS_SND_CARD_MASTER: + /*mr = waveOutSetVolume(d->waveoutdev, dwVolume); */ + if (mr != MMSYSERR_NOERROR) + { + ms_warning("Failed to set master volume. (waveOutSetVolume:0x%i)", mr); + return; + } + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("winsndds_card_set_level: unsupported command."); + } +} + +static int winsnddscard_get_level(MSSndCard *card, MSSndCardMixerElem e){ + switch(e){ + case MS_SND_CARD_MASTER: + /*mr=waveOutGetVolume(d->waveoutdev, &dwVolume);*/ + /* Transform to 0 to 100 scale*/ + /*dwVolume = (dwVolume *100) / (0xFFFF);*/ + return 60; + break; + case MS_SND_CARD_CAPTURE: + break; + case MS_SND_CARD_PLAYBACK: + break; + default: + ms_warning("winsndds_card_get_level: unsupported command."); + return -1; + } + return -1; +} + +static void winsnddscard_set_source(MSSndCard *card, MSSndCardCapture source){ + + switch(source){ + case MS_SND_CARD_MIC: + break; + case MS_SND_CARD_LINE: + break; + } +} + +static void winsnddscard_init(MSSndCard *card){ + WinSndDsCard *c=(WinSndDsCard *)ms_new(WinSndDsCard,1); + card->data=c; +} + +static void winsnddscard_uninit(MSSndCard *card){ + ms_free(card->data); +} + +static void winsnddscard_detect(MSSndCardManager *m); +static MSSndCard *winsnddscard_dup(MSSndCard *obj); + +MSSndCardDesc winsndds_card_desc={ + "WINSNDDS", + winsnddscard_detect, + winsnddscard_init, + winsnddscard_set_level, + winsnddscard_get_level, + winsnddscard_set_source, + ms_winsndds_read_new, + ms_winsndds_write_new, + winsnddscard_uninit, + winsnddscard_dup +}; + +static MSSndCard *winsnddscard_dup(MSSndCard *obj){ + MSSndCard *card=ms_snd_card_new(&winsndds_card_desc); + card->name=ms_strdup(obj->name); + card->data=ms_new(WinSndDsCard,1); + memcpy(card->data,obj->data,sizeof(WinSndDsCard)); + return card; +} + +static MSSndCard *winsnddscard_new(const char *name, LPGUID lpguid, int in_dev, int out_dev, unsigned cap){ + MSSndCard *card=ms_snd_card_new(&winsndds_card_desc); + WinSndDsCard *d=(WinSndDsCard*)card->data; + card->name=ms_strdup(name); + d->in_devid=in_dev; + d->out_devid=out_dev; + card->capabilities=cap; + if (out_dev!=-1) + { + if (lpguid!=NULL) + memcpy(&d->out_guid, lpguid, sizeof(GUID)); + else + memset(&d->out_guid, 0, sizeof(GUID)); + } + else + { + if (lpguid!=NULL) + memcpy(&d->in_guid, lpguid, sizeof(GUID)); + else + memset(&d->in_guid, 0, sizeof(GUID)); + } + return card; +} + +static void add_or_update_card(MSSndCardManager *m, const char *name, LPGUID lpguid, int indev, int outdev, unsigned int capability){ + MSSndCard *card; + const MSList *elem=ms_snd_card_manager_get_list(m); + for(;elem!=NULL;elem=elem->next){ + card=(MSSndCard*)elem->data; + if (strcmp(card->name,name)==0){ + /*update already entered card */ + WinSndDsCard *d=(WinSndDsCard*)card->data; + card->capabilities|=capability; + if (indev!=-1) + d->in_devid=indev; + if (outdev!=-1) + d->out_devid=outdev; + + if (outdev!=-1) + { + if (lpguid!=NULL) + memcpy(&d->out_guid, lpguid, sizeof(GUID)); + else + memset(&d->out_guid, 0, sizeof(GUID)); + } + if (indev!=-1) + { + if (lpguid!=NULL) + memcpy(&d->in_guid, lpguid, sizeof(GUID)); + else + memset(&d->in_guid, 0, sizeof(GUID)); + } + return; + } + } + /* add this new card:*/ + ms_snd_card_manager_add_card(m,winsnddscard_new(name,lpguid, indev,outdev,capability)); +} + +static BOOL CALLBACK enumerate_capture_devices_callback(LPGUID lpGUID, + LPCTSTR lpszDesc, + LPCTSTR lpszDrvName, + LPVOID lpContext ) +{ + MSSndCardManager *m = (MSSndCardManager*)lpContext; + static int dev_index=0; + + if ( lpGUID == NULL ) /* primary device */ + { + char snd_card_name[256]; + snprintf(snd_card_name, 256, "ds: %s", lpszDesc); + add_or_update_card(m,snd_card_name,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE); + dev_index++; + } + else + { + char snd_card_name[256]; + snprintf(snd_card_name, 256, "ds: %s", lpszDesc); + add_or_update_card(m,snd_card_name,lpGUID,dev_index,-1,MS_SND_CARD_CAP_CAPTURE); + dev_index++; + } + + return true; +} + +static BOOL CALLBACK enumerate_playback_devices_callback(LPGUID lpGUID, + LPCTSTR lpszDesc, + LPCTSTR lpszDrvName, + LPVOID lpContext ) +{ + MSSndCardManager *m = (MSSndCardManager*)lpContext; + static int dev_index=0; + + if ( lpGUID == NULL ) /* primary device */ + { + char snd_card_name[256]; + snprintf(snd_card_name, 256, "ds: %s", lpszDesc); + + add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK); + dev_index++; + } + else + { + char snd_card_name[256]; + snprintf(snd_card_name, 256, "ds: %s", lpszDesc); + + add_or_update_card(m,snd_card_name,lpGUID,-1,dev_index,MS_SND_CARD_CAP_PLAYBACK); + dev_index++; + } + + return true; +} + +static void winsnddscard_detect(MSSndCardManager *m){ + MMRESULT mr = NOERROR; + + if (ms_lib_instance==NULL) + { + ms_lib_instance = LoadLibrary("dsound.dll"); + if( ms_lib_instance == NULL ) + { + /* error */ + ms_debug("winsnddscard_init: no support for dsound (missing dsound.dll)\n"); + return; + } + + ms_DllGetClassObject =(HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *)) + GetProcAddress( ms_lib_instance, "DllGetClassObject" ); + + ms_DirectSoundCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)) + GetProcAddress( ms_lib_instance, "DirectSoundCreate" ); + + ms_DirectSoundEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) + GetProcAddress( ms_lib_instance, "DirectSoundEnumerateA" ); + + ms_DirectSoundCaptureCreate =(HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN)) + GetProcAddress( ms_lib_instance, "DirectSoundCaptureCreate" ); + + ms_DirectSoundCaptureEnumerate =(HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) + GetProcAddress( ms_lib_instance, "DirectSoundCaptureEnumerateA" ); + + if( ms_DllGetClassObject == NULL || + ms_DirectSoundCreate == NULL || + ms_DirectSoundEnumerate == NULL || + ms_DirectSoundCaptureEnumerate == NULL || + ms_DirectSoundCaptureCreate == NULL ) + { + /* error */ + ms_debug("winsnddscard_init: no support for dsound\n"); + return; + } + } + + ms_DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)enumerate_capture_devices_callback, (void *)m ); + ms_DirectSoundEnumerate( (LPDSENUMCALLBACK)enumerate_playback_devices_callback, (void *)m ); +} + + +typedef struct WinSndDs{ + int dev_id; + GUID in_guid; + GUID out_guid; + + ms_thread_t thread; + ms_mutex_t thread_lock; + ms_cond_t thread_cond; + bool_t thread_running; + + MSBufferizer output_buff; + LPDIRECTSOUND lpDirectSound; + LPDIRECTSOUNDBUFFER lpDirectSoundOutputBuffer; + DWORD outputBufferWriteOffsetBytes; /* last write position */ + double dsw_framesWritten; + + LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; + LPDIRECTSOUNDCAPTUREBUFFER lpDirectSoundInputBuffer; + UINT readOffset; /* last read position */ + UINT inputSize; + + int framesPerDSBuffer; + + WAVEFORMATEX wfx; + queue_t rq; + ms_mutex_t mutex; + unsigned int bytes_read; + unsigned int nbufs_playing; + + int32_t stat_input; + int32_t stat_output; + int32_t stat_notplayed; + + int32_t stat_minimumbuffer; +}WinSndDs; + +void * +winsndds_read_thread(void *arg) +{ + WinSndDs *d=(WinSndDs*)arg; + + ms_mutex_lock(&d->thread_lock); + ms_cond_signal(&d->thread_cond); + ms_mutex_unlock(&d->thread_lock); + + while(d->thread_running) + { + HRESULT hr; + DWORD capturePos; + DWORD readPos; + long filled = 0; + long bytesFilled = 0; + LPBYTE lpInBuf1 = NULL; + LPBYTE lpInBuf2 = NULL; + DWORD dwInSize1 = 0; + DWORD dwInSize2 = 0; + + hr = IDirectSoundCaptureBuffer_GetCurrentPosition( d->lpDirectSoundInputBuffer, + &capturePos, &readPos ); + if( hr != DS_OK ) + { + continue; + } + + filled = readPos - d->readOffset; + if( filled < 0 ) filled += d->inputSize; // unwrap offset + bytesFilled = filled; + + hr = IDirectSoundCaptureBuffer_Lock ( d->lpDirectSoundInputBuffer, + d->readOffset, bytesFilled, + (void **) &lpInBuf1, &dwInSize1, + (void **) &lpInBuf2, &dwInSize2, 0); + if (hr != DS_OK) + { + Sleep(10); + continue; + } + + if (dwInSize1==0) + { + Sleep(10); + } + else if (dwInSize1>=bytesFilled) + { + mblk_t *m=allocb(bytesFilled,0); + memcpy(m->b_rptr, lpInBuf1, bytesFilled); + m->b_wptr+=bytesFilled; + ms_mutex_lock(&d->mutex); + putq(&d->rq,m); + ms_mutex_unlock(&d->mutex); + d->bytes_read+=bytesFilled; + } + else + { + mblk_t *m=allocb(bytesFilled,0); + memcpy(m->b_rptr, lpInBuf1, dwInSize1); + memcpy(m->b_rptr+dwInSize1, lpInBuf2, dwInSize2); + m->b_wptr+=bytesFilled; + ms_mutex_lock(&d->mutex); + putq(&d->rq,m); + ms_mutex_unlock(&d->mutex); + d->bytes_read+=bytesFilled; + } + + d->readOffset = (d->readOffset + bytesFilled) % d->inputSize; + + IDirectSoundCaptureBuffer_Unlock( d->lpDirectSoundInputBuffer, + lpInBuf1, dwInSize1, lpInBuf2, dwInSize2); + } + + ms_mutex_lock(&d->thread_lock); + ms_cond_signal(&d->thread_cond); + ms_mutex_unlock(&d->thread_lock); + ms_thread_exit(NULL); + return NULL; +} + +static void winsndds_apply_settings(WinSndDs *d){ + d->wfx.nBlockAlign=d->wfx.nChannels*d->wfx.wBitsPerSample/8; + d->wfx.nAvgBytesPerSec=d->wfx.nSamplesPerSec*d->wfx.nBlockAlign; +} + +static uint64_t winsndds_get_cur_time( void *data){ + WinSndDs *d=(WinSndDs*)data; + uint64_t curtime=((uint64_t)d->bytes_read*1000)/(uint64_t)d->wfx.nAvgBytesPerSec; + /* ms_debug("winsndds_get_cur_time: bytes_read=%u return %lu\n",d->bytes_read,(unsigned long)curtime); */ + return curtime; +} + + +static void winsndds_init(MSFilter *f){ + WinSndDs *d=(WinSndDs *)ms_new0(WinSndDs,1); + d->wfx.wFormatTag = WAVE_FORMAT_PCM; + d->wfx.cbSize = 0; + d->wfx.nAvgBytesPerSec = 16000; + d->wfx.nBlockAlign = 2; + d->wfx.nChannels = 1; + d->wfx.nSamplesPerSec = 8000; + d->wfx.wBitsPerSample = 16; + qinit(&d->rq); + ms_mutex_init(&d->mutex,NULL); + f->data=d; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER; + + d->framesPerDSBuffer = 4096*3; //320 * (8000 / 1000); + + d->thread = NULL; + ms_mutex_init(&d->thread_lock,NULL); + ms_cond_init(&d->thread_cond,NULL); + d->thread_running = FALSE; + + ms_bufferizer_init(&d->output_buff); +} + +static void winsndds_uninit(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + + d->thread = NULL; + d->thread_running = FALSE; + ms_cond_destroy(&d->thread_cond); + ms_mutex_destroy(&d->thread_lock); + ms_bufferizer_uninit(&d->output_buff); + + flushq(&d->rq,0); + ms_mutex_destroy(&d->mutex); + ms_free(f->data); +} + +static void winsndds_read_preprocess(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + DSCBUFFERDESC captureDesc; + HRESULT hr; + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER; + + winsndds_apply_settings(d); + ms_DirectSoundCaptureCreate( &d->in_guid, &d->lpDirectSoundCapture, NULL ); + + d->inputSize = d->framesPerDSBuffer * 1 * sizeof(short); + + ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC)); + captureDesc.dwSize = sizeof(DSCBUFFERDESC); + captureDesc.dwFlags = 0; + captureDesc.dwBufferBytes = d->framesPerDSBuffer * 1 * sizeof(short); //bytesPerBuffer; + captureDesc.lpwfxFormat = &d->wfx; + // Create the capture buffer + if ((hr = IDirectSoundCapture_CreateCaptureBuffer( d->lpDirectSoundCapture, + &captureDesc, &d->lpDirectSoundInputBuffer, NULL)) != DS_OK) + { + return; /* hr; */ + } + d->readOffset = 0; // reset last read position to start of buffer + + hr = IDirectSoundCaptureBuffer_Start( d->lpDirectSoundInputBuffer, DSCBSTART_LOOPING ); + + ms_ticker_set_time_func(f->ticker,winsndds_get_cur_time,d); + + d->thread_running=TRUE; + ms_thread_create(&d->thread,NULL,winsndds_read_thread,d); + ms_mutex_lock(&d->thread_lock); + ms_cond_wait(&d->thread_cond,&d->thread_lock); + ms_mutex_unlock(&d->thread_lock); + + return; /* DS_OK; */ +} + +static void winsndds_read_postprocess(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + + ms_mutex_lock(&d->thread_lock); + d->thread_running=FALSE; + ms_cond_wait(&d->thread_cond,&d->thread_lock); + ms_mutex_unlock(&d->thread_lock); + ms_thread_join(d->thread,NULL); + + ms_ticker_set_time_func(f->ticker,NULL,NULL); + + if( d->lpDirectSoundInputBuffer ) + { + IDirectSoundCaptureBuffer_Stop( d->lpDirectSoundInputBuffer ); + IDirectSoundCaptureBuffer_Release( d->lpDirectSoundInputBuffer ); + d->lpDirectSoundInputBuffer = NULL; + } + + if( d->lpDirectSoundCapture ) + { + IDirectSoundCapture_Release( d->lpDirectSoundCapture ); + d->lpDirectSoundCapture = NULL; + } + + ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed); + flushq(&d->rq,0); +} + +static void winsndds_read_process(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + mblk_t *m; + + ms_mutex_lock(&d->mutex); + while((m=getq(&d->rq))!=NULL){ + ms_queue_put(f->outputs[0],m); + } + ms_mutex_unlock(&d->mutex); +} + +static void winsndds_write_preprocess(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + + DWORD dwDataLen; + DWORD playCursor; + HWND hWnd; + HRESULT hr; + LPDIRECTSOUNDBUFFER pPrimaryBuffer; + DSBUFFERDESC primaryDesc; + DSBUFFERDESC secondaryDesc; + unsigned char* pDSBuffData; + + + d->stat_input=0; + d->stat_output=0; + d->stat_notplayed=0; + d->stat_minimumbuffer=WINSNDDS_MINIMUMBUFFER; + + winsndds_apply_settings(d); + + + ms_DirectSoundCreate( &d->out_guid, &d->lpDirectSound, NULL ); + + + hWnd = GetDesktopWindow(); + if ((hr = IDirectSound_SetCooperativeLevel( d->lpDirectSound, + hWnd, DSSCL_EXCLUSIVE)) != DS_OK) + { + return ; + } + + ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC)); + primaryDesc.dwSize = sizeof(DSBUFFERDESC); + primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth + primaryDesc.dwBufferBytes = 0; + primaryDesc.lpwfxFormat = NULL; + // Create the buffer + if ((hr = IDirectSound_CreateSoundBuffer( d->lpDirectSound, + &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) + { + return ;//hr; + } + + if ((hr = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &d->wfx)) != DS_OK) + { + return ;//hr; + } + + // Setup the secondary buffer description + ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC)); + secondaryDesc.dwSize = sizeof(DSBUFFERDESC); + secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; + secondaryDesc.dwBufferBytes = d->framesPerDSBuffer * 1 * sizeof(short); //bytesPerBuffer; + secondaryDesc.lpwfxFormat = &d->wfx; + // Create the secondary buffer + if ((hr = IDirectSound_CreateSoundBuffer( d->lpDirectSound, + &secondaryDesc, &d->lpDirectSoundOutputBuffer, NULL)) != DS_OK) + { + return ;//hr; + } + + // Lock the DS buffer + if ((hr = IDirectSoundBuffer_Lock( d->lpDirectSoundOutputBuffer, 0, + d->framesPerDSBuffer * 1 * sizeof(short), + (LPVOID*)&pDSBuffData, + &dwDataLen, NULL, 0, 0)) != DS_OK) + { + return ;//hr; + } + + // Zero the DS buffer + ZeroMemory(pDSBuffData, dwDataLen); + // Unlock the DS buffer + if ((hr = IDirectSoundBuffer_Unlock( d->lpDirectSoundOutputBuffer, + pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) + { + return ;//hr; + } + + // Let DSound set the starting write position because if we set it to zero, it looks like the + // buffer is full to begin with. This causes a long pause before sound starts when using large buffers. + hr = IDirectSoundBuffer_GetCurrentPosition( d->lpDirectSoundOutputBuffer, + &playCursor, &d->outputBufferWriteOffsetBytes ); + if( hr != DS_OK ) + { + return ;//hr; + } + + hr = IDirectSoundBuffer_SetCurrentPosition( d->lpDirectSoundOutputBuffer, 0 ); + if( hr != DS_OK ) + { + return ;//hr; + } + hr = IDirectSoundBuffer_Play( d->lpDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING); + if( hr != DS_OK ) + { + return ;//hr; + } + + return ;//hr; +} + +static void winsndds_write_postprocess(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + + if( d->lpDirectSoundOutputBuffer ) + { + IDirectSoundBuffer_Stop( d->lpDirectSoundOutputBuffer ); + IDirectSoundBuffer_Release( d->lpDirectSoundOutputBuffer ); + d->lpDirectSoundOutputBuffer = NULL; + } + + if( d->lpDirectSound ) + { + IDirectSound_Release( d->lpDirectSound ); + d->lpDirectSound = NULL; + } + + ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed); +} + +static void winsndds_write_process(MSFilter *f){ + WinSndDs *d=(WinSndDs*)f->data; + int discarded=0; + static int fillme=0; + + if (d->lpDirectSound==NULL) { + ms_queue_flush(f->inputs[0]); + return; + } + + ms_bufferizer_put_from_queue(&d->output_buff,f->inputs[0]); + + if (fillme==0) + { + if (ms_bufferizer_get_avail(&d->output_buff)>=4096*3) + { + fillme=1; + return; + } + return; + } + + int msize = 4096;// 1280; + while (ms_bufferizer_get_avail(&d->output_buff)>=msize) + { + LPBYTE lpOutBuf1 = NULL; + LPBYTE lpOutBuf2 = NULL; + DWORD dwOutSize1 = 0; + DWORD dwOutSize2 = 0; + HRESULT hr; + char input[4096]; + + hr = IDirectSoundBuffer_Lock ( d->lpDirectSoundOutputBuffer, + d->outputBufferWriteOffsetBytes, msize, //bytesToXfer, + (void **) &lpOutBuf1, &dwOutSize1, + (void **) &lpOutBuf2, &dwOutSize2, DSBLOCK_FROMWRITECURSOR); + if (hr != DS_OK) + { + ms_error("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n", hr); + continue; + } + + if (dwOutSize1==0) + { + ms_error("no free room to play sample\n"); + } + else if (dwOutSize1+dwOutSize2!=msize) + { + ms_bufferizer_read(&d->output_buff,(uint8_t*)input,dwOutSize1+dwOutSize2); + memcpy(lpOutBuf1, input, dwOutSize1); + memcpy(lpOutBuf2, input+dwOutSize1, dwOutSize2); + } + else if (dwOutSize1>=msize) + { + ms_bufferizer_read(&d->output_buff,(uint8_t*)input,msize); + memcpy(lpOutBuf1, input, msize); + } + else + { + ms_bufferizer_read(&d->output_buff,(uint8_t*)input,msize); + memcpy(lpOutBuf1, input, dwOutSize1); + memcpy(lpOutBuf2, input+dwOutSize1, dwOutSize2); + } + + IDirectSoundBuffer_Unlock( d->lpDirectSoundOutputBuffer, + lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2); + if (dwOutSize1==0) + break; + if (dwOutSize1+dwOutSize2!=msize) + break; + } + + if (discarded>0) + ms_warning("Extra data for sound card removed (%i buf), (playing: %i) (input-output: %i)", discarded, d->nbufs_playing, d->stat_input - d->stat_output); +} + +static int set_rate(MSFilter *f, void *arg){ + WinSndDs *d=(WinSndDs*)f->data; + d->wfx.nSamplesPerSec=*((int*)arg); + return 0; +} + +static int set_nchannels(MSFilter *f, void *arg){ + WinSndDs *d=(WinSndDs*)f->data; + d->wfx.nChannels=*((int*)arg); + return 0; +} + +static int winsndds_get_stat_input(MSFilter *f, void *arg){ + WinSndDs *d=(WinSndDs*)f->data; + return d->stat_input; +} + +static int winsndds_get_stat_ouptut(MSFilter *f, void *arg){ + WinSndDs *d=(WinSndDs*)f->data; + + return d->stat_output; +} + +static int winsndds_get_stat_discarded(MSFilter *f, void *arg){ + WinSndDs *d=(WinSndDs*)f->data; + + return d->stat_notplayed; +} + +static MSFilterMethod winsndds_methods[]={ + { MS_FILTER_SET_SAMPLE_RATE , set_rate }, + { MS_FILTER_SET_NCHANNELS , set_nchannels }, + { MS_FILTER_GET_STAT_INPUT, winsndds_get_stat_input }, + { MS_FILTER_GET_STAT_OUTPUT, winsndds_get_stat_ouptut }, + { MS_FILTER_GET_STAT_DISCARDED, winsndds_get_stat_discarded }, + { 0 , NULL } +}; + +MSFilterDesc winsndds_read_desc={ + MS_WINSNDDS_READ_ID, + "MSWinSndRead", + "Sound capture filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 0, + 1, + winsndds_init, + winsndds_read_preprocess, + winsndds_read_process, + winsndds_read_postprocess, + winsndds_uninit, + winsndds_methods +}; + + +MSFilterDesc winsndds_write_desc={ + MS_WINSNDDS_WRITE_ID, + "MSWinSndWrite", + "Sound playback filter for Windows Sound drivers", + MS_FILTER_OTHER, + NULL, + 1, + 0, + winsndds_init, + winsndds_write_preprocess, + winsndds_write_process, + winsndds_write_postprocess, + winsndds_uninit, + winsndds_methods +}; + +MSFilter *ms_winsndds_read_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsndds_read_desc); + WinSndDsCard *wc=(WinSndDsCard*)card->data; + WinSndDs *d=(WinSndDs*)f->data; + d->dev_id=wc->in_devid; + memcpy(&d->in_guid, &wc->in_guid, sizeof(GUID)); + memcpy(&d->out_guid, &wc->out_guid, sizeof(GUID)); + return f; +} + + +MSFilter *ms_winsndds_write_new(MSSndCard *card){ + MSFilter *f=ms_filter_new_from_desc(&winsndds_write_desc); + WinSndDsCard *wc=(WinSndDsCard*)card->data; + WinSndDs *d=(WinSndDs*)f->data; + d->dev_id=wc->out_devid; + memcpy(&d->in_guid, &wc->in_guid, sizeof(GUID)); + memcpy(&d->out_guid, &wc->out_guid, sizeof(GUID)); + return f; +} + +MS_FILTER_DESC_EXPORT(winsndds_read_desc) +MS_FILTER_DESC_EXPORT(winsndds_write_desc) + +#endif diff --git a/linphone/mediastreamer2/src/winvideo.c b/linphone/mediastreamer2/src/winvideo.c new file mode 100644 index 000000000..5cae8591a --- /dev/null +++ b/linphone/mediastreamer2/src/winvideo.c @@ -0,0 +1,637 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msv4l.h" +#include "Vfw.h" +#include +#include + +#include "nowebcam.h" +#include "mediastreamer2/mswebcam.h" + +#ifndef _MSC_VER +#include "vfw-missing.h" +#endif + +#define AMD_HACK2 + +typedef struct V4wState{ +#ifdef AMD_HACK2 + ms_thread_t thread; + ms_mutex_t thread_lock; + ms_cond_t thread_cond; + bool_t thread_running; +#endif + + char dev[512]; + int devidx; + HWND capvideo; + MSVideoSize vsize; + int pix_fmt; + mblk_t *mire[10]; + queue_t rq; + ms_mutex_t mutex; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + bool_t running; + bool_t startwith_yuv_bug; /* avoid bug with USB vimicro cards. */ + bool_t started; + bool_t autostarted; +}V4wState; + +static void dummy(void*p){ +} + +LRESULT CALLBACK VideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr) +{ + V4wState *s; + mblk_t *buf; + int size; + + s = (V4wState *)capGetUserData(hWnd); + if (s==NULL) + return FALSE; + + size = lpVHdr->dwBufferLength; + if (size>0 && s->running){ + buf = esballoc(lpVHdr->lpData,size,0,dummy); + buf->b_wptr+=size; + + ms_mutex_lock(&s->mutex); + putq(&s->rq, buf); + ms_mutex_unlock(&s->mutex); + } + return TRUE ; +} + +static bool_t try_format(V4wState *s, BITMAPINFO *videoformat, MSPixFmt pixfmt){ + switch(pixfmt){ + case MS_YUV420P: + videoformat->bmiHeader.biBitCount = 12; + videoformat->bmiHeader.biCompression=MAKEFOURCC('I','4','2','0'); + break; + case MS_RGB24: + videoformat->bmiHeader.biBitCount = 24; + videoformat->bmiHeader.biCompression=BI_RGB; + break; + default: + return FALSE; + } + return capSetVideoFormat(s->capvideo, videoformat, sizeof(BITMAPINFO)); +} + +static int v4w_open_videodevice(V4wState *s) +{ + CAPTUREPARMS capparam ; + BITMAPINFO videoformat; + char compname[5]; + int i; + char dev[80]; + char ver[80]; + compname[4]='\0'; + + for (i = 0; i < 9; i++){ + if (capGetDriverDescription(i, dev, sizeof (dev), + ver, sizeof (ver))) + { + snprintf(s->dev, sizeof(s->dev), "%s/%s",dev,ver); + ms_message("v4w: detected %s",s->dev); + s->devidx=i; + break; + } + } + if (s->capvideo==NULL) + { + s->capvideo = capCreateCaptureWindow("Capture Window",WS_CHILD /* WS_OVERLAPPED */ + ,0,0,s->vsize.width,s->vsize.height,HWND_MESSAGE, 0) ; + if (s->capvideo==NULL) + { + ms_warning("v4w: could not create capture windows"); + return -1; + } + } + + if(!capDriverConnect(s->capvideo,s->devidx )) + { + ms_warning("v4w: could not connect to capture driver"); + DestroyWindow(s->capvideo); + s->capvideo=NULL; + s->pix_fmt=MS_YUV420P; /* no webcam stuff */ + return -1; + } + /* + capPreviewRate(s->capvideo,s->fps) ; + if(!capPreview (s->capvideo, 1)) + { + ms_warning("v4w: cannot start video preview"); + capDriverDisconnect(s->capvideo); + DestroyWindow(s->capvideo); + s->capvideo=NULL; + return -1; + } + */ + capCaptureGetSetup(s->capvideo,&capparam,sizeof(capparam)) ; + capparam.dwRequestMicroSecPerFrame = 100000 ; + // detach capture from application + capparam.fYield = TRUE ; + capparam.fMakeUserHitOKToCapture = FALSE; + capparam.fAbortLeftMouse = FALSE; + capparam.fAbortRightMouse = FALSE; + capparam.wPercentDropForError = 90 ; + capparam.fCaptureAudio = FALSE ; + capparam.fAbortRightMouse = FALSE; + capparam.fAbortLeftMouse = FALSE; + capparam.AVStreamMaster = AVSTREAMMASTER_NONE ; + + if (!capCaptureSetSetup(s->capvideo,&capparam,sizeof(capparam))){ + ms_error("capCaptureSetSetup failed."); + } + capSetUserData(s->capvideo, s); + capGetVideoFormat(s->capvideo, &videoformat, sizeof(BITMAPINFO)); + + videoformat.bmiHeader.biSizeImage = 0; + videoformat.bmiHeader.biWidth = s->vsize.width; + videoformat.bmiHeader.biHeight = s->vsize.height; + /* "orig planes = " disp->videoformat.bmiHeader.biPlanes */ + /* "orig bitcount = " disp->videoformat.bmiHeader.biBitCount */ + /* "orig compression = " disp->videoformat.bmiHeader.biCompression */ + memcpy(compname,&videoformat.bmiHeader.biCompression,4); + ms_message("v4w: camera's current format is %s", compname); + + if (s->startwith_yuv_bug==TRUE && try_format(s,&videoformat,MS_RGB24)){ + s->pix_fmt=MS_RGB24; + ms_message("Using RGB24"); + }else if (try_format(s,&videoformat,MS_YUV420P)){ + s->pix_fmt=MS_YUV420P; + ms_message("Using YUV420P"); + }else if (try_format(s,&videoformat,MS_RGB24)){ + s->pix_fmt=MS_RGB24; + ms_message("Using RGB24"); + s->startwith_yuv_bug=TRUE; + }else{ + ms_error("v4w: Failed to set any video format."); + capDriverDisconnect (s->capvideo); + DestroyWindow(s->capvideo); + s->capvideo=NULL; + return -1; + } + if (!capSetCallbackOnVideoStream(s->capvideo, VideoStreamCallback)) + { + ms_error("v4w: fail to set capture callback"); + capDriverDisconnect (s->capvideo); + DestroyWindow(s->capvideo); + s->capvideo=NULL; + return -1; + } + if (!capCaptureSequenceNoFile(s->capvideo)){ + ms_error("v4w: fail to start capture"); + capDriverDisconnect (s->capvideo); + capSetCallbackOnVideoStream(s->capvideo, NULL); + DestroyWindow(s->capvideo); + s->capvideo=NULL; + } + return 0; +} + +static void v4w_init(MSFilter *f){ + V4wState *s=(V4wState *)ms_new0(V4wState,1); + int idx; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + s->pix_fmt=MS_RGB24; + + s->capvideo=NULL; + qinit(&s->rq); + for (idx=0;idx<10;idx++) + { + s->mire[idx]=NULL; + } + ms_mutex_init(&s->mutex,NULL); + s->start_time=0; + s->frame_count=-1; + s->fps=15; + s->started=FALSE; + s->autostarted=FALSE; + +#ifdef AMD_HACK2 + /* avoid bug with USB vimicro cards: + How can I detect that this problem exist? + */ + s->startwith_yuv_bug=FALSE; +#endif + +#ifdef AMD_HACK2 + s->thread = NULL; + ms_mutex_init(&s->thread_lock,NULL); + ms_cond_init(&s->thread_cond,NULL); + s->thread_running = FALSE; +#endif + + f->data=s; +} + +static int _v4w_start(V4wState *s, void *arg) +{ + int i; + s->frame_count=-1; + i = v4w_open_videodevice(s); + if (i==0 && s->startwith_yuv_bug==TRUE) + { + /* reopen device directly with MS_RGB24 */ + if (s->capvideo){ + capSetUserData(s->capvideo, (long) 0); + capCaptureStop(s->capvideo); + capCaptureAbort(s->capvideo); + capDriverDisconnect(s->capvideo); + capSetCallbackOnVideoStream(s->capvideo, NULL); + flushq(&s->rq,0); + ms_message("v4w: destroying capture window"); + DestroyWindow(s->capvideo); + ms_message("v4w: capture window destroyed"); + s->capvideo=NULL; + } + i = v4w_open_videodevice(s); + } + return i; +} + +static int _v4w_stop(V4wState *s, void *arg){ + s->frame_count=-1; + if (s->capvideo){ + capCaptureStop(s->capvideo); + Sleep(1000); + //capCaptureAbort(s->capvideo); + capSetCallbackOnVideoStream(s->capvideo, NULL); + //SendMessage(s->capvideo, WM_CLOSE, 0, 0); + capDriverDisconnect(s->capvideo); + capSetUserData(s->capvideo, (long) 0); + flushq(&s->rq,0); + ms_message("v4w: destroying capture window"); + DestroyWindow(s->capvideo); + ms_message("v4w: capture window destroyed"); + s->capvideo=NULL; + } +#if 0 + if (s->capvideo){ + CAPSTATUS status; + capCaptureStop(s->capvideo); + capDriverDisconnect(s->capvideo); + capCaptureAbort(s->capvideo); + + capSetCallbackOnVideoStream(s->capvideo, NULL); + while (1) + { + if (capGetStatus(s->capvideo, &status, sizeof(status))) + { + if (status.fCapturingNow==FALSE) + break; + Sleep(10); + ms_message("still capturing"); + } + } + DestroyWindow(s->capvideo); + s->capvideo=NULL; + } +#endif + return 0; +} + +#ifdef AMD_HACK2 + +void * +v4w_thread(void *arg) +{ + V4wState *s=(V4wState*)arg; + MSG msg; + + ms_mutex_lock(&s->thread_lock); + _v4w_start(s, NULL); + ms_cond_signal(&s->thread_cond); + ms_mutex_unlock(&s->thread_lock); + + while(s->thread_running) + { + BOOL fGotMessage; + if((fGotMessage = PeekMessage(&msg, (HWND) s->capvideo, 0, 0, PM_REMOVE)) != 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + Sleep(10); + } + + ms_mutex_lock(&s->thread_lock); + _v4w_stop(s, NULL); + ms_cond_signal(&s->thread_cond); + ms_mutex_unlock(&s->thread_lock); + ms_thread_exit(NULL); + return NULL; +} + + +static int v4w_start(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->thread_running=TRUE; + ms_thread_create(&s->thread,NULL,v4w_thread,s); + ms_mutex_lock(&s->thread_lock); + ms_cond_wait(&s->thread_cond,&s->thread_lock); + ms_mutex_unlock(&s->thread_lock); + s->started=TRUE; + return 0; +} + +static int v4w_stop(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + ms_mutex_lock(&s->thread_lock); + s->thread_running=FALSE; + //SendMessage(s->capvideo, WM_CLOSE, 0, 0); + ms_cond_wait(&s->thread_cond,&s->thread_lock); + ms_mutex_unlock(&s->thread_lock); + ms_thread_join(s->thread,NULL); + s->started=FALSE; + return 0; +} + +#else + +static int v4w_start(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_start(s, NULL); + s->started=TRUE; + return 0; +} + +static int v4w_stop(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_stop(s, NULL); + s->started=FALSE; + return 0; +} + +#endif + +static void v4w_uninit(MSFilter *f){ + V4wState *s=(V4wState*)f->data; + int idx; + flushq(&s->rq,0); + ms_mutex_destroy(&s->mutex); + for (idx=0;idx<10;idx++) + { + if (s->mire[idx]==NULL) + break; + freemsg(s->mire[idx]); + } + if (s->capvideo!=NULL) + { + ms_message("v4w: destroying capture window"); + DestroyWindow(s->capvideo); + ms_message("v4w: capture window destroyed"); + s->capvideo=NULL; + } +#ifdef AMD_HACK2 + ms_cond_destroy(&s->thread_cond); + ms_mutex_destroy(&s->thread_lock); +#endif + ms_free(s); +} + +static mblk_t * v4w_make_nowebcam(V4wState *s){ + int idx; + int count; + if (s->mire[0]==NULL && s->frame_ind==0){ + /* load several images to fake a movie */ + for (idx=0;idx<10;idx++) + { + s->mire[idx]=ms_load_nowebcam(&s->vsize, idx); + if (s->mire[idx]==NULL) + break; + } + if (idx==0) + s->mire[0]=ms_load_nowebcam(&s->vsize, -1); + } + for (count=0;count<10;count++) + { + if (s->mire[count]==NULL) + break; + } + + s->frame_ind++; + if (count==0) + return NULL; + + idx = s->frame_ind%count; + if (s->mire[idx]!=NULL) + return s->mire[idx]; + return s->mire[0]; +} + +static void v4w_preprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + if (!s->started) { + ms_message("V4W auto-started."); + v4w_start(obj,NULL); + s->autostarted=TRUE; + } + s->running=TRUE; + if (s->capvideo==NULL) + s->fps=1; +} + +static void v4w_postprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + s->running=FALSE; + if (s->autostarted){ + v4w_stop(obj,NULL); + } +} + +static void v4w_process(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + mblk_t *m; + uint32_t timestamp; + int cur_frame; + + if (s->frame_count==-1){ + s->start_time=obj->ticker->time; + s->frame_count=0; + } + + + cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame>s->frame_count){ + mblk_t *om=NULL; + ms_mutex_lock(&s->mutex); + /*keep the most recent frame if several frames have been captured */ + if (s->capvideo!=NULL){ + while((m=getq(&s->rq))!=NULL){ + if (om!=NULL) freemsg(om); + om=m; + } + }else { + mblk_t *nowebcam = v4w_make_nowebcam(s); + if (nowebcam!=NULL) + om=dupmsg(nowebcam); + } + ms_mutex_unlock(&s->mutex); + if (om!=NULL){ + timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/ + mblk_set_timestamp_info(om,timestamp); + ms_queue_put(obj->outputs[0],om); + /*ms_message("picture sent");*/ + } + s->frame_count++; + } +} + +static int v4w_set_fps(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->fps=*((float*)arg); + return 0; +} + +static int v4w_get_pix_fmt(MSFilter *f,void *arg){ + V4wState *s=(V4wState*)f->data; + if (!s->started) { + ms_message("V4W auto-started in v4w_get_pix_fmt()"); + v4w_start(f,NULL); + s->autostarted=TRUE; + } + *((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt; + return 0; +} + +static int v4w_set_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->vsize=*((MSVideoSize*)arg); + return 0; +} + +static int v4w_get_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + MSVideoSize *vs=(MSVideoSize*)arg; + vs->width=s->vsize.width; + vs->height=s->vsize.height; + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , v4w_set_fps }, + { MS_FILTER_GET_PIX_FMT , v4w_get_pix_fmt }, + { MS_FILTER_SET_VIDEO_SIZE, v4w_set_vsize }, + { MS_FILTER_GET_VIDEO_SIZE, v4w_get_vsize }, + { MS_V4L_START , v4w_start }, + { MS_V4L_STOP , v4w_stop }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_v4w_desc={ + MS_V4L_ID, + "MSV4w", + "A video4windows compatible source filter to stream pictures.", + MS_FILTER_OTHER, + NULL, + 0, + 1, + v4w_init, + v4w_preprocess, + v4w_process, + v4w_postprocess, + v4w_uninit, + methods +}; + +#else + +MSFilterDesc ms_v4w_desc={ + .id=MS_V4L_ID, + .name="MSV4w", + .text="A video4windows compatible source filter to stream pictures.", + .ninputs=0, + .noutputs=1, + .category=MS_FILTER_OTHER, + .init=v4w_init, + .preprocess=v4w_preprocess, + .process=v4w_process, + .postprocess=v4w_postprocess, + .uninit=v4w_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_v4w_desc) + +static void ms_v4w_detect(MSWebCamManager *obj); + +static void ms_v4w_cam_init(MSWebCam *cam){ +} + + +static MSFilter *ms_v4w_create_reader(MSWebCam *obj){ + MSFilter *f= ms_filter_new_from_desc(&ms_v4w_desc); + V4wState *s=(V4wState*)f->data; + s->devidx=(int)obj->data; + return f; +} + +MSWebCamDesc ms_v4w_cam_desc={ + "VideoForWindows grabber", + &ms_v4w_detect, + &ms_v4w_cam_init, + &ms_v4w_create_reader, + NULL +}; + +static void ms_v4w_detect(MSWebCamManager *obj){ + int i; + char dev[80]; + char ver[80]; + char name[160]; + MSWebCam *cam; + for (i = 0; i < 9; i++){ + if (capGetDriverDescription(i, dev, sizeof (dev), + ver, sizeof (ver))){ + HWND hwnd=capCreateCaptureWindow("Capture Window",WS_CHILD /* WS_OVERLAPPED */ + ,0,0,352,288,HWND_MESSAGE, 0) ; + if (hwnd==NULL) break; + if(!capDriverConnect(hwnd,i )){ + ms_warning("v4w: could not connect to capture driver, no webcam connected."); + DestroyWindow(hwnd); + break; + }else{ + capDriverDisconnect(hwnd); + DestroyWindow(hwnd); + } + snprintf(name, sizeof(name), "%s/%s",dev,ver); + cam=ms_web_cam_new(&ms_v4w_cam_desc); + cam->data=(void*)i;/*store the device index */ + cam->name=ms_strdup(name); + ms_web_cam_manager_add_cam(obj,cam); + } + } +} + diff --git a/linphone/mediastreamer2/src/winvideods.c b/linphone/mediastreamer2/src/winvideods.c new file mode 100644 index 000000000..722fdbc78 --- /dev/null +++ b/linphone/mediastreamer2/src/winvideods.c @@ -0,0 +1,1048 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define UNICODE +#define AYMERIC_TEST +#define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA + +#include "mediastreamer2/msvideo.h" +#include "mediastreamer2/msticker.h" +#include "mediastreamer2/msv4l.h" +#include "mediastreamer2/mswebcam.h" + +#include "nowebcam.h" +#include + +#include +#include +#include + +#include +#include +#include "dxfilter.h" +#include +#include +#include + +HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister); +void RemoveGraphFromRot(DWORD pdwRegister); + +typedef struct V4wState{ + + char dev[512]; + int devidx; + + CComPtr m_pGraph; + CComPtr m_pBuilder; + CComPtr m_pControl; + CDXFilter *m_pDXFilter; + CComPtr m_pIDXFilter; + CComPtr m_pNullRenderer; + CComPtr m_pDeviceFilter; + DWORD rotregvalue; + + MSVideoSize vsize; + int pix_fmt; + mblk_t *mire[10]; + char nowebcamimage[256]; + queue_t rq; + ms_mutex_t mutex; + int frame_ind; + int frame_max; + float fps; + float start_time; + int frame_count; + bool_t running; +}V4wState; + +static V4wState *s_callback=NULL; + +static void dummy(void*p){ +} + +HRESULT ( Callback)(IMediaSample* pSample, REFERENCE_TIME* sTime, REFERENCE_TIME* eTime, BOOL changed) +{ + BYTE *byte_buf=NULL; + mblk_t *buf; + + V4wState *s = s_callback; + if (s==NULL) + return S_OK; + + HRESULT hr = pSample->GetPointer(&byte_buf); + if (FAILED(hr)) + { + return S_OK; + } + + int size = pSample->GetActualDataLength(); + if (size>+1000) + { + buf=allocb(size,0); + memcpy(buf->b_wptr, byte_buf, size); + if (s->pix_fmt==MS_RGB24) + { + /* Conversion from top down bottom up (BGR to RGB and flip) */ + unsigned long Index,nPixels; + unsigned char *blue; + unsigned char tmp; + short iPixelSize; + + blue=buf->b_wptr; + + nPixels=s->vsize.width*s->vsize.height; + iPixelSize=24/8; + + for(Index=0;Index!=nPixels;Index++) // For each pixel + { + tmp=*blue; + *blue=*(blue+2); + *(blue+2)=tmp; + blue+=iPixelSize; + } + + unsigned char *pLine1, *pLine2; + int iLineLen,iIndex; + + iLineLen=s->vsize.width*iPixelSize; + pLine1=buf->b_wptr; + pLine2=&(buf->b_wptr)[iLineLen * (s->vsize.height - 1)]; + + for( ;pLine1b_wptr+=size; + + ms_mutex_lock(&s->mutex); + putq(&s->rq, buf); + ms_mutex_unlock(&s->mutex); + + } + return S_OK; +} + +int try_format(V4wState *s, int format) +{ + HRESULT hr=S_OK; + IEnumPins *pEnum=0; + ULONG ulFound; + IPin *pPin; + + GUID guid_format; + DWORD biCompression; + DWORD biBitCount; + + // Verify input + if (!s->m_pDeviceFilter) + return -1; + + if (format == MS_YUV420P) + guid_format = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); + else if (format == MS_YUYV) + guid_format = MEDIASUBTYPE_YUYV; + else if (format == MS_UYVY) + guid_format = MEDIASUBTYPE_UYVY; + else if (format == MS_RGB24) + guid_format = MEDIASUBTYPE_RGB24; + else if (format == MS_YUY2) + guid_format = MEDIASUBTYPE_YUY2; + + if (format == MS_YUV420P) + biCompression = MAKEFOURCC('I','4','2','0'); + else if (format == MS_YUYV) + biCompression = MAKEFOURCC('Y','U','Y','V'); + else if (format == MS_UYVY) + biCompression = MAKEFOURCC('U','Y','V','Y'); + else if (format == MS_RGB24) + biCompression = BI_RGB; + else if (format == MS_YUY2) + biCompression = MAKEFOURCC('Y','U','Y','2'); + + if (format == MS_YUV420P) + biBitCount = 12; + else if (format == MS_YUYV) + biBitCount = 16; + else if (format == MS_UYVY) + biBitCount = 16; + else if (format == MS_RGB24) + biBitCount = 24; + else if (format == MS_YUY2) + biBitCount = 16; + + // Get pin enumerator + hr = s->m_pDeviceFilter->EnumPins(&pEnum); + if(FAILED(hr)) + return -1; + + pEnum->Reset(); + + // Count every pin on the filter + while(S_OK == pEnum->Next(1, &pPin, &ulFound)) + { + PIN_DIRECTION pindir = (PIN_DIRECTION) 3; + + hr = pPin->QueryDirection(&pindir); + + if(pindir != PINDIR_INPUT) + { + IEnumMediaTypes *ppEnum; + ULONG ulFound2; + hr = pPin->EnumMediaTypes(&ppEnum); + if(FAILED(hr)) + continue; + + AM_MEDIA_TYPE *ppMediaTypes; + while(S_OK == ppEnum->Next(1, &ppMediaTypes, &ulFound2)) + { + if (ppMediaTypes->formattype != FORMAT_VideoInfo) + continue; + if (ppMediaTypes->majortype != MEDIATYPE_Video) + continue; + if (ppMediaTypes->subtype != guid_format) + continue; + VIDEOINFO *pvi = (VIDEOINFO *)ppMediaTypes->pbFormat; + if (pvi->bmiHeader.biCompression!=biCompression) + continue; + if (pvi->bmiHeader.biBitCount!=biBitCount) + continue; + + pPin->Release(); + pEnum->Release(); + return 0; + } + } + + pPin->Release(); + } + + pEnum->Release(); + return -1; +} + +int try_format_size(V4wState *s, int format, int width, int height) +{ + HRESULT hr=S_OK; + IEnumPins *pEnum=0; + ULONG ulFound; + IPin *pPin; + + GUID guid_format; + DWORD biCompression; + DWORD biBitCount; + + // Verify input + if (!s->m_pDeviceFilter) + return -1; + + if (format == MS_YUV420P) + guid_format = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); + else if (format == MS_YUYV) + guid_format = MEDIASUBTYPE_YUYV; + else if (format == MS_UYVY) + guid_format = MEDIASUBTYPE_UYVY; + else if (format == MS_RGB24) + guid_format = MEDIASUBTYPE_RGB24; + else if (format == MS_YUY2) + guid_format = MEDIASUBTYPE_YUY2; + + if (format == MS_YUV420P) + biCompression = MAKEFOURCC('I','4','2','0'); + else if (format == MS_YUYV) + biCompression = MAKEFOURCC('Y','U','Y','V'); + else if (format == MS_UYVY) + biCompression = MAKEFOURCC('U','Y','V','Y'); + else if (format == MS_RGB24) + biCompression = BI_RGB; + else if (format == MS_YUY2) + biCompression = MAKEFOURCC('Y','U','Y','2'); + + if (format == MS_YUV420P) + biBitCount = 12; + else if (format == MS_YUYV) + biBitCount = 16; + else if (format == MS_UYVY) + biBitCount = 16; + else if (format == MS_RGB24) + biBitCount = 24; + else if (format == MS_YUY2) + biBitCount = 16; + + // Get pin enumerator + hr = s->m_pDeviceFilter->EnumPins(&pEnum); + if(FAILED(hr)) + return -1; + + pEnum->Reset(); + + // Count every pin on the filter + while(S_OK == pEnum->Next(1, &pPin, &ulFound)) + { + PIN_DIRECTION pindir = (PIN_DIRECTION) 3; + + hr = pPin->QueryDirection(&pindir); + + if(pindir != PINDIR_INPUT) + { + IEnumMediaTypes *ppEnum; + ULONG ulFound2; + hr = pPin->EnumMediaTypes(&ppEnum); + if(FAILED(hr)) + continue; + + AM_MEDIA_TYPE *ppMediaTypes; + while(S_OK == ppEnum->Next(1, &ppMediaTypes, &ulFound2)) + { + if (ppMediaTypes->formattype != FORMAT_VideoInfo) + continue; + if (ppMediaTypes->majortype != MEDIATYPE_Video) + continue; + if (ppMediaTypes->subtype != guid_format) + continue; + VIDEOINFO *pvi = (VIDEOINFO *)ppMediaTypes->pbFormat; + if (pvi->bmiHeader.biCompression!=biCompression) + continue; + if (pvi->bmiHeader.biBitCount!=biBitCount) + continue; + if (pvi->bmiHeader.biHeight!=height) + continue; + if (pvi->bmiHeader.biWidth!=width) + continue; + + s->vsize.width = width; + s->vsize.height = height; + + pPin->Release(); + pEnum->Release(); + return 0; + } + } + + pPin->Release(); + } + + pEnum->Release(); + return -1; +} + +static int v4w_open_videodevice(V4wState *s) +{ + // Initialize COM + CoInitialize(NULL); + + // get a Graph + HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph); + if(FAILED(hr)) + { + return -1; + } + + // get a CaptureGraphBuilder2 + hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2); + if(FAILED(hr)) + { + return -2; + } + + // connect capture graph builder with the graph + s->m_pBuilder->SetFiltergraph(s->m_pGraph); + + // get mediacontrol so we can start and stop the filter graph + hr=s->m_pGraph.QueryInterface(&(s->m_pControl)); + if(FAILED(hr)) + { + return -3; + } + + +#ifdef _DEBUG + HANDLE m_hLogFile=CreateFile(L"DShowGraphLog.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + if(m_hLogFile!=INVALID_HANDLE_VALUE) + { + hr=s->m_pGraph->SetLogFile((DWORD_PTR)m_hLogFile); + /* ASSERT(SUCCEEDED(hr)); */ + } + + //AddGraphToRot(s->m_pGraph, &s->rotregvalue); +#endif + + ICreateDevEnum *pCreateDevEnum = NULL; + IEnumMoniker *pEnumMoniker = NULL; + IMoniker *pMoniker = NULL; + + ULONG nFetched = 0; + + hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); + if(FAILED(hr)) + { + return -4; + } + + hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, + &pEnumMoniker, 0); + if (FAILED(hr) || pEnumMoniker == NULL) { + //printf("no device\n"); + return -5; + } + + pEnumMoniker->Reset(); + + int pos=0; + while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) ) + { + if (pos>=s->devidx) + break; + pos++; + pMoniker->Release(); + pMoniker=NULL; + } + if(pMoniker==NULL) + { + return -6; + } + + hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); + if(FAILED(hr)) + { + return -7; + } + + s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); + + pMoniker->Release(); + pEnumMoniker->Release(); + pCreateDevEnum->Release(); + + if (try_format(s, s->pix_fmt)==0) + s->pix_fmt = s->pix_fmt; + else if (try_format(s,MS_YUV420P)==0) + s->pix_fmt = MS_YUV420P; + else if (try_format(s,MS_YUY2)==0) + s->pix_fmt = MS_YUY2; + else if (try_format(s,MS_YUYV)==0) + s->pix_fmt = MS_YUYV; + else if (try_format(s,MS_UYVY)==0) + s->pix_fmt = MS_UYVY; + else if (try_format(s,MS_RGB24)==0) + s->pix_fmt = MS_RGB24; + else + { + ms_error("Unsupported video pixel format."); + return -8; + } + + if (s->pix_fmt == MS_YUV420P) + ms_message("Driver supports YUV420P, using that format."); + else if (s->pix_fmt == MS_YUY2) + ms_message("Driver supports YUY2 (UYVY), using that format."); + else if (s->pix_fmt == MS_YUYV) + ms_message("Driver supports YUV422, using that format."); + else if (s->pix_fmt == MS_UYVY) + ms_message("Driver supports UYVY, using that format."); + else if (s->pix_fmt == MS_RGB24) + ms_message("Driver supports RGB24, using that format."); + + if (try_format_size(s, s->pix_fmt, s->vsize.width, s->vsize.height)==0) + ms_message("Selected Size: %ix%i.", s->vsize.width, s->vsize.height); + else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H)==0) + ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H); + else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H)==0) + ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H); + else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H)==0) + ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H); + else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H)==0) + ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H); + else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H)==0) + ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H); + else + { + ms_error("No supported size found for format."); + /* size not supported? */ + return -9; + } + + // get DXFilter + s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); + if(s->m_pDXFilter==NULL) + { + return -10; + } + s->m_pDXFilter->AddRef(); + + CMediaType mt; + mt.SetType(&MEDIATYPE_Video); + + GUID m = MEDIASUBTYPE_RGB24; + if (s->pix_fmt == MS_YUV420P) + m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); + else if (s->pix_fmt == MS_YUY2) + m = MEDIASUBTYPE_YUY2; + else if (s->pix_fmt == MS_YUYV) + m = MEDIASUBTYPE_YUYV; + else if (s->pix_fmt == MS_UYVY) + m = MEDIASUBTYPE_UYVY; + else if (s->pix_fmt == MS_RGB24) + m = MEDIASUBTYPE_RGB24; + mt.SetSubtype(&m); + + mt.formattype = FORMAT_VideoInfo; + mt.SetTemporalCompression(FALSE); + + VIDEOINFO *pvi = (VIDEOINFO *) + mt.AllocFormatBuffer(sizeof(VIDEOINFO)); + if (NULL == pvi) + return -11; + ZeroMemory(pvi, sizeof(VIDEOINFO)); + + if (s->pix_fmt == MS_YUV420P) + pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); + else if (s->pix_fmt == MS_YUY2) + pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2'); + else if (s->pix_fmt == MS_YUYV) + pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','V'); + else if (s->pix_fmt == MS_UYVY) + pvi->bmiHeader.biCompression = MAKEFOURCC('U','Y','V','Y'); + else if (s->pix_fmt == MS_RGB24) + pvi->bmiHeader.biCompression = BI_RGB; + + if (s->pix_fmt == MS_YUV420P) + pvi->bmiHeader.biBitCount = 12; + else if (s->pix_fmt == MS_YUY2) + pvi->bmiHeader.biBitCount = 16; + else if (s->pix_fmt == MS_YUYV) + pvi->bmiHeader.biBitCount = 16; + else if (s->pix_fmt == MS_UYVY) + pvi->bmiHeader.biBitCount = 16; + else if (s->pix_fmt == MS_RGB24) + pvi->bmiHeader.biBitCount = 24; + + pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pvi->bmiHeader.biWidth = s->vsize.width; + pvi->bmiHeader.biHeight = s->vsize.height; + pvi->bmiHeader.biPlanes = 1; + pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); + pvi->bmiHeader.biClrImportant = 0; + mt.SetSampleSize(pvi->bmiHeader.biSizeImage); + mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); + + hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); + if(FAILED(hr)) + { + return -12; + } + + hr = s->m_pDXFilter->SetCallback(Callback); + if(FAILED(hr)) + { + return -13; + } + + hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, + (LPVOID *)&s->m_pIDXFilter); + if(FAILED(hr)) + { + return -14; + } + + hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); + if(FAILED(hr)) + { + return -15; + } + + + // get null renderer + hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer); + if(FAILED(hr)) + { + return -16; + } + if (s->m_pNullRenderer!=NULL) + { + s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); + } + + hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, + &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); + if (FAILED(hr)) + { + //hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, + // &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); + if (FAILED(hr)) + { + return -17; + } + } + + //m_pDXFilter->SetBufferSamples(TRUE); + + s_callback = s; + hr = s->m_pControl->Run(); + if(FAILED(hr)) + { + return -18; + } + + s->rotregvalue=1; + return 0; +} + +/**************************************************************************** + +FUNCTION: AddGraphToRot. + +DESCRIPTION: + Adds a DirectShow filter graph to the Running Object Table, + allowing GraphEdit to "spy" on a remote filter graph. + +PARAMETERS: + +RETURNS: + . 0 for success, otherwise an error #. + . Standard COM/HRESULT error numbers are returned if a COM/HRESULT error + was encountered. + +****************************************************************************/ +HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) +{ + IMoniker * pMoniker; + IRunningObjectTable *pROT; + WCHAR wsz[128]; + HRESULT hr; + + if (FAILED(GetRunningObjectTable(0, &pROT))) + return E_FAIL; + + wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); + wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); + + hr = CreateItemMoniker(L"!", wsz, &pMoniker); + if (SUCCEEDED(hr)) + { + hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister); + pMoniker->Release(); + } + + pROT->Release(); + return hr; +} + + +/**************************************************************************** + +FUNCTION: RemoveGraphFromRot. + +DESCRIPTION: + Removes a filter graph from the Running Object Table. + +PARAMETERS: + +****************************************************************************/ +void RemoveGraphFromRot(DWORD pdwRegister) +{ + IRunningObjectTable *pROT; + + if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) + { + pROT->Revoke(pdwRegister); + pROT->Release(); + } +} + +static void v4w_init(MSFilter *f){ + V4wState *s=(V4wState *)ms_new0(V4wState,1); + int idx; + s->devidx=0; + s->vsize.width=MS_VIDEO_SIZE_CIF_W; + s->vsize.height=MS_VIDEO_SIZE_CIF_H; + //s->pix_fmt=MS_RGB24; + s->pix_fmt=MS_YUV420P; + + s->rotregvalue = 0; + s->m_pGraph=NULL; + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pDXFilter=NULL; + s->m_pIDXFilter=NULL; + s->m_pDeviceFilter=NULL; + + qinit(&s->rq); + for (idx=0;idx<10;idx++) + { + s->mire[idx]=NULL; + } + memset(s->nowebcamimage, 0, sizeof(s->nowebcamimage)); + ms_mutex_init(&s->mutex,NULL); + s->start_time=0; + s->frame_count=-1; + s->fps=15; + + f->data=s; +} + + +static int _v4w_start(V4wState *s, void *arg) +{ + int i; + s->frame_count=-1; + + i = v4w_open_videodevice(s); + + if (s->rotregvalue==0){ + //RemoveGraphFromRot(s->rotregvalue); + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph not started (err=%i)", i); + s->rotregvalue=0; + s->pix_fmt = MS_YUV420P; + } + return i; +} + +static int _v4w_stop(V4wState *s, void *arg){ + s->frame_count=-1; + if (s->rotregvalue>0){ + HRESULT hr = s->m_pControl->Stop(); + if(FAILED(hr)) + { + ms_message("v4w: could not stop graph"); + } + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + //RemoveGraphFromRot(s->rotregvalue); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph destroyed"); + s->rotregvalue=0; + } + return 0; +} + + +static int v4w_start(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_start(s, NULL); + return 0; +} + +static int v4w_stop(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + _v4w_stop(s, NULL); + return 0; +} + + +static void v4w_uninit(MSFilter *f){ + V4wState *s=(V4wState*)f->data; + int idx; + flushq(&s->rq,0); + ms_mutex_destroy(&s->mutex); + for (idx=0;idx<10;idx++) + { + if (s->mire[idx]==NULL) + break; + freemsg(s->mire[idx]); + } + if (s->rotregvalue>0){ + HRESULT hr = s->m_pControl->Stop(); + if(FAILED(hr)) + { + ms_message("v4w: could not stop graph"); + } + if (s->m_pNullRenderer!=NULL) + s->m_pGraph->RemoveFilter(s->m_pNullRenderer); + if (s->m_pIDXFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pIDXFilter); + if (s->m_pDeviceFilter!=NULL) + s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); + //RemoveGraphFromRot(s->rotregvalue); + s->m_pBuilder=NULL; + s->m_pControl=NULL; + s->m_pIDXFilter=NULL; + if (s->m_pDXFilter!=NULL) + s->m_pDXFilter->Release(); + s->m_pDXFilter=NULL; + s->m_pGraph=NULL; + s->m_pNullRenderer=NULL; + s->m_pDeviceFilter=NULL; + CoUninitialize(); + s_callback = NULL; + flushq(&s->rq,0); + ms_message("v4w: graph destroyed"); + s->rotregvalue=0; + } + ms_free(s); +} + +static mblk_t * v4w_make_nowebcam(V4wState *s){ +#if defined(_WIN32_WCE) + return NULL; +#else + int idx; + int count; + if(s->mire[0]==NULL && s->frame_ind==0 && s->nowebcamimage[0] != '\0') + { + s->mire[0] = ms_load_jpeg_as_yuv(s->nowebcamimage,&s->vsize); + } + if (s->mire[0]==NULL && s->frame_ind==0){ + /* load several images to fake a movie */ + for (idx=0;idx<10;idx++) + { + s->mire[idx]=ms_load_nowebcam(&s->vsize, idx); + if (s->mire[idx]==NULL) + break; + } + if (idx==0) + s->mire[0]=ms_load_nowebcam(&s->vsize, -1); + } + for (count=0;count<10;count++) + { + if (s->mire[count]==NULL) + break; + } + + s->frame_ind++; + if (count==0) + return NULL; + + idx = s->frame_ind%count; + if (s->mire[idx]!=NULL) + return s->mire[idx]; + return s->mire[0]; +#endif +} + +static void v4w_preprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + s->running=TRUE; + if (s->rotregvalue==0) + s->fps=1; +} + +static void v4w_postprocess(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + s->running=FALSE; + s->start_time=0; + s->frame_count=-1; + flushq(&s->rq,0); +} + +static void v4w_process(MSFilter * obj){ + V4wState *s=(V4wState*)obj->data; + mblk_t *m; + uint32_t timestamp; + int cur_frame; + + if (s->frame_count==-1){ + s->start_time=obj->ticker->time; + s->frame_count=0; + } + + cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0); + if (cur_frame>s->frame_count){ + mblk_t *om=NULL; + ms_mutex_lock(&s->mutex); + /*keep the most recent frame if several frames have been captured */ + if (s->rotregvalue!=0){ + while((m=getq(&s->rq))!=NULL){ + if (om!=NULL) freemsg(om); + om=m; + } + }else { + mblk_t *nowebcam = v4w_make_nowebcam(s); + if (nowebcam!=NULL) + om=dupmsg(nowebcam); + } + ms_mutex_unlock(&s->mutex); + if (om!=NULL){ + timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/ + mblk_set_timestamp_info(om,timestamp); + ms_queue_put(obj->outputs[0],om); + /*ms_message("picture sent");*/ + } + s->frame_count++; + } +} + + + +static int v4w_set_fps(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->fps=*((float*)arg); + s->frame_count=-1; /* reset counter used for fps */ + return 0; +} + +static int v4w_get_pix_fmt(MSFilter *f,void *arg){ + V4wState *s=(V4wState*)f->data; + *((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt; + return 0; +} + +static int v4w_set_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->vsize=*((MSVideoSize*)arg); + return 0; +} + +static int v4w_get_vsize(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + MSVideoSize *vs=(MSVideoSize*)arg; + vs->width=s->vsize.width; + vs->height=s->vsize.height; + return 0; +} + +static int v4w_set_device(MSFilter *f, void *arg){ + V4wState *s=(V4wState*)f->data; + s->devidx=*((int*)arg); + return 0; +} + +static int v4w_set_image(MSFilter *f, void *arg){ + int idx; + V4wState *s=(V4wState*)f->data; + char *image = (char *)arg; + ms_mutex_lock(&s->mutex); + if (image!=NULL && image[0]!='\0') + snprintf(s->nowebcamimage, sizeof(s->nowebcamimage), "%s", image); + else + s->nowebcamimage[0] = '\0'; + for (idx=0;idx<10;idx++) + { + if (s->mire[idx]==NULL) + break; + freemsg(s->mire[idx]); + s->mire[idx]=NULL; + } + s->frame_ind=0; + ms_mutex_unlock(&s->mutex); + return 0; +} + +static MSFilterMethod methods[]={ + { MS_FILTER_SET_FPS , v4w_set_fps }, + { MS_FILTER_GET_PIX_FMT , v4w_get_pix_fmt }, + { MS_FILTER_SET_VIDEO_SIZE, v4w_set_vsize }, + { MS_FILTER_GET_VIDEO_SIZE, v4w_get_vsize }, + { MS_V4L_START , v4w_start }, + { MS_V4L_STOP , v4w_stop }, + { MS_V4L_SET_DEVICE , v4w_set_device }, + { MS_V4L_SET_IMAGE , v4w_set_image }, + { 0 , NULL } +}; + +#ifdef _MSC_VER + +MSFilterDesc ms_v4w_desc={ + MS_V4L_ID, + "MSV4w", + "A video4windows compatible source filter to stream pictures.", + MS_FILTER_OTHER, + NULL, + 0, + 1, + v4w_init, + v4w_preprocess, + v4w_process, + v4w_postprocess, + v4w_uninit, + methods +}; + +#else + +MSFilterDesc ms_v4w_desc={ + .id=MS_V4L_ID, + .name="MSV4w", + .text="A video4windows compatible source filter to stream pictures.", + .ninputs=0, + .noutputs=1, + .category=MS_FILTER_OTHER, + .init=v4w_init, + .preprocess=v4w_preprocess, + .process=v4w_process, + .postprocess=v4w_postprocess, + .uninit=v4w_uninit, + .methods=methods +}; + +#endif + +MS_FILTER_DESC_EXPORT(ms_v4w_desc) + +static MSFilter *vfw_create_reader(MSWebCam *obj){ + return ms_filter_new_from_desc(&ms_v4w_desc); +} + +static void vfw_detect(MSWebCamManager *obj); + +static void vfw_cam_init(MSWebCam *cam){ + cam->name=ms_strdup("dx0"); +} + +MSWebCamDesc ms_v4w_cam_desc={ + "DirectX Video Grabber", + &vfw_detect, + &vfw_cam_init, + &vfw_create_reader, + NULL +}; + +static void vfw_detect(MSWebCamManager *obj){ + MSWebCam *cam=ms_web_cam_new(&ms_v4w_cam_desc); + ms_web_cam_manager_add_cam(obj,cam); +} diff --git a/linphone/mediastreamer2/tests/.cvsignore b/linphone/mediastreamer2/tests/.cvsignore new file mode 100644 index 000000000..9a8edd6cc --- /dev/null +++ b/linphone/mediastreamer2/tests/.cvsignore @@ -0,0 +1,8 @@ +Makefile.in +Makefile +.deps +.libs +echo +mediastream +ring +videodisplay diff --git a/linphone/mediastreamer2/tests/Makefile.am b/linphone/mediastreamer2/tests/Makefile.am new file mode 100644 index 000000000..ee8638e46 --- /dev/null +++ b/linphone/mediastreamer2/tests/Makefile.am @@ -0,0 +1,32 @@ +noinst_PROGRAMS=echo ring mtudiscover + +if BUILD_VIDEO +noinst_PROGRAMS+=videodisplay +endif + +echo_SOURCES=echo.c +ring_SOURCES=ring.c +videodisplay_SOURCES=videodisplay.c +mtudiscover_SOURCES=mtudiscover.c + +libexec_PROGRAMS=mediastream + +mediastream_SOURCES=mediastream.c + +#libquickstream.la would be enough, but to workaround a bug of libtool when +#cross compiling we need to add all the dependencies. +LDADD= $(top_builddir)/src/libmediastreamer.la \ + $(ORTP_LIBS) \ + $(ALSA_LIBS) \ + $(ARTS_LIBS) \ + $(SPEEX_LIBS) \ + $(GSM_LIBS) \ + $(THEORA_LIBS) \ + $(FFMPEG_LIBS) + + + +INCLUDES=-I$(top_srcdir)/include/ + +AM_CFLAGS=-I$(top_srcdir) $(ORTP_CFLAGS) $(STRICT_OPTIONS) $(VIDEO_CFLAGS) +AM_LDFLAGS=-rdynamic diff --git a/linphone/mediastreamer2/tests/echo.c b/linphone/mediastreamer2/tests/echo.c new file mode 100644 index 000000000..b6cf6411b --- /dev/null +++ b/linphone/mediastreamer2/tests/echo.c @@ -0,0 +1,74 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msticker.h" + +#include + +static int run=1; + +static void stop(int signum){ + run=0; +} + +int main(int argc, char *argv[]){ + MSFilter *f1,*f2; + MSSndCard *card; + MSTicker *ticker; + char *card_id=NULL; + ortp_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + ms_init(); + + signal(SIGINT,stop); + + if (argc>1) + card_id=argv[1]; + + if (card_id!=NULL) + { + card=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),card_id); +#ifdef __linux + if (card==NULL) + card = ms_alsa_card_new_custom(card_id, card_id); +#endif + } + else card=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()); + + if (card==NULL){ + ms_error("No card."); + return -1; + } + f1=ms_snd_card_create_reader(card); + f2=ms_snd_card_create_writer(card); + ticker=ms_ticker_new(); + ms_filter_link(f1,0,f2,0); + ms_ticker_attach(ticker,f1); + while(run) + sleep(1); + ms_ticker_detach(ticker,f1); + ms_ticker_destroy(ticker); + ms_filter_unlink(f1,0,f2,0); + ms_filter_destroy(f1); + ms_filter_destroy(f2); + return 0; +} diff --git a/linphone/mediastreamer2/tests/mediastream.c b/linphone/mediastreamer2/tests/mediastream.c new file mode 100644 index 000000000..17ebef068 --- /dev/null +++ b/linphone/mediastreamer2/tests/mediastream.c @@ -0,0 +1,266 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mediastream.h" +#ifdef VIDEO_ENABLED +#include "mediastreamer2/msv4l.h" +#endif + +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include + +static int cond=1; + +static void stop_handler(int signum) +{ + cond--; + if (cond<0) exit(-1); +} + +static bool_t parse_addr(const char *addr, char *ip, int len, int *port) +{ + char *semicolon=NULL; + int iplen; + int slen; + char *p; + + *port=0; + semicolon=strchr(addr,':'); + for (p=addr+strlen(addr)-1;p>addr;p--){ + if (*p==':') { + semicolon=p; + break; + } + } + if (semicolon==NULL) return FALSE; + iplen=semicolon-addr; + slen=MIN(iplen,len-1); + strncpy(ip,addr,slen); + ip[slen]='\0'; + *port=atoi(semicolon+1); + return TRUE; +} + +static void display_items(void *user_data, uint32_t csrc, rtcp_sdes_type_t t, const char *content, uint8_t content_len){ + char str[256]; + int len=MIN(sizeof(str)-1,content_len); + strncpy(str,content,len); + str[len]='\0'; + switch(t){ + case RTCP_SDES_CNAME: + ms_message("Found CNAME=%s",str); + break; + case RTCP_SDES_TOOL: + ms_message("Found TOOL=%s",str); + break; + case RTCP_SDES_NOTE: + ms_message("Found NOTE=%s",str); + break; + default: + ms_message("Unhandled SDES item (%s)",str); + } +} + +static void parse_rtcp(mblk_t *m){ + do{ + if (rtcp_is_RR(m)){ + ms_message("Receiving RTCP RR"); + }else if (rtcp_is_SR(m)){ + ms_message("Receiving RTCP SR"); + }else if (rtcp_is_SDES(m)){ + ms_message("Receiving RTCP SDES"); + rtcp_sdes_parse(m,display_items,NULL); + }else { + ms_message("Receiving unhandled RTCP message"); + } + }while(rtcp_next_packet(m)); +} + +static void parse_events(OrtpEvQueue *q){ + OrtpEvent *ev; + while((ev=ortp_ev_queue_get(q))!=NULL){ + OrtpEventData *d=ortp_event_get_data(ev); + switch(ortp_event_get_type(ev)){ + case ORTP_EVENT_RTCP_PACKET_RECEIVED: + parse_rtcp(d->packet); + break; + default: + ms_warning("Unhandled ortp event."); + } + ortp_event_destroy(ev); + } +} + +const char *usage="mediastream --local --remote --payload \n" + "[ --fmtp ]\n" + "[ --jitter ]\n"; +static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate); + + +int main(int argc, char * argv[]) +{ + int i; + int localport=0,remoteport=0,payload=0; + char ip[50]; + const char *fmtp=NULL; + int jitter=50; + int bitrate=0; + bool_t ec=FALSE; + /*create the rtp session */ + ortp_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015); + rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb); + rtp_profile_set_payload(&av_profile,111,&payload_type_speex_wb); + rtp_profile_set_payload(&av_profile,112,&payload_type_ilbc); +#ifdef VIDEO_ENABLED + rtp_profile_set_payload(&av_profile,98,&payload_type_h263_1998); + rtp_profile_set_payload(&av_profile,97,&payload_type_theora); + rtp_profile_set_payload(&av_profile,99,&payload_type_mp4v); + rtp_profile_set_payload(&av_profile,100,&payload_type_x_snow); + rtp_profile_set_payload(&av_profile,102,&payload_type_h264); +#endif + if (argc<4) { + printf(usage); + return -1; + } + for (i=1;i0) pt->normal_bitrate=bitrate; + + if (pt->type!=PAYLOAD_VIDEO){ + printf("Starting audio stream.\n"); + audio=audio_stream_start(profile,localport,remote_ip,remoteport,payload,jitter, ec); + if (audio) session=audio->session; + }else{ +#ifdef VIDEO_ENABLED + printf("Starting video stream.\n"); + video=video_stream_new(localport, ms_is_ipv6(remote_ip)); + + video_stream_start(video,profile, + remote_ip, + remoteport,remoteport+1, + payload, + jitter, + ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get())); + session=video->session; +#else + printf("Error: video support not compiled.\n"); +#endif + } + rtp_session_register_event_queue(session,q); + while(cond) + { + int n; + for(n=0;n<100;++n){ +#ifdef WIN32 + MSG msg; + Sleep(10); + while (PeekMessage(&msg, NULL, 0, 0,1)){ + TranslateMessage(&msg); + DispatchMessage(&msg); + } +#else + struct timespec ts; + ts.tv_sec=0; + ts.tv_nsec=10000000; + nanosleep(&ts,NULL); +#endif +#if defined(VIDEO_ENABLED) + if (video) video_stream_iterate(video); +#endif + } + ortp_global_stats_display(); + if (session){ + printf("Bandwidth usage: download=%f kbits/sec, upload=%f kbits/sec\n", + rtp_session_compute_recv_bandwidth(session)*1e-3, + rtp_session_compute_send_bandwidth(session)*1e-3); + parse_events(q); + } + } + + printf("stoping all...\n"); + + if (audio) audio_stream_stop(audio); +#ifdef VIDEO_ENABLED + if (video) video_stream_stop(video); +#endif + ortp_ev_queue_destroy(q); + rtp_profile_destroy(profile); +} diff --git a/linphone/mediastreamer2/tests/mtudiscover.c b/linphone/mediastreamer2/tests/mtudiscover.c new file mode 100644 index 000000000..92f2285ea --- /dev/null +++ b/linphone/mediastreamer2/tests/mtudiscover.c @@ -0,0 +1,33 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "mediastreamer2/mscommon.h" + +int main(int argc, char *argv[]){ + + ms_init(); + if (argc<2){ + ms_error("Usage: mtudiscover [host]"); + return -1; + } + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + printf("result: %i \n",ms_discover_mtu(argv[1])); + return 0; +} diff --git a/linphone/mediastreamer2/tests/ring.c b/linphone/mediastreamer2/tests/ring.c new file mode 100644 index 000000000..4cbcd27d8 --- /dev/null +++ b/linphone/mediastreamer2/tests/ring.c @@ -0,0 +1,52 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "mediastreamer-config.h" +#endif + +#include "mediastreamer2/mediastream.h" + +int main(int argc, char *argv[]){ + RingStream *r; + const char *file; + MSSndCard *sc; + const char * card_id=NULL; + + ortp_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + ms_init(); + if (argc>1){ + file=argv[1]; + }else file="/usr/share/sounds/linphone/rings/oldphone.wav"; + if (argc>2){ + card_id=argv[2]; + } + + sc=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),card_id); +#ifdef __linux + if (sc==NULL) + sc = ms_alsa_card_new_custom(card_id, card_id); +#endif + + r=ring_start(file,2000,sc); + sleep(10); + ring_stop(r); + return 0; +} diff --git a/linphone/mediastreamer2/tests/videodisplay.c b/linphone/mediastreamer2/tests/videodisplay.c new file mode 100644 index 000000000..9d187ac92 --- /dev/null +++ b/linphone/mediastreamer2/tests/videodisplay.c @@ -0,0 +1,116 @@ +/* +mediastreamer2 library - modular sound and video processing and streaming +Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "mediastreamer2/mediastream.h" +#include "mediastreamer2/msvideoout.h" +#include "mediastreamer2/msv4l.h" + +int main(int argc, char *argv[]){ + VideoStream *vs; + MSWebCam *cam; + int i; + ortp_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + ms_init(); + cam=ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get()); + /* this is to test the sequence start/stop */ + for(i=0;i<1;++i){ + int n; + vs=video_preview_start(cam); + + for(n=0;n<1000;++n){ +#ifdef WIN32 + MSG msg; + Sleep(100); + while (PeekMessage(&msg, NULL, 0, 0,1)){ + TranslateMessage(&msg); + DispatchMessage(&msg); + } +#else + struct timespec ts; + ts.tv_sec=0; + ts.tv_nsec=10000000; + nanosleep(&ts,NULL); + + if (vs) video_stream_iterate(vs); +#endif + +#if 0 /* test code */ + if (n==300) + { + ms_filter_call_method_noarg (vs->source, MS_V4L_STOP); + } + if (n==400) + { + ms_ticker_detach (vs->ticker, vs->source); + + vs->tee = ms_filter_new(MS_TEE_ID); + + ms_filter_unlink(vs->pixconv,0, vs->output,0); + + ms_filter_link(vs->pixconv,0,vs->tee,0); + ms_filter_link(vs->tee,0,vs->output,0); + ms_filter_link(vs->tee,1,vs->output,1); + + //ms_filter_unlink(vs->tee,0,vs->output,0); + ms_ticker_attach (vs->ticker, vs->source); + + } + if (n==500) + { + int corner=1; + ms_filter_call_method(vs->output,MS_VIDEO_OUT_SET_CORNER,&corner); + } + if (n==600) + { + int corner=2; + ms_filter_call_method(vs->output,MS_VIDEO_OUT_SET_CORNER,&corner); + } + if (n==700) + { + int corner=3; + ms_filter_call_method(vs->output,MS_VIDEO_OUT_SET_CORNER,&corner); + } + if (n==800) + { + int corner=-1; + ms_filter_call_method(vs->output,MS_VIDEO_OUT_SET_CORNER,&corner); + } + if (n==900) + { + ms_ticker_detach (vs->ticker, vs->source); + + ms_filter_unlink(vs->pixconv,0,vs->tee,0); + ms_filter_unlink(vs->tee,0,vs->output,0); + ms_filter_unlink(vs->tee,1,vs->output,1); + ms_filter_destroy(vs->tee); + vs->tee=NULL; + + ms_filter_link(vs->pixconv,0, vs->output,0); + + + //ms_filter_unlink(vs->tee,0,vs->output,0); + ms_ticker_attach (vs->ticker, vs->source); + } +#endif + } + video_preview_stop(vs); + } + return 0; +} diff --git a/linphone/oRTP/.cvsignore b/linphone/oRTP/.cvsignore new file mode 100644 index 000000000..8babbdc96 --- /dev/null +++ b/linphone/oRTP/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +ortp-config.h +ortp-config.h.in +ortp.defs +ortp.pc +ortp.spec +stamp-h1 +doc +ortp.doxygen +.settings diff --git a/linphone/oRTP/AUTHORS b/linphone/oRTP/AUTHORS new file mode 100644 index 000000000..6e305d120 --- /dev/null +++ b/linphone/oRTP/AUTHORS @@ -0,0 +1,4 @@ +Simon MORLAT (simon dot morlat at linphone dot org) is the author the oRTP library. + + +Lovadina Nicola < lovadina dot nicola dot 10272 at unimo dot it > worked on RTCP support. diff --git a/linphone/oRTP/COPYING b/linphone/oRTP/COPYING new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/linphone/oRTP/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/linphone/oRTP/ChangeLog b/linphone/oRTP/ChangeLog new file mode 100644 index 000000000..8276cdffa --- /dev/null +++ b/linphone/oRTP/ChangeLog @@ -0,0 +1,153 @@ +2007-07-26 Francois-Xavier Kowalski + + * pkg.list: 1.3 + Do not run makewhatis when installing EPM-generated package. + +2007-04-19 Francois-Xavier Kowalski + + * ortp.spec.in (Requires): 1.4 + Adapt to new documentation generation change from gtk-doc to + Doxygen. + + * Makefile.am (docdir): 1.27 + automake's docdir is not always defined & is generally not + package specific, so we manually define docdir & pkgdocdir. + +2007-03-01 Francois-Xavier Kowalski + + * include/ortp/payloadtype.h: 1.28 + Encompass every declaration (whether lvalue or not) under extern + "C". + +2007-01-18 Francois-Xavier Kowalski + + * oRTP/Makefile.am: 1.24 + Fix RPM package generattion to cope with + + +2006-10-24 Francois-Xavier 'FiX' KOWALSKI + + * include/ortp/port.h: 1.21 + * src/scheduler.h (ortp_get_scheduler): 1.13 + Disable some Intel C/C++ warnings to build with icc. + + * include/ortp/stun_udp.h (__STUN_UDP_H__): 1.6 + * include/ortp/stun.h: 1.6 + Use + +2006-07-10 Francois-Xavier 'FiX' KOWALSKI + + * configure.ac: 1.89 + * gtk-doc.make (dist-check-gtkdoc): 1.1 + Non-fatal but incomplete "make dist" when gtk-doc is not + installed. + +2006-07-07 Francois-Xavier 'FiX' KOWALSKI + + * src/avprofile.c (NORMAL_BITRATE): 1.27 + Use ISO C/99 tagged struct syntax rather than GCC's legacy one. + +2006-07-07 Francois-Xavier Kowalski + + * src/rtpsession.c (RTP_SEQ_IS_GREATER): 1.132 + Fix comment content (using <>) that breaks gtkdoc SGML + generation. + + * include/ortp/event.h: 1.3 + OrtpEventData cannot be a type a s struct at the same time. + + * ortp.spec.in (Requires): 1.2 + Drop glib option + + * gtk-doc.make: + * docs/Makefile.am (#DOC_MAIN_SGML_FILE): 1.7 + * Makefile.am + Use slightly modified gtkdocize. + + * ortp.spec.in (Requires): 1.2 + Force build of gtk-doc, as the default choice that comes with + GTK_DOC_CHECK m4 macro is "no". + +2006-07-06 Francois-Xavier Kowalski + + * src/payloadtype.c (rtp_profile_destroy): 1.20 + avoid double-free + + * configure.ac: 1.88 + ortp-0.10.1.1 + +Friday March 10 2006 : ortp-0.9.1 + - fix package name (was 0.9.0.) + +Wednesday March 8 2006 : ortp-0.9.0 + - a lot of cleanups, glib dropped, win32 port reactivated + +Tuesday December 20 2005 : ortp-0.8.1 + - change session's clockrate dependant parameters upon payload type changed events at socket level + - rtp_session_set_recv_buf_size() added. + - bugfix in rtp_session_set_remote_addr() + - memory leak fixed in rtp_profile_destroy() + +Wednesday December 07 2005: ortp-0.8.0 + - make package modifications + - make rpm added + - add support for different payload types for incoming and outgoing stream (which breaks api compatibility) + - prefix all PayloadType with payload_type_* to avoid naming conflicts + +Wednesday August 24 2005: ortp-0.7.1 + - added patch for pkgconfig support from Jean-Philippe Barrette-LaPierre + +Monday August 8 2005: ortp-0.7.1pre5 + - adaptive jitter buffer improvements + - timestamp compensated packets returned by rtp_session_recvm_with_ts + - new payload definitions. + +Tuesday August 2 2005: ortp-0.7.1pre4 + - adaptive jitter buffer cleanups. + - hton24 utility function added for RTCP + +Tuesday July 4 2005: ortp-0.7.1pre3 + - improve automatic jitter buffer: no more closed-loop; just estimation. + - merge patch for multicast from Samuel Thibault + - merge patch for parsing of rtcp packets from Nicola Baldo + - add static payload definitions for g723.1 and g729. + +Wednesday November 17 2004: ortp-0.7.0 series starts + - add automatic jitter buffer: + * compensate clock slides + * estimate the jitter and sets the minimum jitter compensation delay accordingly + - posix timer simplified + - less system calls: use non blocking recv() and don't use select() or poll() + - add new functions for optimized packet sending + - recv() and send() are always made within the rtp_session_recv..() and rtp_session_send..() + functions. That means that scheduled non blocking mode does no more work as it worked before, ie + that packet will be sent immediately rather than being sent on time by the scheduler as it was before. + - HPUX kernel target removed. + - scheduler always built. + +Tuesday August 12 2003 : ortp-0.6.3 + - some improvements by Aymeric Moizard for Win32 build + - some bug fixes concerning ipv6 support. + +Thursday August 7 2003 : ortp-0.6.2 + - just some minor improvements for using oRTP in a C++ environment. + +Wednesday January 8 2003: ortp-0.6.0 + - many bug fixes by Telisma: the most important bug concerned the windows port. + - some new functionnalities concerning the RTP profiles and payload management. + - ported to glib-2.0 . + +Monday September 23 2002: ortp-0.5.0 + - ortp has been ported to the Microsoft Windows OS (version 2000 and later) by Eloquant + (http://www.eloquant.com) + - some bug fixes and improvements of the windows port have been made by Telisma + (http://www.telisma.com) + +Wednesday June 5 2002: ortp-0.4.4 + - Some crashing bugs fixed. + +Wednesday May 15 2002: ortp-0.4.3 + - Install include files properly. + +Tuesday May 7 2002: ortp-0.4.2 + - First official and public release of oRTP. diff --git a/linphone/oRTP/INSTALL b/linphone/oRTP/INSTALL new file mode 100644 index 000000000..54caf7c19 --- /dev/null +++ b/linphone/oRTP/INSTALL @@ -0,0 +1,229 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/linphone/oRTP/Makefile.am b/linphone/oRTP/Makefile.am new file mode 100644 index 000000000..498efe1ab --- /dev/null +++ b/linphone/oRTP/Makefile.am @@ -0,0 +1,88 @@ +# linphone/oRTP/Makefile.am -- + +EXTRA_DIST = oRTP.prj ortp-config.h.in TODO pkg.list autogen.sh ortp.pc.in ortp.spec.in ortp.spec ortp.doxygen + +SUBDIRS=src build include + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ortp.pc + + +#html doc +if HAVE_DOXYGEN + +# doxdir & pkgdocdir are not always defined by automake +docdir=$(datadir)/doc +pkgdocdir=$(docdir)/$(PACKAGE)-$(VERSION) +doc_htmldir=$(pkgdocdir)/html + +doc_html_DATA = $(top_builddir)/doc/html/html.tar + +$(doc_html_DATA): $(top_builddir)/doc/html/index.html + cd $( + TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz + +# `make package' + +if WITH_EPM + +.PHONY: package + +PKG_NAME = $(PACKAGE)-$(VERSION)-$(RELEASE) +BUILDROOT = $(shell pwd)/epm-install + +package: $(srcdir)/pkg.list $(srcdir)/configure + -rm -rf pkg $(BUILDROOT) $(PKG_NAME).* + $(MAKE) install DESTDIR=$(BUILDROOT) + $(MKEPMLIST) -u $(SYS_USER) -g $(SYS_GROUP) --prefix $(prefix) \ + $(BUILDROOT)/$(prefix) > files.list + $(EPM) -vv -f native -g -n -a $(ARCH) --keep-files --output-dir pkg \ + srcdir=$(srcdir) \ + top_srcdir=$(top_srcdir) \ + top_builddir=$(top_builddir) \ + PACKAGE=$(PACKAGE) \ + SUMMARY="$(SUMMARY)" \ + VERSION=$(ORTP_PKGCONFIG_VERSION) \ + RELEASE=$(RELEASE) \ + LICENSE="$(LICENSE)" \ + VENDOR="$(VENDOR)" \ + PACKAGER="$(PACKAGER)" \ + $(PACKAGE) $(srcdir)/pkg.list + mv -f pkg/$(PACKAGE)-$(ORTP_PKGCONFIG_VERSION)-$(RELEASE).$(EPM_PKG_EXT) $(PKG_NAME).$(ARCH).$(EPM_PKG_EXT) + +clean-local: + rm -rf pkg $(BUILDROOT) + rm -f files.list + rm -rf doc + +endif WITH_EPM + +distclean-local: + -rm -f ortp.defs + +all-local: ortp.spec + +ortp.spec: ortp.spec.in + diff --git a/linphone/oRTP/NEWS b/linphone/oRTP/NEWS new file mode 100644 index 000000000..4d1f4c413 --- /dev/null +++ b/linphone/oRTP/NEWS @@ -0,0 +1,43 @@ +DATE ortp-0.15.0 + - telephone event detection bugfix + - reduce number of memory allocation: !! attention here ABI/API change !! + If you are using mp=rtp_session_recvm_with_ts(), the payload data is no more pointed by mp->b_cont->b_rptr. + Instead you can use the following to skip the header: + rtp_get_payload(mp,mp->b_rptr); + +March 14, 2007: ortp-0.14.3 + - new ortp_set_memory_functions() method + - jitter buffer bugfixes, simplification and improvements + +July 27, 2007: ortp-0.14.0 + - a few optimisations + - support for number of channels in PayloadType (interface changed !) + - srtp optional support (using libsrtp from http://srtp.sf.net) + +April, 11 2007: ortp-0.13.1: + - do not recv rtcp packets from rtp_session_sendm_with_ts() when session is not send-only. + - removed gtk-doc, using doxygen instead. + - minor patches + +January, 23 2007: ortp-0.13.0 + - add support for a pluggable transport layer + - enables use of different RtpProfile for send and recv directions + - fix RTCP memleak + - new telephone-event types added. + +November, 9 2006: ortp-0.12.0 + - fix statistics + - jitter buffer accuracy improved + - enable 0 ms jitter buffer (implies permissive dequeuing of packets) + - enable optional connected mode: the udp socket is connect()ed so only + packets coming from the connected destination are received. + +August, 22 2006: ortp-0.11.0 + - added rtp_session_set_dscp, rtp_session_send_rtcp_APP + - fixed statistics little bugs. + +May, 30 2006: ortp-0.10.0 + - new RTCP parser + - new event api + - stun helper routines + - permissive algorithm for video packet enqueueing diff --git a/linphone/oRTP/README b/linphone/oRTP/README new file mode 100644 index 000000000..be6a82033 --- /dev/null +++ b/linphone/oRTP/README @@ -0,0 +1,58 @@ +What is it ? +************ + +oRTP is a LGPL licensed C library implementing the RTP protocol (rfc3550). It is available +for most unix clones (primilarly Linux and HP-UX), and Microsoft Windows. + +What are the build prequisites ? +******************************** +libc library and header files. + +How do you I test ? +******************* + +There are shorts and easy to understand programs given with the library. There are good example +to understand how to use oRTP api. +- rtpsend : sends a stream from a file on disk. +- rtprecv : receives a stream and writes it to disk. +- mrtpsend: sends multiple streams from a file on disk to a range of remote port. +- mrtprecv: receives mutiple streams on a range of local ports and writes them on disk. + + +Is there some documentation ? +***************************** + +See the doxygen generated API documentation in docs/html. Program examples are a very good +starting point. + + +What are the current features ? +****************************** + - works with ipv6 + - packet scheduler + - adaptive jitter compensation + - automatic sending of RTCP SR or RR coumpounded with a SDES + - RTCP parser API + + +What are the planned features ? +******************************* + - multi-endpoint rtp sessions. + + +In which application oRTP is being used ? +***************************************** + - linphone (http://www.linphone.org) was the first. + - the OCMP platform (a Hewlett Packard product). + +How to compile my program using ortp ? +************************************** +gcc -o myprogram `pkg-config --cflags ortp` myprogram.c \ + `pkg-config --libs ortp` + + +What about Windows port ? +************************* +There are instructions and Microsoft Visual C++ project files in build/win32native/oRTP. + + diff --git a/linphone/oRTP/TODO b/linphone/oRTP/TODO new file mode 100644 index 000000000..ade9114db --- /dev/null +++ b/linphone/oRTP/TODO @@ -0,0 +1,2 @@ +* make statistics thread-safe. +* add a rtp_stats_display() func to display rtp_stats_t properly. diff --git a/linphone/oRTP/autogen.sh b/linphone/oRTP/autogen.sh new file mode 100755 index 000000000..203deb262 --- /dev/null +++ b/linphone/oRTP/autogen.sh @@ -0,0 +1,18 @@ +#!/bin/sh +AM_VERSION="1.9" +if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then + # automake-1.9 (recommended) is not available on Fedora 8 + AUTOMAKE=automake + ACLOCAL=aclocal +else + ACLOCAL=aclocal-${AM_VERSION} + AUTOMAKE=automake-${AM_VERSION} +fi + +set -x +rm -rf config.cache autom4te.cache +$ACLOCAL +autoheader +$AUTOMAKE --add-missing --copy +libtoolize --copy --force +autoconf diff --git a/linphone/oRTP/build/.cvsignore b/linphone/oRTP/build/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/oRTP/build/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/oRTP/build/Makefile.am b/linphone/oRTP/build/Makefile.am new file mode 100644 index 000000000..2a2af13b6 --- /dev/null +++ b/linphone/oRTP/build/Makefile.am @@ -0,0 +1 @@ +SUBDIRS= win32native wince diff --git a/linphone/oRTP/build/win32/.cvsignore b/linphone/oRTP/build/win32/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/oRTP/build/win32/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/oRTP/build/win32native/.cvsignore b/linphone/oRTP/build/win32native/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/oRTP/build/win32native/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/oRTP/build/win32native/Makefile.am b/linphone/oRTP/build/win32native/Makefile.am new file mode 100644 index 000000000..dc2e14b05 --- /dev/null +++ b/linphone/oRTP/build/win32native/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=oRTP.vcproj ortp.def ortp.dev + diff --git a/linphone/oRTP/build/win32native/oRTP.vcproj b/linphone/oRTP/build/win32native/oRTP.vcproj new file mode 100644 index 000000000..f5da64506 --- /dev/null +++ b/linphone/oRTP/build/win32native/oRTP.vcproj @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/oRTP/build/win32native/ortp-dll.dev b/linphone/oRTP/build/win32native/ortp-dll.dev new file mode 100755 index 000000000..336b4e44f --- /dev/null +++ b/linphone/oRTP/build/win32native/ortp-dll.dev @@ -0,0 +1,473 @@ +[Project] +FileName=ortp-dll.dev +Name=ortp +UnitCount=41 +Type=2 +Ver=3 +IsCpp=1 +Folders= +CommandLine= +CompilerSettings=00000000000100000000b0 +PchHead=-1 +PchSource=-1 +ProfilesCount=1 +ProfileIndex=0 + +[Unit1] +FileName=..\..\include\ortp\telephonyevents.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\ortp\ortp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\ortp\payloadtype.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\ortp\port.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\ortp\rtcp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\ortp\rtp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\ortp\rtpsignaltable.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\ortp\sessionset.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\ortp\str_utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\src\avprofile.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\src\jitterctl.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\src\jitterctl.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\src\ortp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\src\payloadtype.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\src\port.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\src\posixtimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\src\rtcp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\src\rtcpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\src\rtpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\src\rtpsession.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\src\rtpsignaltable.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\src\rtptimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\src\rtptimer.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\src\scheduler.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\src\scheduler.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\src\sessionset.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\src\str_utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\src\telephonyevents.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\src\utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\src\utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\src\dll_entry.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\src\ortp-config-win32.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\src\event.c +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\include\ortp\event.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\src\stun.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 +UnitCount=40 + +[Unit37] +FileName=..\..\src\stun_udp.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\src\rtpsession_inet.c +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=0 + +[Unit7] +FileName=..\..\include\ortp\rtpsession.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\src\rtpsession_priv.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\include\ortp\stun.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Profile1] +ProfileName=Default Profile +Type=3 +ObjFiles= +Includes=../../include;. +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DORTP_INET6_@@_-D_WORKAROUND_MINGW32_BUGS _@@_-Wall -Werror _@@_-D_WIN32_WINNT=0x0501_@@_-DORTP_STATIC_@@_ +CppCompiler=_@@_ +Linker=-lws2_32_@@_-liphlpapi_@@_-lwinmm_@@_ +PreprocDefines= +CompilerSettings=00000000000100000000b0 +Icon= +ExeOutput=..\WIN32N~1 +ObjectOutput=Default Profile +OverrideOutput=1 +OverrideOutputName=ortp.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + +[Unit41] +FileName=..\..\src\b64.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= $(CC) -c b64.c -o "Default Profile/b64.o" $(CFLAGS) + diff --git a/linphone/oRTP/build/win32native/ortp-static.dev b/linphone/oRTP/build/win32native/ortp-static.dev new file mode 100755 index 000000000..3a8b15901 --- /dev/null +++ b/linphone/oRTP/build/win32native/ortp-static.dev @@ -0,0 +1,462 @@ +[Project] +FileName=ortp-static.dev +Name=ortp +UnitCount=40 +Type=2 +Ver=3 +IsCpp=1 +Folders= +CommandLine= +CompilerSettings=00000000000100000000b0 +PchHead=-1 +PchSource=-1 +ProfilesCount=1 +ProfileIndex=0 + +[Unit1] +FileName=..\..\include\ortp\telephonyevents.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\ortp\ortp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\ortp\payloadtype.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\ortp\port.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\ortp\rtcp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\ortp\rtp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\ortp\rtpsignaltable.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\ortp\sessionset.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\ortp\str_utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\src\avprofile.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\src\jitterctl.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\src\jitterctl.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\src\ortp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\src\payloadtype.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\src\port.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\src\posixtimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\src\rtcp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\src\rtcpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\src\rtpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\src\rtpsession.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\src\rtpsignaltable.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\src\rtptimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\src\rtptimer.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\src\scheduler.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\src\scheduler.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\src\sessionset.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\src\str_utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\src\telephonyevents.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\src\utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\src\utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\src\dll_entry.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\src\ortp-config-win32.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\src\event.c +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\include\ortp\event.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\src\stun.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 + +[Unit37] +FileName=..\..\src\stun_udp.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\src\rtpsession_inet.c +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=0 + +[Unit7] +FileName=..\..\include\ortp\rtpsession.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\src\rtpsession_priv.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\include\ortp\stun.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Profile1] +ProfileName=Default Profile +Type=2 +ObjFiles= +Includes=../../include;. +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DORTP_INET6_@@_-D_WORKAROUND_MINGW32_BUGS _@@_-Wall -Werror _@@_-D_WIN32_WINNT=0x0501_@@_-DORTP_STATIC_@@_ +CppCompiler=_@@_ +Linker=_@@_ +PreprocDefines= +CompilerSettings=00000000000100000000b0 +Icon= +ExeOutput=..\WIN32N~1 +ObjectOutput=Default Profile +OverrideOutput=1 +OverrideOutputName=libortp.a +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + diff --git a/linphone/oRTP/build/win32native/ortp.def b/linphone/oRTP/build/win32native/ortp.def new file mode 100755 index 000000000..be8988976 --- /dev/null +++ b/linphone/oRTP/build/win32native/ortp.def @@ -0,0 +1,174 @@ +LIBRARY ortp + +EXPORTS + + ortp_init + ortp_scheduler_init + ortp_exit + + ortp_get_scheduler + ortp_set_log_file + ortp_set_log_level_mask + ortp_logv_out + ortp_set_log_handler + ortp_strdup_printf + ortp_logv + + ortp_get_global_stats + ortp_global_stats_display + + session_set_new + session_set_select + session_set_destroy + + rtp_stats_display + rtp_session_get_stats + + rtp_session_init + rtp_session_new + + rtp_session_set_scheduling_mode + rtp_session_set_blocking_mode + rtp_session_set_profile + rtp_session_get_profile + rtp_session_set_data + + rtp_session_signal_connect + rtp_session_signal_disconnect_by_callback + rtp_session_set_ssrc + rtp_session_set_seq_number + rtp_session_get_seq_number + rtp_session_set_jitter_compensation + rtp_session_set_local_addr + rtp_session_set_remote_addr + rtp_session_enable_adaptive_jitter_compensation + rtp_session_set_recv_buf_size + + rtp_session_send_with_ts + rtp_session_sendm_with_ts + + rtp_session_set_sockets + rtp_session_get_rtp_socket + rtp_session_get_rtcp_socket + + rtp_session_set_payload_type + rtp_session_set_send_payload_type + rtp_session_get_send_payload_type + rtp_session_set_recv_payload_type + rtp_session_get_recv_payload_type + + rtp_session_recv_with_ts + rtp_session_recvm_with_ts + rtp_session_create_packet + + rtp_session_get_current_send_ts + rtp_session_get_current_recv_ts + rtp_session_reset + rtp_session_uninit + rtp_session_destroy + + rtp_add_csrc + + rtp_session_send_dtmf + + rtp_session_set_source_description + rtp_session_set_symmetric_rtp + + rtp_profile_new + rtp_profile_set_payload + rtp_profile_clone_full + rtp_profile_destroy + rtp_profile_get_payload_from_rtpmap + + payload_type_set_send_fmtp + payload_type_clone + fmtp_get_value + + ortp_free + ortp_malloc + ortp_strdup + ortp_realloc + ortp_malloc0 + freemsg + dupmsg + + allocb + getq + putq + msgpullup + qinit + flushq + msgdsize + peekq + freeb + dupb + concatb + esballoc + + WIN_thread_create + WIN_thread_join + WIN_cond_init + WIN_mutex_init + WIN_mutex_unlock + WIN_cond_wait + WIN_mutex_lock + WIN_cond_destroy + WIN_mutex_destroy + WIN_cond_signal + + __ortp_log_mask + + rtp_session_register_event_queue + rtp_session_unregister_event_queue + ortp_ev_queue_new + ortp_ev_queue_flush + ortp_ev_queue_get + ortp_ev_queue_destroy + ortp_event_get_type + ortp_event_get_data + ortp_event_destroy + + stunParseHostName + stunParseServerName + sendMessage + stunEncodeMessage + stunBuildReqSimple + stunParseMessage + stunServerProcessMsg + stunNatType + stunTest + stunOpenSocket + stunOpenSocketPair + + getWinSocketError + + rtp_session_set_transports + srtp_transport_new + + ortp_srtp_init + ortp_srtp_create + ortp_srtp_dealloc + ortp_srtp_add_stream + + rtp_session_set_dscp + rtp_session_compute_recv_bandwidth + rtp_session_compute_send_bandwidth + rtcp_next_packet + rtcp_sdes_parse + rtcp_is_SDES + rtcp_SR_get_report_block + rtcp_is_SR + rtcp_is_RR + rtp_session_flush_sockets + rtp_session_resync + rtp_session_set_remote_addr_and_port + rtp_session_set_time_jump_limit + + copymsg + rtp_session_enable_jitter_buffer + + rtp_session_set_rtp_socket_recv_buffer_size + rtp_session_set_rtp_socket_send_buffer_size + rtp_session_set_jitter_buffer_params + + rtp_get_payload diff --git a/linphone/oRTP/build/win32native/ortp.dev b/linphone/oRTP/build/win32native/ortp.dev new file mode 100755 index 000000000..8b0165162 --- /dev/null +++ b/linphone/oRTP/build/win32native/ortp.dev @@ -0,0 +1,449 @@ +[Project] +FileName=ortp.dev +Name=ortp +UnitCount=40 +Type=3 +Ver=1 +ObjFiles= +Includes=../../include;. +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DORTP_EXPORTS _@@_-DBUILDING_DLL=1 _@@_-DORTP_DLL_@@_-DORTP_INET6_@@_-D_WORKAROUND_MINGW32_BUGS -Wall -Werror _@@_-D_WIN32_WINNT=0x0501_@@_ +CppCompiler=-DBUILDING_DLL=1_@@_ +Linker=--no-export-all-symbols --add-stdcall-alias_@@_--def ortp.def_@@_-lws2_32 -lwinmm_@@_ +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=1 +OverrideOutputName=ortp.dll +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=00000000000100000000b0 + +[Unit1] +FileName=..\..\include\ortp\telephonyevents.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\ortp\ortp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\ortp\payloadtype.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\ortp\port.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\ortp\rtcp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\ortp\rtp.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\ortp\rtpsignaltable.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\ortp\sessionset.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\ortp\str_utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\src\avprofile.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\src\jitterctl.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\src\jitterctl.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\src\ortp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\src\payloadtype.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\src\port.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\src\posixtimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\src\rtcp.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\src\rtcpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\src\rtpparse.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\src\rtpsession.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\src\rtpsignaltable.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\src\rtptimer.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\src\rtptimer.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\src\scheduler.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\src\scheduler.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\src\sessionset.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\src\str_utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\src\telephonyevents.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\src\utils.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\src\utils.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\src\dll_entry.c +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\src\ortp-config-win32.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\src\event.c +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\include\ortp\event.h +CompileCpp=0 +Folder=ortp/telephonyevents.h +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\src\stun.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit37] +FileName=..\..\src\stun_udp.c +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\src\rtpsession_inet.c +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=0 + +[Unit7] +FileName=..\..\include\ortp\rtpsession.h +CompileCpp=0 +Folder=ortpdll +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\src\rtpsession_priv.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\include\ortp\stun.h +CompileCpp=0 +Folder=ortp +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/linphone/oRTP/build/wince/.cvsignore b/linphone/oRTP/build/wince/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/oRTP/build/wince/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/oRTP/build/wince/Makefile.am b/linphone/oRTP/build/wince/Makefile.am new file mode 100644 index 000000000..3a96a0bac --- /dev/null +++ b/linphone/oRTP/build/wince/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=oRTP.vcproj ortp.def + diff --git a/linphone/oRTP/build/wince/oRTP.vcproj b/linphone/oRTP/build/wince/oRTP.vcproj new file mode 100644 index 000000000..81e457dc4 --- /dev/null +++ b/linphone/oRTP/build/wince/oRTP.vcproj @@ -0,0 +1,1019 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/oRTP/build/wince/ortp.def b/linphone/oRTP/build/wince/ortp.def new file mode 100644 index 000000000..f51512c82 --- /dev/null +++ b/linphone/oRTP/build/wince/ortp.def @@ -0,0 +1,163 @@ +LIBRARY ortp + +EXPORTS + + ortp_init + ortp_scheduler_init + ortp_exit + + ortp_get_scheduler + ortp_set_log_file + ortp_set_log_level_mask + ortp_logv_out + ortp_set_log_handler + ortp_strdup_printf + ortp_logv + + ortp_get_global_stats + ortp_global_stats_display + + session_set_new + session_set_select + session_set_destroy + + rtp_stats_display + rtp_session_get_stats + + rtp_session_init + rtp_session_new + + rtp_session_set_scheduling_mode + rtp_session_set_blocking_mode + rtp_session_set_profile + rtp_session_get_profile + rtp_session_set_data + + rtp_session_signal_connect + rtp_session_signal_disconnect_by_callback + rtp_session_set_ssrc + rtp_session_set_seq_number + rtp_session_get_seq_number + rtp_session_set_jitter_compensation + rtp_session_set_local_addr + rtp_session_set_remote_addr + rtp_session_enable_adaptive_jitter_compensation + rtp_session_set_recv_buf_size + + rtp_session_send_with_ts + rtp_session_sendm_with_ts + + rtp_session_set_sockets + rtp_session_get_rtp_socket + rtp_session_get_rtcp_socket + + rtp_session_set_payload_type + rtp_session_set_send_payload_type + rtp_session_get_send_payload_type + rtp_session_set_recv_payload_type + rtp_session_get_recv_payload_type + + rtp_session_recv_with_ts + rtp_session_recvm_with_ts + rtp_session_create_packet + + rtp_session_get_current_send_ts + rtp_session_get_current_recv_ts + rtp_session_reset + rtp_session_uninit + rtp_session_destroy + + rtp_add_csrc + + rtp_session_send_dtmf + + rtp_session_set_source_description + rtp_session_set_symmetric_rtp + + rtp_profile_new + rtp_profile_set_payload + rtp_profile_clone_full + rtp_profile_destroy + rtp_profile_get_payload_from_rtpmap + + payload_type_set_send_fmtp + payload_type_clone + fmtp_get_value + + ortp_free + ortp_malloc + ortp_strdup + ortp_realloc + ortp_malloc0 + freemsg + dupmsg + + allocb + getq + putq + msgpullup + qinit + flushq + msgdsize + peekq + freeb + dupb + concatb + + WIN_thread_create + WIN_thread_join + WIN_cond_init + WIN_mutex_init + WIN_mutex_unlock + WIN_cond_wait + WIN_mutex_lock + WIN_cond_destroy + WIN_mutex_destroy + WIN_cond_signal + + __ortp_log_mask + + rtp_session_register_event_queue + rtp_session_unregister_event_queue + ortp_ev_queue_new + ortp_ev_queue_flush + ortp_ev_queue_get + ortp_ev_queue_destroy + ortp_event_get_type + ortp_event_get_data + ortp_event_destroy + + stunParseHostName + stunParseServerName + sendMessage + stunEncodeMessage + stunBuildReqSimple + stunParseMessage + stunServerProcessMsg + stunNatType + stunTest + stunOpenSocket + stunOpenSocketPair + + getWinSocketError + + rtp_session_set_dscp + esballoc + + rtp_session_flush_sockets + rtp_session_resync + rtp_session_set_remote_addr_and_port + rtp_session_resync + rtp_session_set_time_jump_limit + + copymsg + rtp_session_enable_jitter_buffer + + rtp_session_compute_recv_bandwidth + rtp_session_compute_send_bandwidth + + rtp_session_set_rtp_socket_recv_buffer_size + rtp_session_set_rtp_socket_send_buffer_size + rtp_session_set_jitter_buffer_params + + rtp_get_payload diff --git a/linphone/oRTP/configure.ac b/linphone/oRTP/configure.ac new file mode 100644 index 000000000..6feb26f64 --- /dev/null +++ b/linphone/oRTP/configure.ac @@ -0,0 +1,331 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT([ortp],[0.15.0]) +AC_CANONICAL_SYSTEM + +dnl Source packaging numbers +ORTP_MAJOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f1) +ORTP_MINOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f2) +ORTP_MICRO_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f3) +ORTP_EXTRA_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f4) + +LIBORTP_SO_CURRENT=8 dnl increment this number when you add/change/remove an interface +LIBORTP_SO_REVISION=0 dnl increment this number when you change source code, without changing interfaces; set to 0 when incrementing CURRENT +LIBORTP_SO_AGE=0 dnl increment this number when you add an interface, set to 0 if you remove an interface + +LIBORTP_SO_VERSION=$LIBORTP_SO_CURRENT:$LIBORTP_SO_REVISION:$LIBORTP_SO_AGE +ORTP_VERSION=${ORTP_MAJOR_VERSION}.${ORTP_MINOR_VERSION}.${ORTP_MICRO_VERSION} + +if test -n "$ORTP_EXTRA_VERSION" ; then + ORTP_VERSION="${ORTP_VERSION}.${ORTP_EXTRA_VERSION}" +fi + +ORTP_PKGCONFIG_VERSION=${ORTP_VERSION} + +AC_SUBST(LIBORTP_SO_VERSION) +AC_SUBST(ORTP_VERSION) +AC_SUBST(ORTP_PKGCONFIG_VERSION) + + +PACKAGE=ortp + +AM_INIT_AUTOMAKE([tar-ustar]) +AC_CONFIG_HEADERS(ortp-config.h) +AC_DEFINE_UNQUOTED(ORTP_MAJOR_VERSION,$ORTP_MAJOR_VERSION, [major version]) +AC_DEFINE_UNQUOTED(ORTP_MINOR_VERSION,$ORTP_MINOR_VERSION, [minor version]) +AC_DEFINE_UNQUOTED(ORTP_MICRO_VERSION,$ORTP_MICRO_VERSION, [micro version]) +AC_DEFINE_UNQUOTED(ORTP_VERSION,"$ORTP_VERSION",[ortp version number]) + +AC_SUBST([mkdir_p]) + +AC_MSG_CHECKING([warning make an error on compilation]) +AC_ARG_ENABLE(strict, +[ --enable-strict Enable error on compilation warning [default=yes]], +[wall_werror=$enableval], +[wall_werror=yes] +) + +AC_ARG_ENABLE(perf, +[ --enable-perf Disable costly features to reduce cpu consumtion [default=no]], +[perf=$enableval], +[perf=no] +) + +ORTP_DEFS= + +dnl enable ipv6 support +AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Turn on ipv6 support], + [case "${enableval}" in + yes) ipv6=true;; + no) ipv6=false;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ipv6) ;; + esac],[ipv6=true]) +if test x$ipv6 = xtrue ; then + ORTP_DEFS="$ORTP_DEFS -DORTP_INET6" +fi + +AC_ARG_ENABLE(mode64bit, + [ --enable-mode64bit=[yes/no] produce a 64-bit library. [default=no]], + [case "${enableval}" in + yes) mode64bit_enabled=yes;; + no) mode64bit_enabled=no;; + *) AC_MSG_ERROR("Bad value for --enable-mode64bit");; + esac], + [mode64bit_enabled=no]) + +AC_ARG_ENABLE(debug, + [ --enable-debug=[yes/no] enables the display of traces showing the execution of the library. [default=yes]], + [case "${enableval}" in + yes) debug_enabled=yes;; + no) debug_enabled=no;; + *) AC_MSG_ERROR("Bad value for --enable-debug");; + esac], + [debug_enabled=no]) + + +hpux_host=no +posixtimer_interval=10000 +PTHREAD_LDFLAGS= + +case "$target_os" in + *hpux*) + hpux_host=yes + AC_DEFINE(NOCONNECT,1,[Defined if we should not use connect() on udp sockets]) + CFLAGS="$CFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=199506L" + LIBS="$LIBS -lxnet" + ;; + *freebsd*) + AC_DEFINE(NOCONNECT,1,[Defined if we should not use connect() on udp sockets]) + PTHREAD_LDFLAGS="-pthread" + ;; +esac + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) + +if test "$GCC" != "yes" ; then + if test "$hpux_host" = "yes" ; then + dnl we are probably using HPUX cc compiler, so add a +O2 to CFLAGS + CFLAGS="$CFLAGS +O2 -g " + if test x$mode64bit_enabled = xyes ; then + CFLAGS="$CFLAGS +DA2.0W +DS2.0" + fi + fi +else + CFLAGS="$CFLAGS -Wall" +fi + +build_scheduler=yes + +dnl Check if we have seteuid system call +AC_CHECK_FUNCS(seteuid) + + +dnl check if we can use the pthread_library +AC_CHECK_LIB(pthread, pthread_mutex_init, [pthread_enabled=yes], [pthread_enabled=no]) +if test $pthread_enabled = "no" ; then + build_scheduler=no +else + PTHREAD_LIBS="-lpthread" + PTHREAD_CFLAGS="-D_REENTRANT" + AC_SUBST(PTHREAD_CFLAGS) + AC_SUBST(PTHREAD_LIBS) + AC_SUBST(PTHREAD_LDFLAGS) +fi +AC_ARG_WITH(thread-stack-size, + AC_HELP_STRING([--with-thread-stack-size=SIZE-IN-BYTES],[Set thread stack size [[default=os-default]]]), + [thread_stack_size=$withval], [thread_stack_size=0]) +AC_DEFINE_UNQUOTED(ORTP_DEFAULT_THREAD_STACK_SIZE, $thread_stack_size, [Default thread stack size (0 = let operating system decide)]) + + +dnl check for libsrtp support (secure rtp) +AC_ARG_WITH( srtp, + [ --with-srtp Set prefix where libsrtp can be found (ex:/usr or /usr/local)[default=/usr] ], + [ srtp_prefix=${withval}],[ srtp_prefix=/usr ]) + + +if test "${srtp_prefix}" != "/usr" ; then + SRTP_CFLAGS="-I${srtp_prefix}/include" + SRTP_LIBS="-L${srtp_prefix}/lib" +fi +SRTP_LIBS="$SRTP_LIBS -lsrtp" + +dnl check srtp headers +have_srtp=no +CPPFLAGS_save=$CPPFLAGS +CPPFLAGS=$SRTP_CFLAGS +AC_CHECK_HEADER([srtp/srtp.h],have_srtp_headers=yes) +CPPFLAGS=$CPPFLAGS_save + +dnl check for srtp lib +LDFLAGS_save=$LDFLAGS +LDFLAGS=$SRTP_LIBS +LIBS_save=$LIBS +AC_CHECK_LIB(srtp,srtp_init,have_srtp_lib=yes) +LDFLAGS=$LDFLAGS_save +LIBS=$LIBS_save + +if test "$have_srtp_headers$have_srtp_lib" = "yesyes" ; then + have_srtp=yes + AC_DEFINE(HAVE_SRTP, 1, [Defined when srtp support is compiled]) +else + AC_MSG_NOTICE([Could not find libsrtp headers or lib, cryto transport disabled.]) + SRTP_CFLAGS= + SRTP_LIBS= +fi + +AC_SUBST(SRTP_CFLAGS) +AC_SUBST(SRTP_LIBS) + +if test $debug_enabled = "yes"; then + ORTP_DEFS="$ORTP_DEFS -DORTP_DEBUG_MODE -g" + CFLAGS=`echo $CFLAGS | sed 's/-O.//'` +fi + +AC_ARG_ENABLE(memcheck, + [ --enable-memcheck=[yes/no] enables memory leak detection (HPUX only).], + [case "${enableval}" in + yes) memcheck_enabled=yes;; + no) memcheck_enabled=no;; + *) AC_MSG_ERROR("Bad value for --enable-memcheck");; + esac], + [memcheck_enabled=no]) + +if test "$memcheck_enabled" = "yes" ; then + if test "$hpux_host" = "yes" ; then + AC_DEFINE(ENABLE_MEMCHECK,1,[Defined when memory leak checking if enabled]) + else + echo "WARNING ************ : the memory check option is only available for HPUX." + fi +fi + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(poll.h sys/poll.h sys/uio.h fcntl.h sys/time.h unistd.h sys/audio.h linux/soundcard.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_HEADER_TIME +AC_WORDS_BIGENDIAN +if test x$ac_cv_c_bigendian = xyes ; then + ORTP_DEFS="$ORTP_DEFS -DORTP_BIGENDIAN" +fi + +dnl Checks for library functions. +AC_CHECK_FUNCS(select socket strerror) + +if test $hpux_host = "yes" ; then +dnl it seems 10 ms is too fast on hpux and it causes trouble + posixtimer_interval=20000 +fi + +AC_DEFINE_UNQUOTED(POSIXTIMER_INTERVAL,$posixtimer_interval,[Defines the periodicity of the rtp scheduler in microseconds]) + +if test "$perf" = "yes" ; then + CFLAGS="$CFLAGS -DPERF" +fi + +if test $GCC = yes && test $wall_werror = yes; then + CFLAGS="$CFLAGS -Werror " +fi + +ORTPDEPS_LIBS="$ORTPDEPS_LIBS $PTHREAD_LIBS $PTHREAD_LDFLAGS $SRTP_LIBS" +ORTPDEPS_CFLAGS="$ORTPDEPS_CFLAGS $PTHREAD_CFLAGS $ORTP_DEFS $SRTP_CFLAGS" +CFLAGS="$CFLAGS $ORTP_DEFS" +echo "$ORTPDEPS_CFLAGS" > ortp.defs + + +dnl ################################################## +dnl # Check for gtk-doc. +dnl ################################################## + +AC_PATH_PROG(DOXYGEN,doxygen,false) +AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false) + + +dnl ################################################## +dnl # Check for ESP Packager +dnl ################################################## + +AC_PATH_PROG(EPM,epm,false) +AC_PATH_PROG(MKEPMLIST,mkepmlist,false) +AC_PATH_PROG(EPMINSTALL,epminstall,false) +AM_CONDITIONAL(WITH_EPM,test $EPM != false && test $MKEPMLIST != false && test $EPMINSTALL != false) + + +# Preferred packaging system, as per EPM terminology +case $target in +*-*-linux*) + if test -f /etc/debian_version ; then + EPM_PKG_EXT=deb + else + EPM_PKG_EXT=rpm + fi + ;; +*-hp-hpux*) + EPM_PKG_EXT=depot.gz;; +*-dec-osf*) + EPM_PKG_EXT=setld;; +esac +AC_SUBST(EPM_PKG_EXT) + +# System software User & Group names +case $target in +*-*-linux*) + SYS_USER=root + SYS_GROUP=root + ;; +*-*-hpux*|*-dec-osf*) + SYS_USER=bin + SYS_GROUP=bin + ;; +esac +AC_SUBST(SYS_USER) +AC_SUBST(SYS_GROUP) + +# CPU Architecture +case $target_cpu in +i?86) ARCH=i386;; +*) ARCH=$target_cpu;; +esac +AC_SUBST(ARCH) + +# Various other packaging variables, that can be over-ridden ad `make +# package' time +SUMMARY="An LGPL implementation of RTP - RFC3550" +AC_SUBST(SUMMARY) +PACKAGER=anonymous +AC_SUBST(PACKAGER) +LICENSE=LGPL +AC_SUBST(LICENSE) +VENDOR=Linphone +AC_SUBST(VENDOR) +RELEASE=1 +AC_SUBST(RELEASE) + +AC_SUBST(ORTPDEPS_CFLAGS) +AC_SUBST(ORTPDEPS_LIBS) +AC_SUBST(ORTPDEPS_LDFLAGS) + +AC_OUTPUT( +Makefile +include/Makefile +include/ortp/Makefile +src/Makefile +src/tests/Makefile +src/tests/win_receiver/Makefile +src/tests/win_sender/Makefile +build/Makefile +build/win32native/Makefile +build/wince/Makefile +ortp.pc +ortp.spec +ortp.doxygen +) + +AC_MSG_WARN([ortp-0.15.0 breaks compatibility with older releases, because value returned by rtp_session_recvm_with_ts() has + changed. See the API documentation in doc/ for further readings.]) diff --git a/linphone/oRTP/docs/.cvsignore b/linphone/oRTP/docs/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/oRTP/docs/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/oRTP/include/.cvsignore b/linphone/oRTP/include/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/oRTP/include/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/oRTP/include/Makefile.am b/linphone/oRTP/include/Makefile.am new file mode 100644 index 000000000..ca785d102 --- /dev/null +++ b/linphone/oRTP/include/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=ortp diff --git a/linphone/oRTP/include/ortp/.cvsignore b/linphone/oRTP/include/ortp/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/oRTP/include/ortp/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/oRTP/include/ortp/Makefile.am b/linphone/oRTP/include/ortp/Makefile.am new file mode 100644 index 000000000..c8f0133f1 --- /dev/null +++ b/linphone/oRTP/include/ortp/Makefile.am @@ -0,0 +1,11 @@ + + +ortp_includedir=$(includedir)/ortp + +ortp_include_HEADERS=str_utils.h rtpsession.h rtp.h port.h \ + ortp.h telephonyevents.h sessionset.h payloadtype.h rtpsignaltable.h \ + rtcp.h \ + event.h stun.h stun_udp.h srtp.h \ + b64.h + +EXTRA_DIST=$(ortp_include_HEADERS) diff --git a/linphone/oRTP/include/ortp/b64.h b/linphone/oRTP/include/ortp/b64.h new file mode 100644 index 000000000..f2ce4578a --- /dev/null +++ b/linphone/oRTP/include/ortp/b64.h @@ -0,0 +1,420 @@ +/* ///////////////////////////////////////////////////////////////////////////// + * File: b64/b64.h + * + * Purpose: Header file for the b64 library + * + * Created: 18th October 2004 + * Updated: 24th August 2008 + * + * Thanks: To Adam McLaurin, for ideas regarding the b64_decode2() and + * b64_encode2(). + * + * Home: http://synesis.com.au/software/ + * + * Copyright (c) 2004-2008, Matthew Wilson and Synesis Software + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of + * any contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * ////////////////////////////////////////////////////////////////////////// */ + + +/** \file b64/b64.h + * + * \brief [C/C++] Header file for the b64 library. + */ + +#ifndef B64_INCL_B64_H_B64 +#define B64_INCL_B64_H_B64 + +/* ///////////////////////////////////////////////////////////////////////////// + * Version information + */ + +#ifndef B64_DOCUMENTATION_SKIP_SECTION +# define B64_VER_B64_H_B64_MAJOR 1 +# define B64_VER_B64_H_B64_MINOR 5 +# define B64_VER_B64_H_B64_REVISION 4 +# define B64_VER_B64_H_B64_EDIT 28 +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ + +/** \def B64_VER_MAJOR + * The major version number of b64 + */ + +/** \def B64_VER_MINOR + * The minor version number of b64 + */ + +/** \def B64_VER_REVISION + * The revision version number of b64 + */ + +/** \def B64_VER + * The current composite version number of b64 + */ + +#ifndef B64_DOCUMENTATION_SKIP_SECTION +# define B64_VER_1_0_1 0x01000100 +# define B64_VER_1_0_2 0x01000200 +# define B64_VER_1_0_3 0x01000300 +# define B64_VER_1_1_1 0x01010100 +# define B64_VER_1_1_2 0x01010200 +# define B64_VER_1_1_3 0x01010300 +# define B64_VER_1_2_1 0x01020100 +# define B64_VER_1_2_2 0x01020200 +# define B64_VER_1_2_3 0x01020300 +# define B64_VER_1_2_4 0x01020400 +# define B64_VER_1_2_5 0x01020500 +# define B64_VER_1_2_6 0x01020600 +# define B64_VER_1_2_7 0x01020700 +# define B64_VER_1_3_1 0x010301ff +# define B64_VER_1_3_2 0x010302ff +# define B64_VER_1_3_3 0x010303ff +# define B64_VER_1_3_4 0x010304ff + +# define B64_VER B64_VER_1_3_4 +#else /* ? B64_DOCUMENTATION_SKIP_SECTION */ +# define B64_VER 0x010304ff +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ + +#define B64_VER_MAJOR 1 +#define B64_VER_MINOR 3 +#define B64_VER_REVISION 4 + +/* ///////////////////////////////////////////////////////////////////////////// + * Includes + */ + +#include + +/* ///////////////////////////////////////////////////////////////////////////// + * Namespace + */ + +#if !defined(B64_NO_NAMESPACE) && \ + !defined(__cplusplus) +# define B64_NO_NAMESPACE +#endif /* !B64_NO_NAMESPACE && !__cplusplus */ + +#ifdef B64_NAMESPACE +# undef B64_NAMESPACE +#endif /* B64_NAMESPACE */ + +#ifdef B64_NAMESPACE_QUALIFIER +# undef B64_NAMESPACE_QUALIFIER +#endif /* B64_NAMESPACE_QUALIFIER */ + + +#ifndef B64_NO_NAMESPACE + +# ifdef B64_CUSTOM_NAMESPACE +# define B64_NAMESPACE B64_CUSTOM_NAMESPACE +# else /* ? B64_CUSTOM_NAMESPACE */ +# define B64_NAMESPACE b64 +# endif /* B64_CUSTOM_NAMESPACE */ + +# if defined(B64_CUSTOM_NAMESPACE) && \ + defined(B64_CUSTOM_NAMESPACE_QUALIFIER) +# define B64_NAMESPACE_QUALIFIER B64_CUSTOM_NAMESPACE_QUALIFIER +# else /* B64_CUSTOM_NAMESPACE && B64_CUSTOM_NAMESPACE_QUALIFIER */ +# define B64_NAMESPACE_QUALIFIER ::B64_NAMESPACE +# endif /* B64_CUSTOM_NAMESPACE && B64_CUSTOM_NAMESPACE_QUALIFIER */ + + +/** \brief [C/C++] The b64 namespace, within which the core library types and functions + * reside in C++ compilation. In C compilation, they all reside in the global + * namespace. + * + * \htmlonly + *


+ * \endhtmlonly + */ +namespace B64_NAMESPACE +{ +#endif /* !B64_NO_NAMESPACE */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Enumerations + */ + +/** \brief Return codes (from b64_encode2() / b64_decode2()) + */ +enum B64_RC +{ + B64_RC_OK = 0 /*!< Operation was successful. */ + , B64_RC_INSUFFICIENT_BUFFER = 1 /*!< The given translation buffer was not of sufficient size. */ + , B64_RC_TRUNCATED_INPUT = 2 /*!< The input did not represent a fully formed stream of octet couplings. */ + , B64_RC_DATA_ERROR = 3 /*!< Invalid data. */ +#ifndef B64_DOCUMENTATION_SKIP_SECTION + , B64_max_RC_value +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ +}; + +#ifndef __cplusplus +typedef enum B64_RC B64_RC; +#endif /* !__cplusplus */ + +/** \brief Coding behaviour modification flags (for b64_encode2() / b64_decode2()) + */ +enum B64_FLAGS +{ + B64_F_LINE_LEN_USE_PARAM = 0x0000 /*!< Uses the lineLen parameter to b64_encode2(). Ignored by b64_decode2(). */ + , B64_F_LINE_LEN_INFINITE = 0x0001 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is infinite. Ignored by b64_decode2(). */ + , B64_F_LINE_LEN_64 = 0x0002 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is 64. Ignored by b64_decode2(). */ + , B64_F_LINE_LEN_76 = 0x0003 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is 76. Ignored by b64_decode2(). */ + , B64_F_LINE_LEN_MASK = 0x000f /*!< Mask for testing line length flags to b64_encode2(). Ignored by b64_encode2(). */ + , B64_F_STOP_ON_NOTHING = 0x0000 /*!< Decoding ignores all invalid characters in the input data. Ignored by b64_encode2(). */ + , B64_F_STOP_ON_UNKNOWN_CHAR = 0x0100 /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/], non-whitespace character is encountered. Ignored by b64_encode2(). */ + , B64_F_STOP_ON_UNEXPECTED_WS = 0x0200 /*!< Causes decoding to break if any unexpected whitespace is encountered. Ignored by b64_encode2(). */ + , B64_F_STOP_ON_BAD_CHAR = 0x0300 /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/] character is encountered. Ignored by b64_encode2(). */ +}; + +#ifndef __cplusplus +typedef enum B64_FLAGS B64_FLAGS; +#endif /* !__cplusplus */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Functions + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** \brief Encodes a block of binary data into Base-64 + * + * \param src Pointer to the block to be encoded. May not be NULL, except when + * \c dest is NULL, in which case it is ignored. + * \param srcSize Length of block to be encoded + * \param dest Pointer to the buffer into which the result is to be written. May + * be NULL, in which case the function returns the required length + * \param destLen Length of the buffer into which the result is to be written. Must + * be at least as large as that indicated by the return value from + * \link b64::b64_encode b64_encode(NULL, srcSize, NULL, 0)\endlink. + * + * \return 0 if the size of the buffer was insufficient, or the length of the + * converted buffer was longer than \c destLen + * + * \note The function returns the required length if \c dest is NULL + * + * \note The function returns the required length if \c dest is NULL. The returned size + * might be larger than the actual required size, but will never be smaller. + * + * \note Threading: The function is fully re-entrant. + * + * \see b64::encode() + */ +size_t b64_encode(void const *src, size_t srcSize, char *dest, size_t destLen); + +/** \brief Encodes a block of binary data into Base-64 + * + * \param src Pointer to the block to be encoded. May not be NULL, except when + * \c dest is NULL, in which case it is ignored. + * \param srcSize Length of block to be encoded + * \param dest Pointer to the buffer into which the result is to be written. May + * be NULL, in which case the function returns the required length + * \param destLen Length of the buffer into which the result is to be written. Must + * be at least as large as that indicated by the return value from + * \link b64::b64_encode2 b64_encode2(NULL, srcSize, NULL, 0, flags, lineLen, rc)\endlink. + * \param flags A combination of the B64_FLAGS enumeration, that moderate the + * behaviour of the function + * \param lineLen If the flags parameter contains B64_F_LINE_LEN_USE_PARAM, then + * this parameter represents the length of the lines into which the encoded form is split, + * with a hard line break ('\\r\\n'). If this value is 0, then the line is not + * split. If it is <0, then the RFC-1113 recommended line length of 64 is used + * \param rc The return code representing the status of the operation. May be NULL. + * + * \return 0 if the size of the buffer was insufficient, or the length of the + * converted buffer was longer than \c destLen + * + * \note The function returns the required length if \c dest is NULL. The returned size + * might be larger than the actual required size, but will never be smaller. + * + * \note Threading: The function is fully re-entrant. + * + * \see b64::encode() + */ +size_t b64_encode2( void const *src + , size_t srcSize + , char *dest + , size_t destLen + , unsigned flags + , int lineLen /* = 0 */ + , B64_RC *rc /* = NULL */); + +/** \brief Decodes a sequence of Base-64 into a block of binary data + * + * \param src Pointer to the Base-64 block to be decoded. May not be NULL, except when + * \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is + * not NULL, then the returned value is calculated exactly, otherwise a value + * is returned that is guaranteed to be large enough to hold the decoded block. + * + * \param srcLen Length of block to be encoded. Must be an integral of 4, the Base-64 + * encoding quantum, otherwise the Base-64 block is assumed to be invalid + * \param dest Pointer to the buffer into which the result is to be written. May + * be NULL, in which case the function returns the required length + * \param destSize Length of the buffer into which the result is to be written. Must + * be at least as large as that indicated by the return value from + * \c b64_decode(src, srcSize, NULL, 0), even in the case where the encoded form + * contains a number of characters that will be ignored, resulting in a lower total + * length of converted form. + * + * \return 0 if the size of the buffer was insufficient, or the length of the + * converted buffer was longer than \c destSize + * + * \note The function returns the required length if \c dest is NULL. The returned size + * might be larger than the actual required size, but will never be smaller. + * + * \note \anchor anchor__4_characters The behaviour of both + * \link b64::b64_encode2 b64_encode2()\endlink + * and + * \link b64::b64_decode2 b64_decode2()\endlink + * are undefined if the line length is not a multiple of 4. + * + * \note Threading: The function is fully re-entrant. + * + * \see b64::decode() + */ +size_t b64_decode(char const *src, size_t srcLen, void *dest, size_t destSize); + +/** \brief Decodes a sequence of Base-64 into a block of binary data + * + * \param src Pointer to the Base-64 block to be decoded. May not be NULL, except when + * \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is + * not NULL, then the returned value is calculated exactly, otherwise a value + * is returned that is guaranteed to be large enough to hold the decoded block. + * + * \param srcLen Length of block to be encoded. Must be an integral of 4, the Base-64 + * encoding quantum, otherwise the Base-64 block is assumed to be invalid + * \param dest Pointer to the buffer into which the result is to be written. May + * be NULL, in which case the function returns the required length + * \param destSize Length of the buffer into which the result is to be written. Must + * be at least as large as that indicated by the return value from + * \c b64_decode(src, srcSize, NULL, 0), even in the case where the encoded form + * contains a number of characters that will be ignored, resulting in a lower total + * length of converted form. + * \param flags A combination of the B64_FLAGS enumeration, that moderate the + * behaviour of the function. + * \param rc The return code representing the status of the operation. May be NULL. + * \param badChar If the flags parameter does not contain B64_F_STOP_ON_NOTHING, this + * parameter specifies the address of a pointer that will be set to point to any + * character in the sequence that stops the parsing, as dictated by the flags + * parameter. May be NULL. + * + * \return 0 if the size of the buffer was insufficient, or the length of the + * converted buffer was longer than \c destSize, or a bad character stopped parsing. + * + * \note The function returns the required length if \c dest is NULL. The returned size + * might be larger than the actual required size, but will never be smaller. + * + * \note The behaviour of both + * \link b64::b64_encode2 b64_encode2()\endlink + * and + * \link b64::b64_decode2 b64_decode2()\endlink + * are undefined if the line length is not a multiple of 4. + * + * \note Threading: The function is fully re-entrant. + * + * \see b64::decode() + */ +size_t b64_decode2( char const *src + , size_t srcLen + , void *dest + , size_t destSize + , unsigned flags + , char const **badChar /* = NULL */ + , B64_RC *rc /* = NULL */); + + +/** \brief Returns the textual description of the error + * + * \param code The \link b64::B64_RC error code\endlink + */ +char const *b64_getErrorString(B64_RC code); + +/** \brief Returns the length of the textual description of the error + * + * \see b64_getErrorString() + * + * \param code The \link b64::B64_RC error code\endlink + */ +size_t b64_getErrorStringLength(B64_RC code); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Namespace + */ + +#ifndef B64_NO_NAMESPACE +} /* namespace B64_NAMESPACE */ + +# ifndef B64_DOCUMENTATION_SKIP_SECTION + +namespace stlsoft +{ + + inline char const *c_str_data_a( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorString(code); + } + inline char const *c_str_data( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorString(code); + } + + inline size_t c_str_len_a( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorStringLength(code); + } + inline size_t c_str_len( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorStringLength(code); + } + + inline char const *c_str_ptr_a( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorString(code); + } + inline char const *c_str_ptr( B64_NAMESPACE_QUALIFIER::B64_RC code) + { + return B64_NAMESPACE_QUALIFIER::b64_getErrorString(code); + } + +} /* namespace stlsoft */ + +# endif /* !B64_DOCUMENTATION_SKIP_SECTION */ + +#endif /* !B64_NO_NAMESPACE */ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#endif /* B64_INCL_B64_H_B64 */ + +/* ////////////////////////////////////////////////////////////////////////// */ diff --git a/linphone/oRTP/include/ortp/event.h b/linphone/oRTP/include/ortp/event.h new file mode 100644 index 000000000..071d417d6 --- /dev/null +++ b/linphone/oRTP/include/ortp/event.h @@ -0,0 +1,85 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef ortp_events_h +#define ortp_events_h + +#include + +typedef mblk_t OrtpEvent; + +typedef unsigned long OrtpEventType; + +typedef struct RtpEndpoint{ +#ifdef ORTP_INET6 + struct sockaddr_storage addr; +#else + struct sockaddr addr; +#endif + socklen_t addrlen; +}RtpEndpoint; + + +struct _OrtpEventData{ + mblk_t *packet; /* most events are associated to a received packet */ + RtpEndpoint *ep; + union { + int telephone_event; + int payload_type; + } info; +}; + +typedef struct _OrtpEventData OrtpEventData; + + + +#ifdef __cplusplus +extern "C"{ +#endif + +RtpEndpoint *rtp_endpoint_new(struct sockaddr *addr, socklen_t addrlen); +RtpEndpoint *rtp_endpoint_dup(const RtpEndpoint *ep); + +OrtpEvent * ortp_event_new(OrtpEventType tp); +OrtpEventType ortp_event_get_type(const OrtpEvent *ev); +/* type is one of the following*/ +#define ORTP_EVENT_STUN_PACKET_RECEIVED 1 +#define ORTP_EVENT_PAYLOAD_TYPE_CHANGED 2 +#define ORTP_EVENT_TELEPHONE_EVENT 3 +#define ORTP_EVENT_RTCP_PACKET_RECEIVED 4 +OrtpEventData * ortp_event_get_data(OrtpEvent *ev); +void ortp_event_destroy(OrtpEvent *ev); +OrtpEvent *ortp_event_dup(OrtpEvent *ev); + +typedef struct OrtpEvQueue{ + queue_t q; + ortp_mutex_t mutex; +} OrtpEvQueue; + +OrtpEvQueue * ortp_ev_queue_new(void); +void ortp_ev_queue_destroy(OrtpEvQueue *q); +OrtpEvent * ortp_ev_queue_get(OrtpEvQueue *q); +void ortp_ev_queue_flush(OrtpEvQueue * qp); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/linphone/oRTP/include/ortp/ortp.h b/linphone/oRTP/include/ortp/ortp.h new file mode 100644 index 000000000..8176af523 --- /dev/null +++ b/linphone/oRTP/include/ortp/ortp.h @@ -0,0 +1,199 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** \mainpage oRTP API documentation + * + * \section init Initializing oRTP + * + * see ortp.h documentation. + * + * \section rtpsession the RtpSession object + * + * see the rtpsession.h documentation. + * + * \section payloadtypes Managing PayloadType(s) and RtpProfile(s) + * + * see the payloadtype.h documentation. + * + * \section telephonevents Sending and receiving telephone-event (RFC2833) + * + * see the telephonyevents.h documentation. + * To get informed about incoming telephone-event you can register a callback + * using rtp_session_signal_connect() or by registering an event queue using + * rtp_session_register_event_queue(). + * + * \section sessionset Managing several RtpSession simultaneously + * + * see the sessionset.h documentation. + * + * \section rtcp Parsing incoming rtcp packets. + * + * The parsing api is defined in rtcp.h (not yet documented). + * + * \section examples Examples + * + * oRTP comes with a set of examples in src/tests. + * - rtprecv.c rtpsend.c show how to receive and send a single RTP stream. + * - mrtprecv.c mrtpsend.c show how to receive and send multiple RTP streams + * simultaneously + * + */ + +/** + * \file ortp.h + * \brief General purpose library functions. + * +**/ + +#ifndef ORTP_H +#define ORTP_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +bool_t ortp_min_version_required(int major, int minor, int micro); +void ortp_init(void); +void ortp_scheduler_init(void); +void ortp_exit(void); + +/***************/ +/* logging api */ +/***************/ + +typedef enum { + ORTP_DEBUG=1, + ORTP_MESSAGE=1<<1, + ORTP_WARNING=1<<2, + ORTP_ERROR=1<<3, + ORTP_FATAL=1<<4, + ORTP_LOGLEV_END=1<<5 +} OrtpLogLevel; + + +typedef void (*OrtpLogFunc)(OrtpLogLevel lev, const char *fmt, va_list args); + +void ortp_set_log_file(FILE *file); +void ortp_set_log_handler(OrtpLogFunc func); + +VAR_DECLSPEC OrtpLogFunc ortp_logv_out; + +extern unsigned int __ortp_log_mask; + +#define ortp_log_level_enabled(level) (__ortp_log_mask & (level)) + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#define ortp_logv(level,fmt,args) \ +{\ + if (ortp_logv_out!=NULL && ortp_log_level_enabled(level)) \ + ortp_logv_out(level,fmt,args);\ + if ((level)==ORTP_FATAL) abort();\ +}while(0) +#else +void ortp_logv(int level, const char *fmt, va_list args); +#endif + +void ortp_set_log_level_mask(int levelmask); + +#ifdef ORTP_DEBUG_MODE +static inline void ortp_debug(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_DEBUG, fmt, args); + va_end (args); +} +#else + +#define ortp_debug(...) + +#endif + +#ifdef ORTP_NOMESSAGE_MODE + +#define ortp_log(...) +#define ortp_message(...) +#define ortp_warning(...) + +#else + +static inline void ortp_log(OrtpLogLevel lev, const char *fmt,...){ + va_list args; + va_start (args, fmt); + ortp_logv(lev, fmt, args); + va_end (args); +} + +static inline void ortp_message(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_MESSAGE, fmt, args); + va_end (args); +} + +static inline void ortp_warning(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_WARNING, fmt, args); + va_end (args); +} + +#endif + +static inline void ortp_error(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_ERROR, fmt, args); + va_end (args); +} + +static inline void ortp_fatal(const char *fmt,...) +{ + va_list args; + va_start (args, fmt); + ortp_logv(ORTP_FATAL, fmt, args); + va_end (args); +} + + +/****************/ +/*statistics api*/ +/****************/ + +extern rtp_stats_t ortp_global_stats; + +void ortp_global_stats_reset(void); +rtp_stats_t *ortp_get_global_stats(void); + +void ortp_global_stats_display(void); +void rtp_stats_display(const rtp_stats_t *stats, const char *header); +void rtp_stats_reset(rtp_stats_t *stats); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/payloadtype.h b/linphone/oRTP/include/ortp/payloadtype.h new file mode 100644 index 000000000..79081ece4 --- /dev/null +++ b/linphone/oRTP/include/ortp/payloadtype.h @@ -0,0 +1,208 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * \file payloadtype.h + * \brief Using and creating standart and custom RTP profiles + * +**/ + +#ifndef PAYLOADTYPE_H +#define PAYLOADTYPE_H +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +/* flags for PayloadType::flags */ + +#define PAYLOAD_TYPE_ALLOCATED (1) + /* private flags for future use by ortp */ +#define PAYLOAD_TYPE_PRIV1 (1<<1) +#define PAYLOAD_TYPE_PRIV2 (1<<2) +#define PAYLOAD_TYPE_PRIV3 (1<<3) + /* user flags, can be used by the application on top of oRTP */ +#define PAYLOAD_TYPE_USER_FLAG_0 (1<<4) +#define PAYLOAD_TYPE_USER_FLAG_1 (1<<5) +#define PAYLOAD_TYPE_USER_FLAG_2 (1<<6) + /* ask for more if you need*/ + +#define PAYLOAD_AUDIO_CONTINUOUS 0 +#define PAYLOAD_AUDIO_PACKETIZED 1 +#define PAYLOAD_VIDEO 2 +#define PAYLOAD_OTHER 3 /* ?? */ + +struct _PayloadType +{ + int type; /**< one of PAYLOAD_* macros*/ + int clock_rate; /**< rtp clock rate*/ + char bits_per_sample; /* in case of continuous audio data */ + char *zero_pattern; + int pattern_length; + /* other useful information for the application*/ + int normal_bitrate; /*in bit/s */ + char *mime_type; /**flags|=((int)flag) +#define payload_type_unset_flag(pt,flag) (pt)->flags&=(~(int)flag) +#define payload_type_get_flags(pt) (pt)->flags + +#define RTP_PROFILE_MAX_PAYLOADS 128 + +/** + * The RTP profile is a table RTP_PROFILE_MAX_PAYLOADS entries to make the matching + * between RTP payload type number and the PayloadType that defines the type of + * media. +**/ +struct _RtpProfile +{ + char *name; + PayloadType *payload[RTP_PROFILE_MAX_PAYLOADS]; +}; + + +typedef struct _RtpProfile RtpProfile; + +PayloadType *payload_type_new(void); +PayloadType *payload_type_clone(PayloadType *payload); +char *payload_type_get_rtpmap(PayloadType *pt); +void payload_type_destroy(PayloadType *pt); +void payload_type_set_recv_fmtp(PayloadType *pt, const char *fmtp); +void payload_type_set_send_fmtp(PayloadType *pt, const char *fmtp); +void payload_type_append_recv_fmtp(PayloadType *pt, const char *fmtp); +void payload_type_append_send_fmtp(PayloadType *pt, const char *fmtp); + + +bool_t fmtp_get_value(const char *fmtp, const char *param_name, char *result, size_t result_len); + +VAR_DECLSPEC RtpProfile av_profile; + +#define payload_type_set_user_data(pt,p) (pt)->user_data=(p) +#define payload_type_get_user_data(pt) ((pt)->user_data) + +#define rtp_profile_get_name(profile) (const char*)((profile)->name) + +void rtp_profile_set_payload(RtpProfile *prof, int idx, PayloadType *pt); + +/** + * Set payload type number @index unassigned in the profile. + * + *@param profile an RTP profile + *@param index the payload type number +**/ +#define rtp_profile_clear_payload(profile,index) \ + rtp_profile_set_payload(profile,index,NULL) + +/* I prefer have this function inlined because it is very often called in the code */ +/** + * + * Gets the payload description of the payload type @index in the profile. + * + *@param profile an RTP profile (a #RtpProfile object) + *@param index the payload type number + *@return the payload description (a PayloadType object) +**/ +static inline PayloadType * rtp_profile_get_payload(RtpProfile *prof, int idx){ + if (idx<0 || idx>=RTP_PROFILE_MAX_PAYLOADS) { + return NULL; + } + return prof->payload[idx]; +} +void rtp_profile_clear_all(RtpProfile *prof); +void rtp_profile_set_name(RtpProfile *prof, const char *name); +PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime); +PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap); +int rtp_profile_get_payload_number_from_mime(RtpProfile *profile,const char *mime); +int rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile, const char *rtpmap); +int rtp_profile_find_payload_number(RtpProfile *prof,const char *mime,int rate, int channels); +PayloadType * rtp_profile_find_payload(RtpProfile *prof,const char *mime,int rate, int channels); +int rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos); + +RtpProfile * rtp_profile_new(const char *name); +/* clone a profile, payload are not cloned */ +RtpProfile * rtp_profile_clone(RtpProfile *prof); + + +/*clone a profile and its payloads (ie payload type are newly allocated, not reusing payload types of the reference profile) */ +RtpProfile * rtp_profile_clone_full(RtpProfile *prof); +/* frees the profile and all its PayloadTypes*/ +void rtp_profile_destroy(RtpProfile *prof); + + +/* some payload types */ +/* audio */ +VAR_DECLSPEC PayloadType payload_type_pcmu8000; +VAR_DECLSPEC PayloadType payload_type_pcma8000; +VAR_DECLSPEC PayloadType payload_type_pcm8000; +VAR_DECLSPEC PayloadType payload_type_l16_mono; +VAR_DECLSPEC PayloadType payload_type_l16_stereo; +VAR_DECLSPEC PayloadType payload_type_lpc1016; +VAR_DECLSPEC PayloadType payload_type_g729; +VAR_DECLSPEC PayloadType payload_type_g7231; +VAR_DECLSPEC PayloadType payload_type_g726_40; +VAR_DECLSPEC PayloadType payload_type_g726_32; +VAR_DECLSPEC PayloadType payload_type_g726_24; +VAR_DECLSPEC PayloadType payload_type_g726_16; +VAR_DECLSPEC PayloadType payload_type_gsm; +VAR_DECLSPEC PayloadType payload_type_lpc; +VAR_DECLSPEC PayloadType payload_type_lpc1015; +VAR_DECLSPEC PayloadType payload_type_speex_nb; +VAR_DECLSPEC PayloadType payload_type_speex_wb; +VAR_DECLSPEC PayloadType payload_type_speex_uwb; +VAR_DECLSPEC PayloadType payload_type_ilbc; +VAR_DECLSPEC PayloadType payload_type_amr; +VAR_DECLSPEC PayloadType payload_type_amrwb; +VAR_DECLSPEC PayloadType payload_type_truespeech; +VAR_DECLSPEC PayloadType payload_type_evrc0; + +/* video */ +VAR_DECLSPEC PayloadType payload_type_mpv; +VAR_DECLSPEC PayloadType payload_type_h261; +VAR_DECLSPEC PayloadType payload_type_h263; +VAR_DECLSPEC PayloadType payload_type_h263_1998; +VAR_DECLSPEC PayloadType payload_type_h263_2000; +VAR_DECLSPEC PayloadType payload_type_mp4v; +VAR_DECLSPEC PayloadType payload_type_theora; +VAR_DECLSPEC PayloadType payload_type_h264; +VAR_DECLSPEC PayloadType payload_type_x_snow; +VAR_DECLSPEC PayloadType payload_type_t140; + +/* non standard file transfer over UDP */ +VAR_DECLSPEC PayloadType payload_type_x_udpftp; + +/* telephone-event */ +VAR_DECLSPEC PayloadType payload_type_telephone_event; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/port.h b/linphone/oRTP/include/ortp/port.h new file mode 100644 index 000000000..c50fb2de0 --- /dev/null +++ b/linphone/oRTP/include/ortp/port.h @@ -0,0 +1,250 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* this file is responsible of the portability of the stack */ + +#ifndef ORTP_PORT_H +#define ORTP_PORT_H + + +#if !defined(WIN32) && !defined(_WIN32_WCE) +/********************************/ +/* definitions for UNIX flavour */ +/********************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux +#include +#endif + + +#include +#include +#include +#if defined(_XOPEN_SOURCE_EXTENDED) || !defined(__hpux) +#include +#endif + + + +#include + +#ifdef ORTP_INET6 +#include +#endif + +typedef int ortp_socket_t; +typedef pthread_t ortp_thread_t; +typedef pthread_mutex_t ortp_mutex_t; +typedef pthread_cond_t ortp_cond_t; + +#ifdef __INTEL_COMPILER +#pragma warning(disable : 111) // statement is unreachable +#pragma warning(disable : 181) // argument is incompatible with corresponding format string conversion +#pragma warning(disable : 188) // enumerated type mixed with another type +#pragma warning(disable : 593) // variable "xxx" was set but never used +#pragma warning(disable : 810) // conversion from "int" to "unsigned short" may lose significant bits +#pragma warning(disable : 869) // parameter "xxx" was never referenced +#pragma warning(disable : 981) // operands are evaluated in unspecified order +#pragma warning(disable : 1418) // external function definition with no prior declaration +#pragma warning(disable : 1419) // external declaration in primary source file +#pragma warning(disable : 1469) // "cc" clobber ignored +#endif + +int __ortp_thread_join(ortp_thread_t thread, void **ptr); +int __ortp_thread_create(pthread_t *thread, pthread_attr_t *attr, void * (*routine)(void*), void *arg); +#define ortp_thread_create __ortp_thread_create +#define ortp_thread_join __ortp_thread_join +#define ortp_thread_exit pthread_exit +#define ortp_mutex_init pthread_mutex_init +#define ortp_mutex_lock pthread_mutex_lock +#define ortp_mutex_unlock pthread_mutex_unlock +#define ortp_mutex_destroy pthread_mutex_destroy +#define ortp_cond_init pthread_cond_init +#define ortp_cond_signal pthread_cond_signal +#define ortp_cond_broadcast pthread_cond_broadcast +#define ortp_cond_wait pthread_cond_wait +#define ortp_cond_destroy pthread_cond_destroy + +#define SOCKET_OPTION_VALUE void * +#define SOCKET_BUFFER void * + +#define getSocketError() strerror(errno) +#define getSocketErrorCode() (errno) + +#else +/*********************************/ +/* definitions for WIN32 flavour */ +/*********************************/ + +#include +#include +#include +#include +#include + + +#ifdef _MSC_VER +#pragma push_macro("_WINSOCKAPI_") +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef __int16 int16_t; +#else +#include /*provided by mingw32*/ +#endif + +#define vsnprintf _vsnprintf +#define srandom srand +#define random rand + + +typedef SOCKET ortp_socket_t; +typedef HANDLE ortp_cond_t; +typedef HANDLE ortp_mutex_t; +typedef HANDLE ortp_thread_t; + +#define ortp_thread_create WIN_thread_create +#define ortp_thread_join WIN_thread_join +#define ortp_thread_exit(arg) +#define ortp_mutex_init WIN_mutex_init +#define ortp_mutex_lock WIN_mutex_lock +#define ortp_mutex_unlock WIN_mutex_unlock +#define ortp_mutex_destroy WIN_mutex_destroy +#define ortp_cond_init WIN_cond_init +#define ortp_cond_signal WIN_cond_signal +#define ortp_cond_broadcast WIN_cond_broadcast +#define ortp_cond_wait WIN_cond_wait +#define ortp_cond_destroy WIN_cond_destroy + + +#ifdef __cplusplus +extern "C" +{ +#endif + +int WIN_mutex_init(ortp_mutex_t *m, void *attr_unused); +int WIN_mutex_lock(ortp_mutex_t *mutex); +int WIN_mutex_unlock(ortp_mutex_t *mutex); +int WIN_mutex_destroy(ortp_mutex_t *mutex); +int WIN_thread_create(ortp_thread_t *t, void *attr_unused, void *(*func)(void*), void *arg); +int WIN_thread_join(ortp_thread_t thread, void **unused); +int WIN_cond_init(ortp_cond_t *cond, void *attr_unused); +int WIN_cond_wait(ortp_cond_t * cond, ortp_mutex_t * mutex); +int WIN_cond_signal(ortp_cond_t * cond); +int WIN_cond_broadcast(ortp_cond_t * cond); +int WIN_cond_destroy(ortp_cond_t * cond); + +#ifdef __cplusplus +} +#endif + +#define SOCKET_OPTION_VALUE char * +#define inline __inline + +const char *getWinSocketError(int error); +#define getSocketErrorCode() WSAGetLastError() +#define getSocketError() getWinSocketError(WSAGetLastError()) + +#define snprintf _snprintf +#define strcasecmp _stricmp + +#if 0 +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif + +int gettimeofday (struct timeval *tv, void* tz); +#ifdef _WORKAROUND_MINGW32_BUGS +char * WSAAPI gai_strerror(int errnum); +#endif + + +#endif + +typedef unsigned char bool_t; +#undef TRUE +#undef FALSE +#define TRUE 1 +#define FALSE 0 + +#ifdef __cplusplus +extern "C"{ +#endif + +void* ortp_malloc(size_t sz); +void ortp_free(void *ptr); +void* ortp_realloc(void *ptr, size_t sz); +void* ortp_malloc0(size_t sz); +char * ortp_strdup(const char *tmp); + +/*override the allocator with this method, to be called BEFORE ortp_init()*/ +typedef struct _OrtpMemoryFunctions{ + void *(*malloc_fun)(size_t sz); + void *(*realloc_fun)(void *ptr, size_t sz); + void (*free_fun)(void *ptr); +}OrtpMemoryFunctions; + +void ortp_set_memory_functions(OrtpMemoryFunctions *functions); + +#define ortp_new(type,count) ortp_malloc(sizeof(type)*(count)) +#define ortp_new0(type,count) ortp_malloc0(sizeof(type)*(count)) + +int close_socket(ortp_socket_t sock); +int set_non_blocking_socket(ortp_socket_t sock); + +char *ortp_strndup(const char *str,int n); +char *ortp_strdup_printf(const char *fmt,...); + +#ifdef __cplusplus +} +#endif + + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(ORTP_STATIC) +#ifdef ORTP_EXPORTS + #define VAR_DECLSPEC __declspec(dllexport) +#else + #define VAR_DECLSPEC __declspec(dllimport) +#endif +#else + #define VAR_DECLSPEC extern +#endif + + +#endif + + diff --git a/linphone/oRTP/include/ortp/rtcp.h b/linphone/oRTP/include/ortp/rtcp.h new file mode 100644 index 000000000..950179764 --- /dev/null +++ b/linphone/oRTP/include/ortp/rtcp.h @@ -0,0 +1,252 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef RTCP_H +#define RTCP_H + +#include + +#define RTCP_MAX_RECV_BUFSIZE 1024 + +#define RTCP_SENDER_INFO_SIZE 20 +#define RTCP_REPORT_BLOCK_SIZE 24 +#define RTCP_COMMON_HEADER_SIZE 4 +#define RTCP_SSRC_FIELD_SIZE 4 + +#ifdef __cplusplus +extern "C"{ +#endif + +/* RTCP common header */ + +typedef enum { + RTCP_SR = 200, + RTCP_RR = 201, + RTCP_SDES = 202, + RTCP_BYE = 203, + RTCP_APP = 204 +} rtcp_type_t; + + +typedef struct rtcp_common_header +{ +#ifdef ORTP_BIGENDIAN + uint16_t version:2; + uint16_t padbit:1; + uint16_t rc:5; + uint16_t packet_type:8; +#else + uint16_t rc:5; + uint16_t padbit:1; + uint16_t version:2; + uint16_t packet_type:8; +#endif + uint16_t length:16; +} rtcp_common_header_t; + +#define rtcp_common_header_set_version(ch,v) (ch)->version=v +#define rtcp_common_header_set_padbit(ch,p) (ch)->padbit=p +#define rtcp_common_header_set_rc(ch,rc) (ch)->rc=rc +#define rtcp_common_header_set_packet_type(ch,pt) (ch)->packet_type=pt +#define rtcp_common_header_set_length(ch,l) (ch)->length=htons(l) + +#define rtcp_common_header_get_version(ch) ((ch)->version) +#define rtcp_common_header_get padbit(ch) ((ch)->padbit) +#define rtcp_common_header_get_rc(ch) ((ch)->rc) +#define rtcp_common_header_get_packet_type(ch) ((ch)->packet_type) +#define rtcp_common_header_get_length(ch) ntohs((ch)->length) + + +/* SR or RR packets */ + +typedef struct sender_info +{ + uint32_t ntp_timestamp_msw; + uint32_t ntp_timestamp_lsw; + uint32_t rtp_timestamp; + uint32_t senders_packet_count; + uint32_t senders_octet_count; +} sender_info_t; + +uint64_t sender_info_get_ntp_timestamp(const sender_info_t *si); +#define sender_info_get_rtp_timestamp(si) ((si)->rtp_timestamp) +#define sender_info_get_packet_count(si) \ + ntohl((si)->senders_packet_count) +#define sender_info_get_octet_count(si) \ + ntohl((si)->senders_octet_count) + + +typedef struct report_block +{ + uint32_t ssrc; + uint32_t fl_cnpl;/*fraction lost + cumulative number of packet lost*/ + uint32_t ext_high_seq_num_rec; /*extended highest sequence number received */ + uint32_t interarrival_jitter; + uint32_t lsr; /*last SR */ + uint32_t delay_snc_last_sr; /*delay since last sr*/ +} report_block_t; + +#define report_block_get_ssrc(rb) \ + ntohl((rb)->ssrc) +#define report_block_get_fraction_lost(rb) \ + (((uint32_t)ntohl((rb)->fl_cnpl))>>24) +#define report_block_get_cum_packet_loss(rb) \ + (((uint32_t)ntohl((rb)->fl_cnpl)) & 0xFFFFFF) +#define report_block_get_high_ext_seq(rb) \ + ntohl(((report_block_t*)(rb))->ext_high_seq_num_rec) +#define report_block_get_interarrival_jitter(rb) \ + ntohl(((report_block_t*)(rb))->interarrival_jitter) +#define report_block_get_last_SR_time(rb) \ + ntohl(((report_block_t*)(rb))->lsr) +#define report_block_get_last_SR_delay(rb) \ + ntohl(((report_block_t*)(rb))->delay_snc_last_sr) + +#define report_block_set_fraction_lost(rb,fl)\ + ((rb)->fl_cnpl)=htonl( (ntohl((rb)->fl_cnpl) & 0xFFFFFF) | (((fl) & 0xFF)<<24)) + +#define report_block_set_cum_packet_lost(rb,cpl)\ + ((rb)->fl_cnpl)=htonl( (ntohl((rb)->fl_cnpl) & 0xFF000000) | (((cpl) & 0xFFFFFF))) + +/* SDES packets */ + +typedef enum { + RTCP_SDES_END = 0, + RTCP_SDES_CNAME = 1, + RTCP_SDES_NAME = 2, + RTCP_SDES_EMAIL = 3, + RTCP_SDES_PHONE = 4, + RTCP_SDES_LOC = 5, + RTCP_SDES_TOOL = 6, + RTCP_SDES_NOTE = 7, + RTCP_SDES_PRIV = 8, + RTCP_SDES_MAX = 9 +} rtcp_sdes_type_t; + +typedef struct sdes_chunk +{ + uint32_t csrc; +} sdes_chunk_t; + + +#define sdes_chunk_get_csrc(c) ntohl((c)->csrc) + +typedef struct sdes_item +{ + uint8_t item_type; + uint8_t len; + char content[1]; +} sdes_item_t; + +#define RTCP_SDES_MAX_STRING_SIZE 255 +#define RTCP_SDES_ITEM_HEADER_SIZE 2 +#define RTCP_SDES_CHUNK_DEFAULT_SIZE 1024 +#define RTCP_SDES_CHUNK_HEADER_SIZE (sizeof(sdes_chunk_t)) + +/* RTCP bye packet */ + +typedef struct rtcp_bye_reason +{ + uint8_t len; + char content[1]; +} rtcp_bye_reason_t; + +typedef struct rtcp_bye +{ + rtcp_common_header_t ch; + uint32_t ssrc[1]; /* the bye may contain several ssrc/csrc */ +} rtcp_bye_t; +#define RTCP_BYE_HEADER_SIZE sizeof(rtcp_bye_t) +#define RTCP_BYE_REASON_MAX_STRING_SIZE 255 + + + +typedef struct rtcp_sr{ + rtcp_common_header_t ch; + uint32_t ssrc; + sender_info_t si; + report_block_t rb[1]; +} rtcp_sr_t; + +typedef struct rtcp_rr{ + rtcp_common_header_t ch; + uint32_t ssrc; + report_block_t rb[1]; +} rtcp_rr_t; + +typedef struct rtcp_app{ + rtcp_common_header_t ch; + uint32_t ssrc; + char name[4]; +} rtcp_app_t; + +struct _RtpSession; +void rtp_session_rtcp_process_send(struct _RtpSession *s); +void rtp_session_rtcp_process_recv(struct _RtpSession *s); + +#define RTCP_DEFAULT_REPORT_INTERVAL 5 + + +/* packet parsing api */ + +/*in case of coumpound packet, set read pointer of m to the beginning of the next RTCP +packet */ +bool_t rtcp_next_packet(mblk_t *m); +/* put the read pointer at the first RTCP packet of the compound packet (as before any previous calls ot rtcp_next_packet() */ +void rtcp_rewind(mblk_t *m); +/* get common header*/ +const rtcp_common_header_t * rtcp_get_common_header(const mblk_t *m); + +/*Sender Report accessors */ +/* check if this packet is a SR and if it is correct */ +bool_t rtcp_is_SR(const mblk_t *m); +uint32_t rtcp_SR_get_ssrc(const mblk_t *m); +const sender_info_t * rtcp_SR_get_sender_info(const mblk_t *m); +const report_block_t * rtcp_SR_get_report_block(const mblk_t *m, int idx); + +/*Receiver report accessors*/ +bool_t rtcp_is_RR(const mblk_t *m); +uint32_t rtcp_RR_get_ssrc(const mblk_t *m); +const report_block_t * rtcp_RR_get_report_block(const mblk_t *m,int idx); + +/*SDES accessors */ +bool_t rtcp_is_SDES(const mblk_t *m); +typedef void (*SdesItemFoundCallback)(void *user_data, uint32_t csrc, rtcp_sdes_type_t t, const char *content, uint8_t content_len); +void rtcp_sdes_parse(const mblk_t *m, SdesItemFoundCallback cb, void *user_data); + +/*BYE accessors */ +bool_t rtcp_is_BYE(const mblk_t *m); +bool_t rtcp_BYE_get_ssrc(const mblk_t *m, int idx, uint32_t *ssrc); +bool_t rtcp_BYE_get_reason(const mblk_t *m, const char **reason, int *reason_len); + +/*APP accessors */ +bool_t rtcp_is_APP(const mblk_t *m); +int rtcp_APP_get_subtype(const mblk_t *m); +uint32_t rtcp_APP_get_ssrc(const mblk_t *m); +/* name argument is supposed to be at least 4 characters (note: no '\0' written)*/ +void rtcp_APP_get_name(const mblk_t *m, char *name); +/* retrieve the data. when returning, data points directly into the mblk_t */ +void rtcp_APP_get_data(const mblk_t *m, uint8_t **data, int *len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/rtp.h b/linphone/oRTP/include/ortp/rtp.h new file mode 100644 index 000000000..5ecd95def --- /dev/null +++ b/linphone/oRTP/include/ortp/rtp.h @@ -0,0 +1,115 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef RTP_H +#define RTP_H + +#include +#include + +#define IPMAXLEN 20 +#define UDP_MAX_SIZE 1500 +#define RTP_FIXED_HEADER_SIZE 12 +#define RTP_DEFAULT_JITTER_TIME 80 /*miliseconds*/ +#define RTP_DEFAULT_MULTICAST_TTL 5 /*hops*/ +#define RTP_DEFAULT_MULTICAST_LOOPBACK 0 /*false*/ +#define RTP_DEFAULT_DSCP 0x00 /*best effort*/ + + + +typedef struct rtp_header +{ +#ifdef ORTP_BIGENDIAN + uint16_t version:2; + uint16_t padbit:1; + uint16_t extbit:1; + uint16_t cc:4; + uint16_t markbit:1; + uint16_t paytype:7; +#else + uint16_t cc:4; + uint16_t extbit:1; + uint16_t padbit:1; + uint16_t version:2; + uint16_t paytype:7; + uint16_t markbit:1; +#endif + uint16_t seq_number; + uint32_t timestamp; + uint32_t ssrc; + uint32_t csrc[16]; +} rtp_header_t; + + + + +typedef struct rtp_stats +{ + uint64_t packet_sent; + uint64_t sent; /* bytes sent */ + uint64_t recv; /* bytes of payload received and delivered in time to the application */ + uint64_t hw_recv; /* bytes of payload received */ + uint64_t packet_recv; /* number of packets received */ + uint64_t unavaillable; /* packets not availlable when they were queried */ + uint64_t outoftime; /* number of packets that were received too late */ + uint64_t cum_packet_loss; /* cumulative number of packet lost */ + uint64_t bad; /* packets that did not appear to be RTP */ + uint64_t discarded; /* incoming packets discarded because the queue exceeds its max size */ +} rtp_stats_t; + +#define RTP_TIMESTAMP_IS_NEWER_THAN(ts1,ts2) \ + ((uint32_t)((uint32_t)(ts1) - (uint32_t)(ts2))< (uint32_t)(1<<31)) + +#define RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(ts1,ts2) \ + ( ((uint32_t)((uint32_t)(ts1) - (uint32_t)(ts2))< (uint32_t)(1<<31)) && (ts1)!=(ts2) ) + +#define TIME_IS_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_NEWER_THAN(t1,t2) + +#define TIME_IS_STRICTLY_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(t1,t2) + + +#ifdef __cplusplus +extern "C"{ +#endif + +/* packet api */ +/* the first argument is a mblk_t. The header is supposed to be not splitted */ +#define rtp_set_markbit(mp,value) ((rtp_header_t*)((mp)->b_rptr))->markbit=(value) +#define rtp_set_seqnumber(mp,seq) ((rtp_header_t*)((mp)->b_rptr))->seq_number=(seq) +#define rtp_set_timestamp(mp,ts) ((rtp_header_t*)((mp)->b_rptr))->timestamp=(ts) +#define rtp_set_ssrc(mp,_ssrc) ((rtp_header_t*)((mp)->b_rptr))->ssrc=(_ssrc) +void rtp_add_csrc(mblk_t *mp ,uint32_t csrc); +#define rtp_set_payload_type(mp,pt) ((rtp_header_t*)((mp)->b_rptr))->paytype=(pt) + +#define rtp_get_markbit(mp) (((rtp_header_t*)((mp)->b_rptr))->markbit) +#define rtp_get_timestamp(mp) (((rtp_header_t*)((mp)->b_rptr))->timestamp) +#define rtp_get_seqnumber(mp) (((rtp_header_t*)((mp)->b_rptr))->seq_number) +#define rtp_get_payload_type(mp) (((rtp_header_t*)((mp)->b_rptr))->paytype) +#define rtp_get_ssrc(mp) (((rtp_header_t*)((mp)->b_rptr))->ssrc) +#define rtp_get_cc(mp) (((rtp_header_t*)((mp)->b_rptr))->cc) +#define rtp_get_csrc(mp, idx) (((rtp_header_t*)((mp)->b_rptr))->csrc[idx]) + +int rtp_get_payload(mblk_t *packet, unsigned char **start); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/rtpsession.h b/linphone/oRTP/include/ortp/rtpsession.h new file mode 100644 index 000000000..5b127d9ca --- /dev/null +++ b/linphone/oRTP/include/ortp/rtpsession.h @@ -0,0 +1,380 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * \file rtpsession.h + * \brief The RtpSession api + * + * The RtpSession objects represent a RTP session: once it is configured with + * local and remote network addresses and a payload type is given, it let you send + * and recv a media stream. +**/ + + +#ifndef RTPSESSION_H +#define RTPSESSION_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + + +typedef enum { + RTP_SESSION_RECVONLY, + RTP_SESSION_SENDONLY, + RTP_SESSION_SENDRECV +} RtpSessionMode; + + +/*! Jitter buffer parameters +*/ +typedef struct _JBParameters{ + int min_size; /**< in milliseconds*/ + int nom_size; /**< idem */ + int max_size; /**< idem */ + bool_t adaptive; + bool_t pad[3]; + int max_packets; /**< max number of packets allowed to be queued in the jitter buffer */ +} JBParameters; + +typedef struct _JitterControl +{ + int count; + int jitt_comp; /* the user jitt_comp in miliseconds*/ + int jitt_comp_ts; /* the jitt_comp converted in rtp time (same unit as timestamp) */ + int adapt_jitt_comp_ts; + int64_t slide; + int64_t prev_slide; + float jitter; + int olddiff; + float inter_jitter; /* interarrival jitter as defined in the RFC */ + int corrective_step; + int corrective_slide; + bool_t adaptive; + bool_t enabled; +} JitterControl; + +typedef struct _WaitPoint +{ + ortp_mutex_t lock; + ortp_cond_t cond; + uint32_t time; + bool_t wakeup; +} WaitPoint; + +typedef struct _RtpTransport +{ + void *data; + ortp_socket_t (*t_getsocket)(struct _RtpTransport *t); + int (*t_sendto)(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen); + int (*t_recvfrom)(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen); + struct _RtpSession *session;//flags|=(flag) +#define rtp_session_unset_flag(session,flag) (session)->flags&=~(flag) +void rtp_session_uninit(RtpSession *session); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/rtpsignaltable.h b/linphone/oRTP/include/ortp/rtpsignaltable.h new file mode 100644 index 000000000..fb74e8ddc --- /dev/null +++ b/linphone/oRTP/include/ortp/rtpsignaltable.h @@ -0,0 +1,53 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef rtpsignaltable_h +#define rtpsignaltable_h + +#define RTP_CALLBACK_TABLE_MAX_ENTRIES 5 + +typedef void (*RtpCallback)(struct _RtpSession *, ...); + +struct _RtpSignalTable +{ + RtpCallback callback[RTP_CALLBACK_TABLE_MAX_ENTRIES]; + unsigned long user_data[RTP_CALLBACK_TABLE_MAX_ENTRIES]; + struct _RtpSession *session; + const char *signal_name; + int count; +}; + +typedef struct _RtpSignalTable RtpSignalTable; + +void rtp_signal_table_init(RtpSignalTable *table,struct _RtpSession *session, const char *signal_name); + +int rtp_signal_table_add(RtpSignalTable *table,RtpCallback cb, unsigned long user_data); + +void rtp_signal_table_emit(RtpSignalTable *table); + +/* emit but with a second arg */ +void rtp_signal_table_emit2(RtpSignalTable *table, unsigned long arg); + +/* emit but with a third arg */ +void rtp_signal_table_emit3(RtpSignalTable *table, unsigned long arg1, unsigned long arg2); + +int rtp_signal_table_remove_by_callback(RtpSignalTable *table,RtpCallback cb); + +#endif + diff --git a/linphone/oRTP/include/ortp/sessionset.h b/linphone/oRTP/include/ortp/sessionset.h new file mode 100644 index 000000000..1eadc759e --- /dev/null +++ b/linphone/oRTP/include/ortp/sessionset.h @@ -0,0 +1,139 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/** + * \file sessionset.h + * \brief Sending and receiving multiple streams together with only one thread. + * +**/ +#ifndef SESSIONSET_H +#define SESSIONSET_H + + +#include + +#ifdef __cplusplus +extern "C"{ +#endif + + +#if !defined(_WIN32) && !defined(_WIN32_WCE) +/* UNIX */ +#include +#include +#include + +#define ORTP_FD_SET(d, s) FD_SET(d, s) +#define ORTP_FD_CLR(d, s) FD_CLR(d, s) +#define ORTP_FD_ISSET(d, s) FD_ISSET(d, s) +#define ORTP_FD_ZERO(s) FD_ZERO(s) + +typedef fd_set ortp_fd_set; + + +#else +/* WIN32 */ + +#define ORTP_FD_ZERO(s) \ + do { \ + unsigned int __i; \ + ortp_fd_set *__arr = (s); \ + for (__i = 0; __i < sizeof (ortp_fd_set) / sizeof (ortp__fd_mask); ++__i) \ + ORTP__FDS_BITS (__arr)[__i] = 0; \ + } while (0) +#define ORTP_FD_SET(d, s) (ORTP__FDS_BITS (s)[ORTP__FDELT(d)] |= ORTP__FDMASK(d)) +#define ORTP_FD_CLR(d, s) (ORTP__FDS_BITS (s)[ORTP__FDELT(d)] &= ~ORTP__FDMASK(d)) +#define ORTP_FD_ISSET(d, s) ((ORTP__FDS_BITS (s)[ORTP__FDELT(d)] & ORTP__FDMASK(d)) != 0) + + + +/* The fd_set member is required to be an array of longs. */ +typedef long int ortp__fd_mask; + + +/* Number of bits per word of `fd_set' (some code assumes this is 32). */ +#define ORTP__FD_SETSIZE 1024 + +/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ +#define ORTP__NFDBITS (8 * sizeof (ortp__fd_mask)) +#define ORTP__FDELT(d) ((d) / ORTP__NFDBITS) +#define ORTP__FDMASK(d) ((ortp__fd_mask) 1 << ((d) % ORTP__NFDBITS)) + + +/* fd_set for select and pselect. */ +typedef struct + { + ortp__fd_mask fds_bits[ORTP__FD_SETSIZE / ORTP__NFDBITS]; +# define ORTP__FDS_BITS(set) ((set)->fds_bits) + } ortp_fd_set; + + +#endif /*end WIN32*/ + +struct _SessionSet +{ + ortp_fd_set rtpset; +}; + + +typedef struct _SessionSet SessionSet; + +#define session_set_init(ss) ORTP_FD_ZERO(&(ss)->rtpset) + +SessionSet * session_set_new(void); +/** + * This macro adds the rtp session to the set. + * @param ss a set (SessionSet object) + * @param rtpsession a RtpSession +**/ +#define session_set_set(ss,rtpsession) ORTP_FD_SET((rtpsession)->mask_pos,&(ss)->rtpset) + +/** + * This macro tests if the session is part of the set. 1 is returned if true, 0 else. + *@param ss a set (#SessionSet object) + *@param rtpsession a rtp session + * +**/ +#define session_set_is_set(ss,rtpsession) ORTP_FD_ISSET((rtpsession)->mask_pos,&(ss)->rtpset) + +/** + * Removes the session from the set. + *@param ss a set of sessions. + *@param rtpsession a rtp session. + * + * +**/ +#define session_set_clr(ss,rtpsession) ORTP_FD_CLR((rtpsession)->mask_pos,&(ss)->rtpset) + +#define session_set_copy(dest,src) memcpy(&(dest)->rtpset,&(src)->rtpset,sizeof(ortp_fd_set)) + + +/** + * Frees a SessionSet. +**/ +void session_set_destroy(SessionSet *set); + + +int session_set_select(SessionSet *recvs, SessionSet *sends, SessionSet *errors); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/srtp.h b/linphone/oRTP/include/ortp/srtp.h new file mode 100644 index 000000000..f6dae3874 --- /dev/null +++ b/linphone/oRTP/include/ortp/srtp.h @@ -0,0 +1,44 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef ortp_srtp_h +#define ortp_srtp_h + +#include +#include + +#ifdef __cplusplus +extern "C"{ +#endif + + +err_status_t ortp_srtp_init(void); +err_status_t ortp_srtp_create(srtp_t *session, const srtp_policy_t *policy); +err_status_t ortp_srtp_dealloc(srtp_t session); +err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy); + +bool_t ortp_srtp_supported(void); + +int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/str_utils.h b/linphone/oRTP/include/ortp/str_utils.h new file mode 100644 index 000000000..ae073dd5b --- /dev/null +++ b/linphone/oRTP/include/ortp/str_utils.h @@ -0,0 +1,131 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef STR_UTILS_H +#define STR_UTILS_H + + +#include + + +typedef struct msgb +{ + struct msgb *b_prev; + struct msgb *b_next; + struct msgb *b_cont; + struct datab *b_datap; + unsigned char *b_rptr; + unsigned char *b_wptr; + uint32_t reserved1; + uint32_t reserved2; +} mblk_t; + +typedef struct datab +{ + unsigned char *db_base; + unsigned char *db_lim; + void (*db_freefn)(void*); + int db_ref; +} dblk_t; + +typedef struct _queue +{ + mblk_t _q_stopper; + int q_mcount; /*number of packet in the q */ +} queue_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void qinit(queue_t *q); + +void putq(queue_t *q, mblk_t *m); + +mblk_t * getq(queue_t *q); + +void insq(queue_t *q,mblk_t *emp, mblk_t *mp); + +void remq(queue_t *q, mblk_t *mp); + +mblk_t * peekq(queue_t *q); + +/* remove and free all messages in the q */ +#define FLUSHALL 0 +void flushq(queue_t *q, int how); + +void mblk_init(mblk_t *mp); + +/* allocates a mblk_t, that points to a datab_t, that points to a buffer of size size. */ +mblk_t *allocb(int size, int unused); +#define BPRI_MED 0 + +/* allocates a mblk_t, that points to a datab_t, that points to buf; buf will be freed using freefn */ +mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*) ); + +/* frees a mblk_t, and if the datab ref_count is 0, frees it and the buffer too */ +void freeb(mblk_t *m); + +/* frees recursively (follow b_cont) a mblk_t, and if the datab +ref_count is 0, frees it and the buffer too */ +void freemsg(mblk_t *mp); + +/* duplicates a mblk_t , buffer is not duplicated*/ +mblk_t *dupb(mblk_t *m); + +/* duplicates a complex mblk_t, buffer is not duplicated */ +mblk_t *dupmsg(mblk_t* m); + +/* returns the size of data of a message */ +int msgdsize(const mblk_t *mp); + +/* concatenates all fragment of a complex message*/ +void msgpullup(mblk_t *mp,int len); + +/* duplicates a single message, but with buffer included */ +mblk_t *copyb(mblk_t *mp); + +/* duplicates a complex message with buffer included */ +mblk_t *copymsg(mblk_t *mp); + +mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad); +void msgappend(mblk_t *mp, const char *data, int size, bool_t pad); + +mblk_t *concatb(mblk_t *mp, mblk_t *newm); + +#define qempty(q) (&(q)->_q_stopper==(q)->_q_stopper.b_next) +#define qfirst(q) ((q)->_q_stopper.b_next!=&(q)->_q_stopper ? (q)->_q_stopper.b_next : NULL) +#define qbegin(q) ((q)->_q_stopper.b_next) +#define qlast(q) ((q)->_q_stopper.b_prev!=&(q)->_q_stopper ? (q)->_q_stopper.b_prev : NULL) +#define qend(q,mp) ((mp)==&(q)->_q_stopper) +#define qnext(q,mp) ((mp)->b_next) + +typedef struct _msgb_allocator{ + queue_t q; +}msgb_allocator_t; + +void msgb_allocator_init(msgb_allocator_t *pa); +mblk_t *msgb_allocator_alloc(msgb_allocator_t *pa, int size); +void msgb_allocator_uninit(msgb_allocator_t *pa); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/stun.h b/linphone/oRTP/include/ortp/stun.h new file mode 100644 index 000000000..b7be9a4b3 --- /dev/null +++ b/linphone/oRTP/include/ortp/stun.h @@ -0,0 +1,406 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ + + +#ifndef __STUN_H__ +#define __STUN_H__ + +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* if you change this version, change in makefile too */ +#define STUN_VERSION "0.94" + +#define STUN_MAX_STRING 256 +#define STUN_MAX_UNKNOWN_ATTRIBUTES 8 +#define STUN_MAX_MESSAGE_SIZE 2048 + +#define STUN_PORT 3478 + +/* define some basic types */ +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +#if defined(WIN32) || defined(_WIN32_WCE) +typedef unsigned __int64 UInt64; +#else +typedef unsigned long long UInt64; +#endif +typedef struct { unsigned char octet[16]; } UInt128; + +/* define a structure to hold a stun address */ +#define IPv4Family 0x01 +#define IPv6Family 0x02 + +/* define flags */ +#define ChangeIpFlag 0x04 +#define ChangePortFlag 0x02 + +/* define stun attribute */ +#define MappedAddress 0x0001 +#define ResponseAddress 0x0002 +#define ChangeRequest 0x0003 +#define SourceAddress 0x0004 +#define ChangedAddress 0x0005 +#define Username 0x0006 +#define Password 0x0007 +#define MessageIntegrity 0x0008 +#define ErrorCode 0x0009 +#define UnknownAttribute 0x000A +#define ReflectedFrom 0x000B +#define XorMappedAddress 0x0020 +#define XorOnly 0x0021 +#define ServerName 0x0022 +#define SecondaryAddress 0x0050 /* Non standard extention */ + +/* define types for a stun message */ +#define BindRequestMsg 0x0001 +#define BindResponseMsg 0x0101 +#define BindErrorResponseMsg 0x0111 +#define SharedSecretRequestMsg 0x0002 +#define SharedSecretResponseMsg 0x0102 +#define SharedSecretErrorResponseMsg 0x0112 + +typedef struct +{ + UInt16 msgType; + UInt16 msgLength; + UInt128 id; +} StunMsgHdr; + + +typedef struct +{ + UInt16 type; + UInt16 length; +} StunAtrHdr; + +typedef struct +{ + UInt16 port; + UInt32 addr; +} StunAddress4; + +typedef struct +{ + UInt8 pad; + UInt8 family; + StunAddress4 ipv4; +} StunAtrAddress4; + +typedef struct +{ + UInt32 value; +} StunAtrChangeRequest; + +typedef struct +{ + UInt16 pad; /* all 0 */ + UInt8 errorClass; + UInt8 number; + char reason[STUN_MAX_STRING]; + UInt16 sizeReason; +} StunAtrError; + +typedef struct +{ + UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; + UInt16 numAttributes; +} StunAtrUnknown; + +typedef struct +{ + char value[STUN_MAX_STRING]; + UInt16 sizeValue; +} StunAtrString; + +typedef struct +{ + char hash[20]; +} StunAtrIntegrity; + +typedef enum +{ + HmacUnkown=0, + HmacOK, + HmacBadUserName, + HmacUnkownUserName, + HmacFailed +} StunHmacStatus; + +typedef struct +{ + StunMsgHdr msgHdr; + + bool_t hasMappedAddress; + StunAtrAddress4 mappedAddress; + + bool_t hasResponseAddress; + StunAtrAddress4 responseAddress; + + bool_t hasChangeRequest; + StunAtrChangeRequest changeRequest; + + bool_t hasSourceAddress; + StunAtrAddress4 sourceAddress; + + bool_t hasChangedAddress; + StunAtrAddress4 changedAddress; + + bool_t hasUsername; + StunAtrString username; + + bool_t hasPassword; + StunAtrString password; + + bool_t hasMessageIntegrity; + StunAtrIntegrity messageIntegrity; + + bool_t hasErrorCode; + StunAtrError errorCode; + + bool_t hasUnknownAttributes; + StunAtrUnknown unknownAttributes; + + bool_t hasReflectedFrom; + StunAtrAddress4 reflectedFrom; + + bool_t hasXorMappedAddress; + StunAtrAddress4 xorMappedAddress; + + bool_t xorOnly; + + bool_t hasServerName; + StunAtrString serverName; + + bool_t hasSecondaryAddress; + StunAtrAddress4 secondaryAddress; +} StunMessage; + + +/* Define enum with different types of NAT */ +typedef enum +{ + StunTypeUnknown=0, + StunTypeOpen, + StunTypeConeNat, + StunTypeRestrictedNat, + StunTypePortRestrictedNat, + StunTypeSymNat, + StunTypeSymFirewall, + StunTypeBlocked, + StunTypeFailure +} NatType; + + +#define MAX_MEDIA_RELAYS 500 +#define MAX_RTP_MSG_SIZE 1500 +#define MEDIA_RELAY_TIMEOUT 3*60 + +typedef struct +{ + int relayPort; /* media relay port */ + int fd; /* media relay file descriptor */ + StunAddress4 destination; /* NAT IP:port */ + time_t expireTime; /* if no activity after time, close the socket */ +} StunMediaRelay; + +typedef struct +{ + StunAddress4 myAddr; + StunAddress4 altAddr; + Socket myFd; + Socket altPortFd; + Socket altIpFd; + Socket altIpPortFd; + bool_t relay; /* true if media relaying is to be done */ + StunMediaRelay relays[MAX_MEDIA_RELAYS]; +} StunServerInfo; + +bool_t +stunParseMessage( char* buf, + unsigned int bufLen, + StunMessage *message, + bool_t verbose ); + +void +stunBuildReqSimple( StunMessage* msg, + const StunAtrString *username, + bool_t changePort, bool_t changeIp, unsigned int id ); + +unsigned int +stunEncodeMessage( const StunMessage *message, + char* buf, + unsigned int bufLen, + const StunAtrString *password, + bool_t verbose); + +void +stunCreateUserName(const StunAddress4 *addr, StunAtrString* username); + +void +stunGetUserNameAndPassword( const StunAddress4 *dest, + StunAtrString* username, + StunAtrString* password); + +void +stunCreatePassword(const StunAtrString *username, StunAtrString* password); + +int +stunRand(void); + +UInt64 +stunGetSystemTimeSecs(void); + +/* find the IP address of a the specified stun server - return false is fails parse */ +bool_t +stunParseServerName( char* serverName, StunAddress4 *stunServerAddr); + +bool_t +stunParseHostName( char* peerName, + UInt32 *ip, + UInt16 *portVal, + UInt16 defaultPort ); + +/* return true if all is OK + Create a media relay and do the STERN thing if startMediaPort is non-zero */ +bool_t +stunInitServer(StunServerInfo *info, + const StunAddress4 *myAddr, + const StunAddress4 *altAddr, + int startMediaPort, + bool_t verbose); + +void +stunStopServer(StunServerInfo *info); + +#if 0 /* no usefull here */ +/* return true if all is OK */ +bool_t +stunServerProcess(StunServerInfo *info, bool_t verbose); +#endif + +/* returns number of address found - take array or addres */ +int +stunFindLocalInterfaces(UInt32* addresses, int maxSize ); + +int +stunTest( StunAddress4 *dest, int testNum, bool_t verbose, StunAddress4* srcAddr, StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr); + +NatType +stunNatType( StunAddress4 *dest, bool_t verbose, + bool_t* preservePort, /* if set, is return for if NAT preservers ports or not */ + bool_t* hairpin , /* if set, is the return for if NAT will hairpin packets */ + int port, /* port to use for the test, 0 to choose random port */ + StunAddress4* sAddr /* NIC to use */ + ); + +bool_t +stunServerProcessMsg( char* buf, + unsigned int bufLen, + StunAddress4 *from, + StunAddress4 *secondary, + StunAddress4 *myAddr, + StunAddress4 *altAddr, + StunMessage *resp, + StunAddress4 *destination, + StunAtrString *hmacPassword, + bool_t* changePort, + bool_t* changeIp, + bool_t verbose); + +int +stunOpenSocket( StunAddress4 *dest, + StunAddress4* mappedAddr, + int port, + StunAddress4* srcAddr, + bool_t verbose ); + +bool_t +stunOpenSocketPair(StunAddress4 *dest, + StunAddress4* mapAddr_rtp, + StunAddress4* mapAddr_rtcp, + int* fd1, int* fd2, + int srcPort, StunAddress4* srcAddr, + bool_t verbose); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/linphone/oRTP/include/ortp/stun_udp.h b/linphone/oRTP/include/ortp/stun_udp.h new file mode 100644 index 000000000..d4a607946 --- /dev/null +++ b/linphone/oRTP/include/ortp/stun_udp.h @@ -0,0 +1,142 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * . + * + */ + +#ifndef __STUN_UDP_H__ +#define __STUN_UDP_H__ + +#ifndef __cplusplus +//#define bool int +//#define false 0 +//#define true 1 +#endif + +#ifdef __MACH__ +#include +#ifndef _SOCKLEN_T +typedef int socklen_t; +#endif +#endif + +#include + +#if !defined(_WIN32_WCE) +#include +#endif + +#if defined(WIN32) || defined(_WIN32_WCE) +#define snprintf _snprintf + +#include +/* #include */ + +typedef int socklen_t; +typedef SOCKET Socket; + +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEINPROGRESS +#define EALREADY WSAEALREADY +#define ENOTSOCK WSAENOTSOCK +#define EDESTADDRREQ WSAEDESTADDRREQ +#define EMSGSIZE WSAEMSGSIZE +#define EPROTOTYPE WSAEPROTOTYPE +#define ENOPROTOOPT WSAENOPROTOOPT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#define EOPNOTSUPP WSAEOPNOTSUPP +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EADDRINUSE WSAEADDRINUSE +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#define ENETDOWN WSAENETDOWN +#define ENETUNREACH WSAENETUNREACH +#define ENETRESET WSAENETRESET +#define ECONNABORTED WSAECONNABORTED +#define ECONNRESET WSAECONNRESET +#define ENOBUFS WSAENOBUFS +#define EISCONN WSAEISCONN +#define ENOTCONN WSAENOTCONN +#define ESHUTDOWN WSAESHUTDOWN +#define ETOOMANYREFS WSAETOOMANYREFS +#define ETIMEDOUT WSAETIMEDOUT +#define ECONNREFUSED WSAECONNREFUSED +#define ELOOP WSAELOOP +#define EHOSTDOWN WSAEHOSTDOWN +#define EHOSTUNREACH WSAEHOSTUNREACH +#define EPROCLIM WSAEPROCLIM +#define EUSERS WSAEUSERS +#define EDQUOT WSAEDQUOT +#define ESTALE WSAESTALE +#define EREMOTE WSAEREMOTE + +typedef LONGLONG Int64; + +#else + +typedef int Socket; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 + +#define closesocket(fd) close(fd) + +#define WSANOTINITIALISED EPROTONOSUPPORT + +#endif + +#ifdef __cplusplus +extern "C"{ +#endif + +int getErrno(void); + +/* Open a UDP socket to receive on the given port - if port is 0, pick a a + port, if interfaceIp!=0 then use ONLY the interface specified instead of + all of them */ +Socket +openPort( unsigned short port, unsigned int interfaceIp, + bool_t verbose); + + +/* recive a UDP message */ +bool_t +getMessage( Socket fd, char* buf, int* len, + unsigned int* srcIp, unsigned short* srcPort, + bool_t verbose); + + +/* send a UDP message */ +bool_t +sendMessage( Socket fd, char* msg, int len, + unsigned int dstIp, unsigned short dstPort, + bool_t verbose); + + +/* set up network - does nothing in unix but needed for windows */ +void +initNetwork(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/oRTP/include/ortp/telephonyevents.h b/linphone/oRTP/include/ortp/telephonyevents.h new file mode 100644 index 000000000..284e097ee --- /dev/null +++ b/linphone/oRTP/include/ortp/telephonyevents.h @@ -0,0 +1,105 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * \file telephonyevents.h + * \brief Receiving and sending telephone events (RFC2833) + * +**/ + + +#ifndef TELEPHONYEVENTS_H +#define TELEPHONYEVENTS_H + +#include + + +struct _telephone_event +{ +#ifdef ORTP_BIGENDIAN + uint32_t event:8; + uint32_t E:1; + uint32_t R:1; + uint32_t volume:6; + uint32_t duration:16; +#else + uint32_t event:8; + uint32_t volume:6; + uint32_t R:1; + uint32_t E:1; + uint32_t duration:16; +#endif +}; + +typedef struct _telephone_event telephone_event_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* tell if the session supports telephony events. For this the telephony events payload_type + must be present in the rtp profile used by the session */ + +/* low level functions */ +int rtp_session_telephone_events_supported(RtpSession *session); +int rtp_session_send_telephone_events_supported(RtpSession *session); +int rtp_session_recv_telephone_events_supported(RtpSession *session); + +mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start); + +int rtp_session_add_telephone_event(RtpSession *session, + mblk_t *packet, uint8_t event, int end, uint8_t volume, uint16_t duration); + +int rtp_session_read_telephone_event(RtpSession *session, + mblk_t *packet,telephone_event_t **tab); + +/* high level functions*/ +int rtp_session_send_dtmf(RtpSession *session, char dtmf, uint32_t userts); +int rtp_session_send_dtmf2(RtpSession *session, char dtmf, uint32_t userts, int duration); +/* for high level telephony event callback */ +void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0); + +#ifdef __cplusplus +} +#endif + +/* the size allocated for telephony events packets */ +#define TELEPHONY_EVENTS_ALLOCATED_SIZE (4*sizeof(telephone_event_t)) + +/* list of named events */ +#define TEV_DTMF_0 (0) +#define TEV_DTMF_1 (1) +#define TEV_DTMF_2 (2) +#define TEV_DTMF_3 (3) +#define TEV_DTMF_4 (4) +#define TEV_DTMF_5 (5) +#define TEV_DTMF_6 (6) +#define TEV_DTMF_7 (7) +#define TEV_DTMF_8 (8) +#define TEV_DTMF_9 (9) +#define TEV_DTMF_STAR (10) +#define TEV_DTMF_POUND (11) +#define TEV_DTMF_A (12) +#define TEV_DTMF_B (13) +#define TEV_DTMF_C (14) +#define TEV_DTMF_D (15) +#define TEV_FLASH (16) + + +#endif diff --git a/linphone/oRTP/oRTP.prj b/linphone/oRTP/oRTP.prj new file mode 100644 index 000000000..1c406516d --- /dev/null +++ b/linphone/oRTP/oRTP.prj @@ -0,0 +1,193 @@ +# Anjuta Version 1.1.97 +Compatibility Level: 1 + + +Some description + + + + + + + + + + + + + + + + + +props.file.type=project + +anjuta.version=1.1.97 +anjuta.compatibility.level=1 + +project.name=oRTP +project.type=GENERIC +project.target.type=EXECUTABLE +project.version=0.99 +project.author=Simon Morlat +project.source.target=Rtp stack +project.has.gettext=0 +project.gui.command= +project.programming.language=C +project.excluded.modules=intl + +project.config.extra.modules.before= +project.config.extra.modules.after= +project.config.blocked=1 +project.config.disable.overwriting=1 1 1 1 1 1 1 1 1 + +project.menu.entry=oRTP Version 0.99 +project.menu.group=Application +project.menu.comment=oRTP Version 0.99 +project.menu.icon= +project.menu.need.terminal=0 + +project.configure.options= +anjuta.program.arguments= +preferences.build.option.jobs=0 +preferences.build.option.silent=0 +preferences.build.option.autosave=1 +preferences.anjuta.make.options=-k +preferences.make=make +preferences.build.option.keep.going=1 +preferences.build.option.warn.undef=0 +preferences.autoformat.custom.style= -i8 -sc -bli0 -bl0 -cbi0 -ss +preferences.autoformat.style=Style of Kangleipak +preferences.indent.opening=0 +preferences.autoformat.disable=0 +preferences.indent.automatic=1 +preferences.use.tabs=1 +preferences.indent.size=4 +preferences.tabsize=4 +preferences.indent.closing=0 + +module.include.name=. +module.include.type= +module.include.files=\ + src/errno-win32.h\ + src/export.h\ + src/ortp-config-win32.h\ + src/ortp.h\ + src/payloadtype.h\ + src/port_fct.h\ + src/rtp.h\ + src/rtpmod.h\ + src/rtpport.h\ + src/rtpsession.h\ + src/rtpsignaltable.h\ + src/rtptimer.h\ + src/scheduler.h\ + src/sessionset.h\ + src/str_utils.h\ + src/telephonyevents.h\ + src/rtcp.h\ + ortp-config.h + +module.source.name=. +module.source.type= +module.source.files=\ + src/avprofile.c\ + src/export.c\ + src/mrtprecv.c\ + src/mrtpsend.c\ + src/ortp.c\ + src/ortpdlkm.c\ + src/payloadtype.c\ + src/port_fct.c\ + src/posixtimer.c\ + src/rtpmemtest.c\ + src/rtpmod.c\ + src/rtpparse.c\ + src/rtprecv.c\ + src/rtpsend.c\ + src/rtpsession.c\ + src/rtpsignaltable.c\ + src/rtptimer.c\ + src/scheduler.c\ + src/sessionset.c\ + src/str_utils.c\ + src/telephonyevents.c\ + src/test_tevrecv.c\ + src/test_tevsend.c\ + src/test_timer.c\ + src/tevmrtprecv.c\ + src/tevrtprecv.c\ + src/tevrtpsend.c + +module.pixmap.name=. +module.pixmap.type= +module.pixmap.files=\ + docs/html/home.png\ + docs/html/left.png\ + docs/html/right.png\ + docs/html/up.png + +module.data.name=. +module.data.type= +module.data.files= + +module.help.name=. +module.help.type= +module.help.files= + +module.doc.name=. +module.doc.type= +module.doc.files=\ + build/win32/oRTP/README\ + AUTHORS\ + COPYING\ + ChangeLog\ + INSTALL\ + NEWS\ + README\ + TODO\ + docs/tmpl/multiplexing.sgml\ + docs/tmpl/ortp-unused.sgml\ + docs/tmpl/payloads.sgml\ + docs/tmpl/rtpsessionapi.sgml\ + docs/tmpl/stackinit.sgml\ + docs/tmpl/stackmanagement.sgml\ + docs/tmpl/telephoneevents.sgml\ + docs/sgml/payloads.sgml\ + docs/sgml/tree_index.sgml\ + docs/sgml/object_index.sgml\ + docs/sgml/rtpsessionapi.sgml\ + docs/sgml/stackmanagement.sgml\ + docs/sgml/multiplexing.sgml\ + docs/sgml/telephoneevents.sgml\ + docs/ortp-docs.sgml\ + docs/html/book1.html\ + docs/html/ortpapi.html\ + docs/html/ortp-stack-management-functions.html\ + docs/html/ortp-rtpsession-api.html\ + docs/html/ortp-rtp-payloads-and-profiles.html\ + docs/html/ortp-multiplexing-sessions-(in-a-one-thread-design).html\ + docs/html/ortp-telephone-events-(rfc2833)-.html\ + docs/html/index.sgml\ + docs/html/ortp-library-management-functions.html + +module.po.files= + +compiler.options.supports= +compiler.options.include.paths=\ + .\ + .. +compiler.options.library.paths= +compiler.options.libraries= +compiler.options.libraries.selected= +compiler.options.defines=\ + HAVE_CONFIG_H +compiler.options.defines.selected= +compiler.options.warning.buttons=0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 +compiler.options.optimize.buttons=0 0 1 0 +compiler.options.other.buttons=1 0 +compiler.options.other.c.flags= +compiler.options.other.l.flags= +compiler.options.other.l.libs= + +project.src.paths= diff --git a/linphone/oRTP/oRTP.pws b/linphone/oRTP/oRTP.pws new file mode 100644 index 000000000..342999ad9 --- /dev/null +++ b/linphone/oRTP/oRTP.pws @@ -0,0 +1,67 @@ + +[executer] +RunInTerminal=true + +[Project DBase] +ShowLocals=true + +[filenumbers] +0=1846 +1=270 +2=1 +3=34 +4=43 +5=1 +6=4 +7=27 +8=9 + +[filemarkers] +0= +1= +2= +3= +4= +5= +6= +7= +8= + +[File View] +filter.file.unmatch=*.so *.o *.a *.la +filter.file.ignore.hidden=0 +filter.dir.ignore.hidden=0 + +[filelist] +0=/home/sangamon/src/devel/linphone/oRTP/src/rtpsession.c +1=/home/sangamon/src/devel/linphone/oRTP/src/rtpsession.h +2=/home/sangamon/src/devel/linphone/oRTP/src/rtcp.h +3=/home/sangamon/src/devel/linphone/oRTP/src/scheduler.c + +[Project Tree] +0=0 +1=0:1 + +[File Tree] +0=0 + +[replace_text] +0=telephone_event +1=session->rtp +2=PAYLOAD_AUDIO_CONTINUOUS +3=ortp_global_stats +4=session->rtp.rq +5=session->rtp.wq + +[find_text] +0=rtp_session_create +1=chunk_item_new +2=rtcp_calculate_sdes_padding +3=rtp_session_process +4=scheduler +5=rtp +6=rtp_send +7=RtpSession + +[find_in_files] +0=exit diff --git a/linphone/oRTP/ortp.doxygen.in b/linphone/oRTP/ortp.doxygen.in new file mode 100644 index 000000000..69ba62da2 --- /dev/null +++ b/linphone/oRTP/ortp.doxygen.in @@ -0,0 +1,225 @@ +# Doxyfile 1.5.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = oRTP +PROJECT_NUMBER = @ORTP_VERSION@ +OUTPUT_DIRECTORY = doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @srcdir@/src @srcdir@/include/ortp +FILE_PATTERNS = *.c *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = @srcdir@/src/tests +EXAMPLE_PATTERNS = *.c +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/linphone/oRTP/ortp.pc.in b/linphone/oRTP/ortp.pc.in new file mode 100644 index 000000000..8084faecd --- /dev/null +++ b/linphone/oRTP/ortp.pc.in @@ -0,0 +1,10 @@ +# This is a comment +prefix=@prefix@ +exec_prefix=@exec_prefix@ +includedir=@includedir@ + +Name: oRTP +Description: Implement the RFC3550 (RTP) with a easy to use API with high and low level access. +Version: @ORTP_PKGCONFIG_VERSION@ +Libs: -L@libdir@ -lortp @ORTPDEPS_LIBS@ +Cflags: -I@includedir@ @ORTPDEPS_CFLAGS@ diff --git a/linphone/oRTP/ortp.spec.in b/linphone/oRTP/ortp.spec.in new file mode 100644 index 000000000..f73cdfcdf --- /dev/null +++ b/linphone/oRTP/ortp.spec.in @@ -0,0 +1,83 @@ +# -*- rpm-spec -*- +# +# ortp -- Real-time Transport Protocol Stack +# +# Default is optimized for Pentium IV but will execute on Pentium II & +# later (i686). + +%ifarch %ix86 +%define ortp_cpu pentium4 +%endif + +Summary: Real-time Transport Protocol Stack +Name: ortp +Version: @ORTP_PKGCONFIG_VERSION@ +Release: 1 +License: LGPL +Group: Applications/Communications +URL: http://linphone.org/ortp/ +Source0: %{name}-@ORTP_PKGCONFIG_VERSION@.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +%ifarch %ix86 +BuildArch: i686 +%endif + +%description +oRTP is a LGPL licensed C library implementing the RTP protocol +(rfc1889). It is available for most unix clones (primilarly Linux and +HP-UX), and Microsoft Windows. + +%package devel +Summary: Headers, libraries and docs for the oRTP library +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +oRTP is a LGPL licensed C library implementing the RTP protocol +(rfc1889). It is available for most unix clones (primilarly Linux and +HP-UX), and Microsoft Windows. + +This package contains header files and development libraries needed to +develop programs using the oRTP library. + +%ifarch %ix86 +%define ortp_arch_cflags -malign-double -march=i686 -mcpu=%{ortp_cpu} +%else +# Must be non-empty +%define ortp_arch_cflags -Wall +%endif +%define ortp_cflags %ortp_arch_cflags -Wall -g -pipe -pthread -O3 -fomit-frame-pointer -fno-schedule-insns -fschedule-insns2 -fstrict-aliasing + +%prep +%setup -q + +%build +%configure \ + --enable-shared \ + --enable-static +%{__make} -j$RPM_BUILD_NCPUS CFLAGS="%ortp_cflags" CXXFLAGS="%ortp_cflags" + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO +%{_libdir}/*.so.* + +%files devel +%defattr(-,root,root,-) +%doc doc/html +%{_libdir}/*.la +%{_libdir}/*.a +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_includedir} + +%changelog +* Tue Oct 25 2005 Francois-Xavier Kowalski +- Add to oRTP distribution with "make rpm" target diff --git a/linphone/oRTP/pkg.list b/linphone/oRTP/pkg.list new file mode 100644 index 000000000..e02f91683 --- /dev/null +++ b/linphone/oRTP/pkg.list @@ -0,0 +1,38 @@ +# -*- rpm-spec -*- ############################################################ +# +# EPM list file. See epm(1) and epm.list(5) for details +# +############################################################################### + +%product ${SUMMARY} +%version ${VERSION} +%release ${RELEASE} +%description ${SUMMARY} +%vendor ${VENDOR} +%copyright ${LICENSE} +%license ${LICENSE} +%readme ${srcdir}/README +%packager ${PACKAGER} + +%system linux + +# Package all-in one: should be split later on... +%provides ortp-devel + +%postinstall << EOF +ldconfig 2>&1 | logger -i -s -t ${PACKAGE} +EOF + +%postremove << EOF +ldconfig 2>&1 | logger -i -s -t ${PACKAGE} +EOF + +%system hpux + +%system all + +%include files.list + +%provides ortp +%replaces ortp + diff --git a/linphone/oRTP/src/.cvsignore b/linphone/oRTP/src/.cvsignore new file mode 100644 index 000000000..fec93a5ec --- /dev/null +++ b/linphone/oRTP/src/.cvsignore @@ -0,0 +1,15 @@ +*.lo +.deps +.libs +Makefile +Makefile.in +libortp.la +mrtprecv +mrtpsend +rtpmemtest +rtprecv +rtpsend +test_timer +tevmrtprecv +tevrtprecv +tevrtpsend diff --git a/linphone/oRTP/src/Makefile.am b/linphone/oRTP/src/Makefile.am new file mode 100644 index 000000000..3a6ca3780 --- /dev/null +++ b/linphone/oRTP/src/Makefile.am @@ -0,0 +1,41 @@ + +EXTRA_DIST=ortp-config-win32.h dll_entry.c + +AM_CFLAGS= $(PTHREAD_CFLAGS) -I$(top_srcdir) $(TRUESPEECH_CFLAGS) $(SRTP_CFLAGS) +AM_LDFLAGS= $(PTHREAD_LDFLAGS) + +INCLUDES=-I$(top_srcdir)/include/ + +lib_LTLIBRARIES = libortp.la + +libortp_la_SOURCES= str_utils.c \ + port.c \ + rtpparse.c \ + rtpsession.c \ + rtpsession_inet.c \ + rtpsession_priv.h \ + jitterctl.c jitterctl.h \ + rtpsignaltable.c \ + rtptimer.c rtptimer.h \ + posixtimer.c \ + ortp.c \ + scheduler.c scheduler.h \ + avprofile.c \ + sessionset.c \ + telephonyevents.c \ + payloadtype.c \ + rtcp.c \ + utils.c utils.h \ + rtcpparse.c \ + event.c \ + stun.c stun_udp.c \ + srtp.c \ + b64.c + + +libortp_la_LIBADD= $(PTHREAD_LIBS) -lm $(SRTP_LIBS) + +libortp_la_LDFLAGS= -version-info $(LIBORTP_SO_VERSION) + + +SUBDIRS= . tests diff --git a/linphone/oRTP/src/avprofile.c b/linphone/oRTP/src/avprofile.c new file mode 100644 index 000000000..8939abf35 --- /dev/null +++ b/linphone/oRTP/src/avprofile.c @@ -0,0 +1,483 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include + +char offset127=127; +char offset0xD5=(char)0xD5; +char offset0[4] = {0x00, 0x00, 0x00, 0x00}; + +/* + * IMPORTANT : some compiler don't support the tagged-field syntax. Those + * macros are there to trap the problem This means that if you want to keep + * portability, payload types must be defined with their fields in the right + * order. + */ +#if defined(_ISOC99_SOURCE) +// ISO C99's tagged syntax +#define TYPE(val) .type=(val) +#define CLOCK_RATE(val) .clock_rate=(val) +#define BITS_PER_SAMPLE(val) .bits_per_sample=(val) +#define ZERO_PATTERN(val) .zero_pattern=(val) +#define PATTERN_LENGTH(val) .pattern_length=(val) +#define NORMAL_BITRATE(val) .normal_bitrate=(val) +#define MIME_TYPE(val) .mime_type=(val) +#define CHANNELS(val) .channels=(val) +#define FMTP(val) .FMTP=(val) +#elif defined(__GNUC__) +// GCC's legacy tagged syntax (even old versions have it) +#define TYPE(val) type: (val) +#define CLOCK_RATE(val) clock_rate: (val) +#define BITS_PER_SAMPLE(val) bits_per_sample: (val) +#define ZERO_PATTERN(val) zero_pattern: (val) +#define PATTERN_LENGTH(val) pattern_length: (val) +#define NORMAL_BITRATE(val) normal_bitrate: (val) +#define MIME_TYPE(val) mime_type: (val) +#define CHANNELS(val) channels: (val) +#define FMTP(val) FMTP: (val) +#else +// No tagged syntax supported +#define TYPE(val) (val) +#define CLOCK_RATE(val) (val) +#define BITS_PER_SAMPLE(val) (val) +#define ZERO_PATTERN(val) (val) +#define PATTERN_LENGTH(val) (val) +#define NORMAL_BITRATE(val) (val) +#define MIME_TYPE(val) (val) +#define CHANNELS(val) (val) +#define FMTP(val) (val) + +#endif + +PayloadType payload_type_pcmu8000={ + TYPE( PAYLOAD_AUDIO_CONTINUOUS), + CLOCK_RATE( 8000), + BITS_PER_SAMPLE(8), + ZERO_PATTERN( &offset127), + PATTERN_LENGTH( 1), + NORMAL_BITRATE( 64000), + MIME_TYPE ("PCMU"), + CHANNELS(1) +}; + +PayloadType payload_type_pcma8000={ + TYPE( PAYLOAD_AUDIO_CONTINUOUS), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(8), + ZERO_PATTERN( &offset0xD5), + PATTERN_LENGTH( 1), + NORMAL_BITRATE( 64000), + MIME_TYPE ("PCMA"), + CHANNELS(1) +}; + +PayloadType payload_type_pcm8000={ + TYPE( PAYLOAD_AUDIO_CONTINUOUS), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(16), + ZERO_PATTERN( offset0), + PATTERN_LENGTH(1), + NORMAL_BITRATE( 128000), + MIME_TYPE ("PCM"), + CHANNELS(1) +}; + +PayloadType payload_type_l16_mono={ + TYPE( PAYLOAD_AUDIO_CONTINUOUS), + CLOCK_RATE(44100), + BITS_PER_SAMPLE(16), + ZERO_PATTERN( offset0 ), + PATTERN_LENGTH(2), + NORMAL_BITRATE(705600), /* (44100 x 16bits per frame x 1 channel) */ + MIME_TYPE ("L16"), + CHANNELS(1) +}; + +PayloadType payload_type_l16_stereo={ + TYPE( PAYLOAD_AUDIO_CONTINUOUS), + CLOCK_RATE(44100), + BITS_PER_SAMPLE(32), /* 16bits x 2 channels */ + ZERO_PATTERN( offset0 ), + PATTERN_LENGTH(4), + NORMAL_BITRATE(1411200), /* (44100 x 16bits per frame x 2 channels) */ + MIME_TYPE ("L16"), + CHANNELS(2) +}; + +PayloadType payload_type_lpc1016={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN( NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 2400), + MIME_TYPE ("1016"), + CHANNELS(1) +}; + + +PayloadType payload_type_gsm= +{ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 13500), + MIME_TYPE ("GSM"), + CHANNELS(1) +}; + +PayloadType payload_type_lpc= +{ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 5600), /* 20ms / 14 octets per frame */ + MIME_TYPE ("LPC"), + CHANNELS(1) +}; + +PayloadType payload_type_g7231= +{ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 6300), + MIME_TYPE ("G723"), + CHANNELS(1) +}; + +PayloadType payload_type_g729={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 8000), + MIME_TYPE ("G729"), + CHANNELS(1) +}; + +PayloadType payload_type_g726_40={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 8000), + MIME_TYPE ("G726-40"), + CHANNELS(1) +}; + +PayloadType payload_type_g726_32={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 8000), + MIME_TYPE ("G726-32"), + CHANNELS(1) +}; + +PayloadType payload_type_g726_24={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 8000), + MIME_TYPE ("G726-24"), + CHANNELS(1) +}; + +PayloadType payload_type_g726_16={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE( 8000), + MIME_TYPE ("G726-16"), + CHANNELS(1) +}; + +PayloadType payload_type_mpv= +{ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE( 256000), + MIME_TYPE ("MPV"), + CHANNELS(0) +}; + + +PayloadType payload_type_h261={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("H261"), + CHANNELS(0) +}; + +PayloadType payload_type_h263={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(256000), + MIME_TYPE ("H263"), + CHANNELS(0) +}; + +PayloadType payload_type_truespeech= +{ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE( 0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH( 0), + NORMAL_BITRATE(8536), + MIME_TYPE ("TSP0"), + CHANNELS(0) +}; + + +#ifdef __cplusplus +extern "C" +{ +#endif +RtpProfile av_profile; +#ifdef __cplusplus +} +#endif + + +void av_profile_init(RtpProfile *profile) +{ + rtp_profile_clear_all(profile); + profile->name="AV profile"; + rtp_profile_set_payload(profile,0,&payload_type_pcmu8000); + rtp_profile_set_payload(profile,1,&payload_type_lpc1016); + rtp_profile_set_payload(profile,3,&payload_type_gsm); + rtp_profile_set_payload(profile,7,&payload_type_lpc); + rtp_profile_set_payload(profile,4,&payload_type_g7231); + rtp_profile_set_payload(profile,8,&payload_type_pcma8000); + rtp_profile_set_payload(profile,10,&payload_type_l16_stereo); + rtp_profile_set_payload(profile,11,&payload_type_l16_mono); + rtp_profile_set_payload(profile,18,&payload_type_g729); + rtp_profile_set_payload(profile,31,&payload_type_h261); + rtp_profile_set_payload(profile,32,&payload_type_mpv); + rtp_profile_set_payload(profile,34,&payload_type_h263); +} + +/* these are extra payload types that can be used dynamically */ +PayloadType payload_type_lpc1015={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(2400), + MIME_TYPE ("1015"), + CHANNELS(1) +}; + +PayloadType payload_type_speex_nb={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(8000), /*not true: 8000 is the minimum*/ + MIME_TYPE ("speex"), + CHANNELS(1) +}; + +PayloadType payload_type_speex_wb={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(16000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(28000), + MIME_TYPE ("speex"), + CHANNELS(1) +}; + +PayloadType payload_type_speex_uwb={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(32000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(28000), + MIME_TYPE ("speex"), + CHANNELS(1) +}; + +PayloadType payload_type_ilbc={ + TYPE( PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(13300), /* the minimum, with 30ms frames */ + MIME_TYPE ("iLBC"), + CHANNELS(1), +}; + +PayloadType payload_type_amr={ + TYPE(PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("AMR"), + CHANNELS(1) +}; + +PayloadType payload_type_amrwb={ + TYPE(PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(16000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("AMR-WB"), + CHANNELS(1) +}; + +PayloadType payload_type_mp4v={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("MP4V-ES"), + CHANNELS(0) +}; + + +PayloadType payload_type_evrc0={ + TYPE(PAYLOAD_AUDIO_PACKETIZED), + CLOCK_RATE(8000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("EVRC0"), + CHANNELS(1) +}; + + +PayloadType payload_type_h263_1998={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(256000), + MIME_TYPE ("H263-1998"), + CHANNELS(0) +}; + +PayloadType payload_type_h263_2000={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(0), + MIME_TYPE ("H263-2000"), + CHANNELS(0) +}; + +PayloadType payload_type_theora={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(256000), + MIME_TYPE ("theora"), + CHANNELS(0) +}; + +PayloadType payload_type_h264={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(256000), + MIME_TYPE ("H264"), + CHANNELS(0) +}; + +PayloadType payload_type_x_snow={ + TYPE( PAYLOAD_VIDEO), + CLOCK_RATE(90000), + BITS_PER_SAMPLE(0), + ZERO_PATTERN(NULL), + PATTERN_LENGTH(0), + NORMAL_BITRATE(256000), + MIME_TYPE ("x-snow"), + CHANNELS(0) +}; + +PayloadType payload_type_t140={ + PAYLOAD_AUDIO_PACKETIZED, /*type */ + 1000, + 0, + NULL, + 0, + 0, + "t140", + 0, + 0 +}; + +PayloadType payload_type_x_udpftp={ + PAYLOAD_AUDIO_PACKETIZED, /*type */ + 1000, + 0, + NULL, + 0, + 0, + "x-udpftp", + 0, + 0 +}; + diff --git a/linphone/oRTP/src/b64.c b/linphone/oRTP/src/b64.c new file mode 100644 index 000000000..352367198 --- /dev/null +++ b/linphone/oRTP/src/b64.c @@ -0,0 +1,606 @@ +/* ///////////////////////////////////////////////////////////////////////////// + * File: b64.c + * + * Purpose: Implementation file for the b64 library + * + * Created: 18th October 2004 + * Updated: 3rd May 2008 + * + * Home: http://synesis.com.au/software/ + * + * Copyright (c) 2004-2008, Matthew Wilson and Synesis Software + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of + * any contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * ////////////////////////////////////////////////////////////////////////// */ + + +/** \file b64.c Implementation file for the b64 library + */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Version information + */ + +#ifndef B64_DOCUMENTATION_SKIP_SECTION +# define B64_VER_C_B64_MAJOR 1 +# define B64_VER_C_B64_MINOR 2 +# define B64_VER_C_B64_REVISION 3 +# define B64_VER_C_B64_EDIT 17 +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Includes + */ + +#include "ortp/b64.h" + +#include +#include + +/* ///////////////////////////////////////////////////////////////////////////// + * Constants and definitions + */ + +#ifndef B64_DOCUMENTATION_SKIP_SECTION +# define NUM_PLAIN_DATA_BYTES (3) +# define NUM_ENCODED_DATA_BYTES (4) +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Macros + */ + +#ifndef NUM_ELEMENTS +# define NUM_ELEMENTS(x) (sizeof(x) / sizeof(x[0])) +#endif /* !NUM_ELEMENTS */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Warnings + */ + +#if defined(_MSC_VER) && \ + _MSC_VER < 1000 +# pragma warning(disable : 4705) +#endif /* _MSC_VER < 1000 */ + +/* ///////////////////////////////////////////////////////////////////////////// + * Data + */ + +static const char b64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const signed char b64_indexes[] = +{ + /* 0 - 31 / 0x00 - 0x1f */ + -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + /* 32 - 63 / 0x20 - 0x3f */ + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, 62, -1, -1, -1, 63 /* ... , '+', ... '/' */ + , 52, 53, 54, 55, 56, 57, 58, 59 /* '0' - '7' */ + , 60, 61, -1, -1, -1, -1, -1, -1 /* '8', '9', ... */ + /* 64 - 95 / 0x40 - 0x5f */ + , -1, 0, 1, 2, 3, 4, 5, 6 /* ..., 'A' - 'G' */ + , 7, 8, 9, 10, 11, 12, 13, 14 /* 'H' - 'O' */ + , 15, 16, 17, 18, 19, 20, 21, 22 /* 'P' - 'W' */ + , 23, 24, 25, -1, -1, -1, -1, -1 /* 'X', 'Y', 'Z', ... */ + /* 96 - 127 / 0x60 - 0x7f */ + , -1, 26, 27, 28, 29, 30, 31, 32 /* ..., 'a' - 'g' */ + , 33, 34, 35, 36, 37, 38, 39, 40 /* 'h' - 'o' */ + , 41, 42, 43, 44, 45, 46, 47, 48 /* 'p' - 'w' */ + , 49, 50, 51, -1, -1, -1, -1, -1 /* 'x', 'y', 'z', ... */ + + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* ///////////////////////////////////////////////////////////////////////////// + * Helper functions + */ + +/** This function reads in 3 bytes at a time, and translates them into 4 + * characters. + */ +static size_t b64_encode_( unsigned char const *src + , size_t srcSize + , char *const dest + , size_t destLen + , unsigned lineLen + , B64_RC *rc) +{ + size_t total = ((srcSize + (NUM_PLAIN_DATA_BYTES - 1)) / NUM_PLAIN_DATA_BYTES) * NUM_ENCODED_DATA_BYTES; + + assert(NULL != rc); + *rc = B64_RC_OK; + + if(lineLen > 0) + { + size_t numLines = (total + (lineLen - 1)) / lineLen; + + total += 2 * (numLines - 1); + } + + if(NULL == dest) + { + return total; + } + else if(destLen < total) + { + *rc = B64_RC_INSUFFICIENT_BUFFER; + + return 0; + } + else + { + char *p = dest; + char *end = dest + destLen; + size_t len = 0; + + for(; NUM_PLAIN_DATA_BYTES <= srcSize; srcSize -= NUM_PLAIN_DATA_BYTES) + { + char characters[NUM_ENCODED_DATA_BYTES]; + + /* + * + * | 0 | 1 | 2 | + * + * | | | | + * | | | | | | | + * | | | | | | | | | | | | | + * | | | | | | | | | | | | | | | | | | | | | | | | | + * + * | 0 | 1 | 2 | 3 | + * + */ + + /* characters[0] is the 6 left-most bits of src[0] */ + characters[0] = (char)((src[0] & 0xfc) >> 2); + /* characters[0] is the right-most 2 bits of src[0] and the left-most 4 bits of src[1] */ + characters[1] = (char)(((src[0] & 0x03) << 4) + ((src[1] & 0xf0) >> 4)); + /* characters[0] is the right-most 4 bits of src[1] and the 2 left-most bits of src[2] */ + characters[2] = (char)(((src[1] & 0x0f) << 2) + ((src[2] & 0xc0) >> 6)); + /* characters[3] is the right-most 6 bits of src[2] */ + characters[3] = (char)(src[2] & 0x3f); + +#ifndef __WATCOMC__ + assert(characters[0] >= 0 && characters[0] < 64); + assert(characters[1] >= 0 && characters[1] < 64); + assert(characters[2] >= 0 && characters[2] < 64); + assert(characters[3] >= 0 && characters[3] < 64); +#endif /* __WATCOMC__ */ + + src += NUM_PLAIN_DATA_BYTES; + *p++ = b64_chars[(unsigned char)characters[0]]; + assert(NULL != strchr(b64_chars, *(p-1))); + ++len; + assert(len != lineLen); + + *p++ = b64_chars[(unsigned char)characters[1]]; + assert(NULL != strchr(b64_chars, *(p-1))); + ++len; + assert(len != lineLen); + + *p++ = b64_chars[(unsigned char)characters[2]]; + assert(NULL != strchr(b64_chars, *(p-1))); + ++len; + assert(len != lineLen); + + *p++ = b64_chars[(unsigned char)characters[3]]; + assert(NULL != strchr(b64_chars, *(p-1))); + + if( ++len == lineLen && + p != end) + { + *p++ = '\r'; + *p++ = '\n'; + len = 0; + } + } + + if(0 != srcSize) + { + /* Deal with the overspill, by boosting it up to three bytes (using 0s) + * and then appending '=' for any missing characters. + * + * This is done into a temporary buffer, so we can call ourselves and + * have the output continue to be written direct to the destination. + */ + + unsigned char dummy[NUM_PLAIN_DATA_BYTES]; + size_t i; + + for(i = 0; i < srcSize; ++i) + { + dummy[i] = *src++; + } + + for(; i < NUM_PLAIN_DATA_BYTES; ++i) + { + dummy[i] = '\0'; + } + + b64_encode_(&dummy[0], NUM_PLAIN_DATA_BYTES, p, NUM_ENCODED_DATA_BYTES * (1 + 2), 0, rc); + + for(p += 1 + srcSize; srcSize++ < NUM_PLAIN_DATA_BYTES; ) + { + *p++ = '='; + } + } + + return total; + } +} + +/** This function reads in a character string in 4-character chunks, and writes + * out the converted form in 3-byte chunks to the destination. + */ +static size_t b64_decode_( char const *src + , size_t srcLen + , unsigned char *dest + , size_t destSize + , unsigned flags + , char const **badChar + , B64_RC *rc) +{ + const size_t wholeChunks = (srcLen / NUM_ENCODED_DATA_BYTES); + const size_t remainderBytes = (srcLen % NUM_ENCODED_DATA_BYTES); + size_t maxTotal = (wholeChunks + (0 != remainderBytes)) * NUM_PLAIN_DATA_BYTES; + unsigned char *dest_ = dest; + + ((void)remainderBytes); + + assert(NULL != badChar); + assert(NULL != rc); + + *badChar = NULL; + *rc = B64_RC_OK; + + if(NULL == dest) + { + return maxTotal; + } + else if(destSize < maxTotal) + { + *rc = B64_RC_INSUFFICIENT_BUFFER; + + return 0; + } + else + { + /* Now we iterate through the src, collecting together four characters + * at a time from the Base-64 alphabet, until the end-point is reached. + * + * + */ + + char const *begin = src; + char const *const end = begin + srcLen; + size_t currIndex = 0; + size_t numPads = 0; + signed char indexes[NUM_ENCODED_DATA_BYTES]; /* 4 */ + + for(; begin != end; ++begin) + { + const char ch = *begin; + + if('=' == ch) + { + assert(currIndex < NUM_ENCODED_DATA_BYTES); + + indexes[currIndex++] = '\0'; + + ++numPads; + } + else + { + /* NOTE: Had to rename 'index' to 'ix', due to name clash with GCC on 64-bit Linux. */ + signed char ix = b64_indexes[(unsigned char)ch]; + + if(-1 == ix) + { + switch(ch) + { + case ' ': + case '\t': + case '\b': + case '\v': + if(B64_F_STOP_ON_UNEXPECTED_WS & flags) + { + *rc = B64_RC_DATA_ERROR; + *badChar = begin; + return 0; + } + else + { + /* Fall through */ + } + case '\r': + case '\n': + continue; + default: + if(B64_F_STOP_ON_UNKNOWN_CHAR & flags) + { + *rc = B64_RC_DATA_ERROR; + *badChar = begin; + return 0; + } + else + { + continue; + } + } + } + else + { + numPads = 0; + + assert(currIndex < NUM_ENCODED_DATA_BYTES); + + indexes[currIndex++] = ix; + } + } + + if(NUM_ENCODED_DATA_BYTES == currIndex) + { + unsigned char bytes[NUM_PLAIN_DATA_BYTES]; /* 3 */ + + bytes[0] = (unsigned char)((indexes[0] << 2) + ((indexes[1] & 0x30) >> 4)); + + currIndex = 0; + + *dest++ = bytes[0]; + if(2 != numPads) + { + bytes[1] = (unsigned char)(((indexes[1] & 0xf) << 4) + ((indexes[2] & 0x3c) >> 2)); + + *dest++ = bytes[1]; + + if(1 != numPads) + { + bytes[2] = (unsigned char)(((indexes[2] & 0x3) << 6) + indexes[3]); + + *dest++ = bytes[2]; + } + } + if(0 != numPads) + { + break; + } + } + } + + return (size_t)(dest - dest_); + } +} + +/* ///////////////////////////////////////////////////////////////////////////// + * API functions + */ + +size_t b64_encode(void const *src, size_t srcSize, char *dest, size_t destLen) +{ + /* Use Null Object (Variable) here for rc, so do not need to check + * elsewhere. + */ + B64_RC rc_; + + return b64_encode_((unsigned char const*)src, srcSize, dest, destLen, 0, &rc_); +} + +size_t b64_encode2( void const *src + , size_t srcSize + , char *dest + , size_t destLen + , unsigned flags + , int lineLen /* = -1 */ + , B64_RC *rc /* = NULL */) +{ + /* Use Null Object (Variable) here for rc, so do not need to check + * elsewhere + */ + B64_RC rc_; + if(NULL == rc) + { + rc = &rc_; + } + + switch(B64_F_LINE_LEN_MASK & flags) + { + case B64_F_LINE_LEN_USE_PARAM: + if(lineLen >= 0) + { + break; + } + /* Fall through to 64 */ + case B64_F_LINE_LEN_64: + lineLen = 64; + break; + case B64_F_LINE_LEN_76: + lineLen = 76; + break; + default: + assert(!"Bad line length flag specified to b64_encode2()"); + case B64_F_LINE_LEN_INFINITE: + lineLen = 0; + break; + } + + assert(0 == (lineLen % 4)); + + return b64_encode_((unsigned char const*)src, srcSize, dest, destLen, (unsigned)lineLen, rc); +} + +size_t b64_decode(char const *src, size_t srcLen, void *dest, size_t destSize) +{ + /* Use Null Object (Variable) here for rc and badChar, so do not need to + * check elsewhere. + */ + char const *badChar_; + B64_RC rc_; + + return b64_decode_(src, srcLen, (unsigned char*)dest, destSize, B64_F_STOP_ON_NOTHING, &badChar_, &rc_); +} + +size_t b64_decode2( char const *src + , size_t srcLen + , void *dest + , size_t destSize + , unsigned flags + , char const **badChar /* = NULL */ + , B64_RC *rc /* = NULL */) +{ + char const *badChar_; + B64_RC rc_; + + /* Use Null Object (Variable) here for rc and badChar, so do not need to + * check elsewhere. + */ + if(NULL == badChar) + { + badChar = &badChar_; + } + if(NULL == rc) + { + rc = &rc_; + } + + return b64_decode_(src, srcLen, (unsigned char*)dest, destSize, flags, badChar, rc); +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef B64_DOCUMENTATION_SKIP_SECTION +struct b64ErrorString_t_ +#else /* !B64_DOCUMENTATION_SKIP_SECTION */ +typedef struct b64ErrorString_t_ b64ErrorString_t_; +struct b64ErrorString_t_ +#endif /* !B64_DOCUMENTATION_SKIP_SECTION */ +{ + int code; /*!< The error code. */ + char const *str; /*!< The string. */ + size_t len; /*!< The string length. */ +}; + + + +#define SEVERITY_STR_DECL(rc, desc) \ + \ + static const char s_str##rc[] = desc; \ + static const b64ErrorString_t_ s_rct##rc = { rc, s_str##rc, NUM_ELEMENTS(s_str##rc) - 1 } + + +#define SEVERITY_STR_ENTRY(rc) \ + \ + &s_rct##rc + + +static char const *b64_LookupCodeA_(int code, b64ErrorString_t_ const **mappings, size_t cMappings, size_t *len) +{ + /* Use Null Object (Variable) here for len, so do not need to check + * elsewhere. + */ + size_t len_; + + if(NULL == len) + { + len = &len_; + } + + /* Checked, indexed search. */ + if( code >= 0 && + code < B64_max_RC_value) + { + if(code == mappings[code]->code) + { + return (*len = mappings[code]->len, mappings[code]->str); + } + } + + /* Linear search. Should only be needed if order in + * b64_LookupErrorStringA_() messed up. + */ + { size_t i; for(i = 0; i < cMappings; ++i) + { + if(code == mappings[i]->code) + { + return (*len = mappings[i]->len, mappings[i]->str); + } + }} + + return (*len = 0, ""); +} + +static char const *b64_LookupErrorStringA_(int error, size_t *len) +{ + SEVERITY_STR_DECL(B64_RC_OK , "Operation was successful" ); + SEVERITY_STR_DECL(B64_RC_INSUFFICIENT_BUFFER , "The given translation buffer was not of sufficient size" ); + SEVERITY_STR_DECL(B64_RC_TRUNCATED_INPUT , "The input did not represent a fully formed stream of octet couplings" ); + SEVERITY_STR_DECL(B64_RC_DATA_ERROR , "Invalid data" ); + + static const b64ErrorString_t_ *s_strings[] = + { + SEVERITY_STR_ENTRY(B64_RC_OK), + SEVERITY_STR_ENTRY(B64_RC_INSUFFICIENT_BUFFER), + SEVERITY_STR_ENTRY(B64_RC_TRUNCATED_INPUT), + SEVERITY_STR_ENTRY(B64_RC_DATA_ERROR), + }; + + return b64_LookupCodeA_(error, s_strings, NUM_ELEMENTS(s_strings), len); +} + +char const *b64_getErrorString(B64_RC code) +{ + return b64_LookupErrorStringA_((int)code, NULL); +} + +size_t b64_getErrorStringLength(B64_RC code) +{ + size_t len; + + return (b64_LookupErrorStringA_((int)code, &len), len); +} + +/* ////////////////////////////////////////////////////////////////////////// */ diff --git a/linphone/oRTP/src/dll_entry.c b/linphone/oRTP/src/dll_entry.c new file mode 100644 index 000000000..37ac6cf12 --- /dev/null +++ b/linphone/oRTP/src/dll_entry.c @@ -0,0 +1,147 @@ + +#ifdef WIN32 +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif +#include "ortp/ortp.h" + +typedef struct __STRUCT_SHARED_DATA__ +{ + DWORD m_nReference; + DWORD m_dwStartTime; + BOOL m_bInitialize; + +} SHARED_DATA, * LPSHARED_DATA; + +#ifdef EXTERNAL_LOGGER +#include "logger.h" +#else +#define RegisterLog(logVar, logString); +#define UnregisterLog(logVar, logString); +#endif + +extern DWORD dwoRTPLogLevel; + +#define SHMEMSIZE sizeof(SHARED_DATA) + +static LPSHARED_DATA lpSharedData; +static HANDLE hMapObject = NULL; // handle to file mapping + +BOOL WINAPI DllMain( + HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpReserved // reserved + ) +{ + BOOL fInit = FALSE; + WORD wVersionRequested; + WSADATA wsaData; + + // Perform actions based on the reason for calling. + switch( fdwReason ) + { + case DLL_PROCESS_ATTACH: + + OutputDebugString("--> dll_entry.c - oRTP.dll - DLL_PROCESS_ATTACH()\n"); + + wVersionRequested = MAKEWORD( 1, 0 ); + + if (WSAStartup(wVersionRequested,&wsaData)!=0) + { + return FALSE; + } + + // Create a named file mapping object. + hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file + NULL, // default security attributes + PAGE_READWRITE, // read/write access + 0, // size: high 32-bits + SHMEMSIZE, // size: low 32-bits + "oRTPSharedMemory"); // name of map object + + if (hMapObject == NULL) + return FALSE; + + // The first process to attach initializes memory. + fInit = (GetLastError() != ERROR_ALREADY_EXISTS); + + // Get a pointer to the file-mapped shared memory. + + lpSharedData = (LPSHARED_DATA) MapViewOfFile( hMapObject, // object to map view of + FILE_MAP_WRITE, // read/write access + 0, // high offset: map from + 0, // low offset: beginning + 0); // default: map entire file + if (lpSharedData == NULL) + return FALSE; + + // Initialize memory if this is the first process. + + if (fInit) + { + OutputDebugString("--> dll_entry.c - oRTP.dll - Initializing module\n"); + + lpSharedData->m_dwStartTime = GetTickCount(); + lpSharedData->m_nReference = 1; + lpSharedData->m_bInitialize = FALSE; + + // Register the log + RegisterLog(&dwoRTPLogLevel, "LOG_ORTP"); + } + else + { + OutputDebugString("--> dll_entry.c - oRTP.dll - Binding\n"); + lpSharedData->m_nReference++; + } + break; + + case DLL_THREAD_ATTACH: + + if (lpSharedData != NULL) + { + if (lpSharedData->m_bInitialize == FALSE) + { + // Initialize oRTP + ortp_init(); + + // Start the scheduler + //ortp_scheduler_init(); + + lpSharedData->m_bInitialize = TRUE; + } + } + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + + if (lpSharedData != NULL) + { + OutputDebugString("--> dll_entry.c - oRTP.dll - Binding\n"); + lpSharedData->m_nReference--; + + if (lpSharedData->m_nReference == 0) + { + OutputDebugString("--> dll_entry.c - oRTP.dll - Detaching\n"); + + ortp_exit(); + UnregisterLog(&dwoRTPLogLevel, "LOG_ORTP"); + + + // Unmap shared memory from the process's address space. + UnmapViewOfFile(lpSharedData); + lpSharedData = NULL; + + // Close the process's handle to the file-mapping object. + CloseHandle(hMapObject); + hMapObject = INVALID_HANDLE_VALUE; + } + } + break; + } + + return TRUE; // Successful DLL_PROCESS_ATTACH. +} diff --git a/linphone/oRTP/src/event.c b/linphone/oRTP/src/event.c new file mode 100644 index 000000000..00718e2e7 --- /dev/null +++ b/linphone/oRTP/src/event.c @@ -0,0 +1,116 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/event.h" +#include "ortp/ortp.h" + +RtpEndpoint *rtp_endpoint_new(struct sockaddr *addr, socklen_t addrlen){ + RtpEndpoint *ep=ortp_new(RtpEndpoint,1); + if (sizeof(ep->addr)addr,addr,addrlen); + ep->addrlen=addrlen; + return ep; +} + +void rtp_endpoint_destroy(RtpEndpoint *ep){ + ortp_free(ep); +} + +RtpEndpoint *rtp_endpoint_dup(const RtpEndpoint *ep){ + return rtp_endpoint_new((struct sockaddr*)&ep->addr,ep->addrlen); +} + +OrtpEvent * ortp_event_new(unsigned long type){ + const int size=sizeof(OrtpEventType)+sizeof(OrtpEventData); + mblk_t *m=allocb(size,0); + memset(m->b_wptr,0,size); + *((OrtpEventType*)m->b_wptr)=type; + return m; +} + +OrtpEvent *ortp_event_dup(OrtpEvent *ev){ +#if 0 + OrtpEvent *nev=dupb(ev); +#else + OrtpEvent *nev = ortp_event_new(ortp_event_get_type(ev)); + OrtpEventData * ed = ortp_event_get_data(ev); + OrtpEventData * edv = ortp_event_get_data(nev); + + if (ed->ep) edv->ep = rtp_endpoint_dup(ed->ep); + if (ed->packet) edv->packet = copymsg(ed->packet); + edv->info.telephone_event = ed->info.telephone_event; +#endif + return nev; +} + +OrtpEventType ortp_event_get_type(const OrtpEvent *ev){ + return ((OrtpEventType*)ev->b_rptr)[0]; +} + +OrtpEventData * ortp_event_get_data(OrtpEvent *ev){ + return (OrtpEventData*)(ev->b_rptr+sizeof(OrtpEventType)); +} + +void ortp_event_destroy(OrtpEvent *ev){ + OrtpEventData *d=ortp_event_get_data(ev); + if (ev->b_datap->db_ref==1){ + if (d->packet) freemsg(d->packet); + if (d->ep) rtp_endpoint_destroy(d->ep); + } + freemsg(ev); +} + +OrtpEvQueue * ortp_ev_queue_new(){ + OrtpEvQueue *q=ortp_new(OrtpEvQueue,1); + qinit(&q->q); + ortp_mutex_init(&q->mutex,NULL); + return q; +} + +void ortp_ev_queue_flush(OrtpEvQueue * qp){ + OrtpEvent *ev; + while((ev=ortp_ev_queue_get(qp))!=NULL){ + ortp_event_destroy(ev); + } +} + +OrtpEvent * ortp_ev_queue_get(OrtpEvQueue *q){ + OrtpEvent *ev; + ortp_mutex_lock(&q->mutex); + ev=getq(&q->q); + ortp_mutex_unlock(&q->mutex); + return ev; +} + +void ortp_ev_queue_destroy(OrtpEvQueue * qp){ + ortp_ev_queue_flush(qp); + ortp_mutex_destroy(&qp->mutex); + ortp_free(qp); +} + +void ortp_ev_queue_put(OrtpEvQueue *q, OrtpEvent *ev){ + ortp_mutex_lock(&q->mutex); + putq(&q->q,ev); + ortp_mutex_unlock(&q->mutex); +} + diff --git a/linphone/oRTP/src/jitterctl.c b/linphone/oRTP/src/jitterctl.c new file mode 100644 index 000000000..0ee9dd4ca --- /dev/null +++ b/linphone/oRTP/src/jitterctl.c @@ -0,0 +1,182 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/*************************************************************************** + * jitterctl.c + * + * Mon Nov 8 11:53:21 2004 + * Copyright 2004 Simon MORLAT + * Email simon.morlat@linphone.org + ****************************************************************************/ + +#include "ortp/rtpsession.h" +#include "ortp/payloadtype.h" +#include "ortp/ortp.h" +#include "utils.h" +#include "rtpsession_priv.h" +#include + +#define JC_BETA 0.01 +#define JC_GAMMA (JC_BETA) + +#include "jitterctl.h" + +void jitter_control_init(JitterControl *ctl, int base_jiitt_time, PayloadType *payload){ + ctl->count=0; + ctl->slide=0; + ctl->prev_slide=0; + ctl->jitter=0; + ctl->inter_jitter=0; + ctl->slide=0; + if (base_jiitt_time!=-1) ctl->jitt_comp = base_jiitt_time; + /* convert in timestamp unit: */ + if (payload!=NULL){ + jitter_control_set_payload(ctl,payload); + } + ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts; + ctl->corrective_slide=0; +} + +void jitter_control_enable_adaptive(JitterControl *ctl, bool_t val){ + ctl->adaptive=val; +} + +void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt){ + ctl->jitt_comp_ts = + (int) (((double) ctl->jitt_comp / 1000.0) * (pt->clock_rate)); + ctl->corrective_step=(160 * 8000 )/pt->clock_rate; /* This formula got to me after some beers */ + ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts; +} + + +void jitter_control_dump_stats(JitterControl *ctl){ + ortp_message("JitterControl:\n\tslide=%g,jitter=%g,count=%i", + (double)ctl->slide,ctl->jitter, ctl->count); +} + +/*the goal of this method is to compute "corrective_slide": a timestamp unit'd value to be added + to recv timestamp to make them reflect the instant they are delivered by the jitter buffer. */ +void jitter_control_update_corrective_slide(JitterControl *ctl){ + int tmp; + tmp=(int)(ctl->slide)-ctl->prev_slide; + if (tmp>ctl->corrective_step) { + ctl->corrective_slide+=ctl->corrective_step; + ctl->prev_slide=ctl->slide+ctl->corrective_step; + } + else if (tmp<-ctl->corrective_step) { + ctl->corrective_slide-=ctl->corrective_step; + ctl->prev_slide=ctl->slide-ctl->corrective_step; + } +} + +/* + The algorithm computes two values: + slide: an average of difference between the expected and the socket-received timestamp + jitter: an average of the absolute value of the difference between socket-received timestamp and slide. + slide is used to make clock-slide detection and correction. + jitter is added to the initial jitt_comp_time value. It compensates bursty packets arrival (packets + not arriving at regular interval ). +*/ +void jitter_control_new_packet(JitterControl *ctl, uint32_t packet_ts, uint32_t cur_str_ts){ + int64_t diff=(int64_t)packet_ts - (int64_t)cur_str_ts; + double gap,slide; + int d; + //printf("diff=%g\n",diff); + if (ctl->count==0){ + slide=ctl->slide=ctl->prev_slide=diff; + ctl->olddiff=diff; + ctl->jitter=0; + }else{ + slide=((double)ctl->slide*(1-JC_BETA)) + ((double)diff*JC_BETA); + } + gap=(double)diff - slide; + gap=gap<0 ? -gap : 0; /*compute only for late packets*/ + ctl->jitter=(float) ((ctl->jitter*(1-JC_GAMMA)) + (gap*JC_GAMMA)); + d=diff-ctl->olddiff; + ctl->inter_jitter=(float) (ctl->inter_jitter+ (( (float)abs(d) - ctl->inter_jitter)*(1/16.0))); + ctl->olddiff=diff; + ctl->count++; + if (ctl->adaptive){ + + if (ctl->count%50==0) { + ctl->adapt_jitt_comp_ts=(int) MAX(ctl->jitt_comp_ts,2*ctl->jitter); + /*jitter_control_dump_stats(ctl);*/ + } + + ctl->slide=slide; + }else { + /*ctl->slide and jitter size are not updated*/ + } + return ; +} + + + + + +/** + *rtp_session_set_jitter_compensation: + *@session: a RtpSession + *@milisec: the time interval in milisec to be jitter compensed. + * + * Sets the time interval for which packet are buffered instead of being delivered to the + * application. + **/ +void +rtp_session_set_jitter_compensation (RtpSession * session, int milisec) +{ + PayloadType *payload=NULL; + if (session->rcv.pt!=-1) { + payload = rtp_profile_get_payload (session->rcv.profile,session->rcv.pt); + }/*else not set yet */ + jitter_control_init(&session->rtp.jittctl,milisec,payload); +} + +void rtp_session_enable_adaptive_jitter_compensation(RtpSession *session, bool_t val){ + jitter_control_enable_adaptive(&session->rtp.jittctl,val); +} + +bool_t rtp_session_adaptive_jitter_compensation_enabled(RtpSession *session){ + return session->rtp.jittctl.adaptive; +} + +void rtp_session_enable_jitter_buffer(RtpSession *session, bool_t enabled){ + session->rtp.jittctl.enabled=enabled; + session->flags|=RTP_SESSION_RECV_SYNC; +} + +bool_t rtp_session_jitter_buffer_enabled(const RtpSession *session){ + return session->rtp.jittctl.enabled; +} + +void rtp_session_set_jitter_buffer_params(RtpSession *session, const JBParameters *par){ + /* FIXME min_size and max_size to be implemented */ + rtp_session_set_jitter_compensation(session,par->nom_size); + jitter_control_enable_adaptive(&session->rtp.jittctl,par->adaptive); + session->rtp.max_rq_size=par->max_packets; +} + +void rtp_session_get_jitter_buffer_params(RtpSession *session, JBParameters *par){ + int nom_size=session->rtp.jittctl.jitt_comp; + par->min_size=nom_size; + par->nom_size=nom_size; + par->max_size=-1; + par->adaptive=session->rtp.jittctl.adaptive; + par->max_packets=session->rtp.max_rq_size; +} + diff --git a/linphone/oRTP/src/jitterctl.h b/linphone/oRTP/src/jitterctl.h new file mode 100644 index 000000000..713756118 --- /dev/null +++ b/linphone/oRTP/src/jitterctl.h @@ -0,0 +1,41 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/*************************************************************************** + * jitterctl.c + * + * Mon Nov 8 11:53:21 2004 + * Copyright 2004 Simon MORLAT + * Email simon.morlat@linphone.org + ****************************************************************************/ + +#ifndef JITTERCTL_H +#define JITTERCTL_H + + +void jitter_control_init(JitterControl *ctl, int base_jiitt_time, PayloadType *pt); +void jitter_control_enable_adaptive(JitterControl *ctl, bool_t val); +void jitter_control_new_packet(JitterControl *ctl, uint32_t packet_ts, uint32_t cur_str_ts); +#define jitter_control_adaptive_enabled(ctl) ((ctl)->adaptive) +void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt); +void jitter_control_update_corrective_slide(JitterControl *ctl); +static inline uint32_t jitter_control_get_compensated_timestamp(JitterControl *obj , uint32_t user_ts){ + return user_ts+obj->slide-obj->adapt_jitt_comp_ts; +} + +#endif diff --git a/linphone/oRTP/src/master b/linphone/oRTP/src/master new file mode 100644 index 000000000..ded8bca41 --- /dev/null +++ b/linphone/oRTP/src/master @@ -0,0 +1,33 @@ +*############################################################ +*# +*# $Header: /sources/linphone/linphone/oRTP/src/master,v 1.1 2002/02/25 08:41:53 smorlat Exp $ +*# +*# $Source: /sources/linphone/linphone/oRTP/src/master,v $ +*# $Revision: 1.1 $ +*# $Locker: $ +*# +*############################################################ +$VERSION +1 +$$$ + +$DRIVER_INSTALL +oRTP -1 -1 +$$$ + +$LOADABLE +$$$ + +$INTERFACE +base +$$$ + +$DRIVER_DEPENDENCY +$$$ + +$TYPE +oRTP wsio_class pseudo pmi -1 -1 +$$$ + +$TUNABLE +$$$ diff --git a/linphone/oRTP/src/ortp-config-win32.h b/linphone/oRTP/src/ortp-config-win32.h new file mode 100644 index 000000000..6227ef64b --- /dev/null +++ b/linphone/oRTP/src/ortp-config-win32.h @@ -0,0 +1,31 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* ortp-config-win32.h. Generated manually... */ +#define ORTP_VERSION "0.8.2" +#define ORTP_MAJOR_VERSION 0 +#define ORTP_MINOR_VERSION 8 +#define ORTP_MICRO_VERSION 2 +#define ORTP_EXTRA_VERSION + +/* define the debug mode */ +#define RTP_DEBUG 1 + +#define HAVE_SRTP 1 diff --git a/linphone/oRTP/src/ortp.c b/linphone/oRTP/src/ortp.c new file mode 100644 index 000000000..2c11abf56 --- /dev/null +++ b/linphone/oRTP/src/ortp.c @@ -0,0 +1,372 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif +#include "ortp/ortp.h" +#include "scheduler.h" + +rtp_stats_t ortp_global_stats; + +#ifdef ENABLE_MEMCHECK +int ortp_allocations=0; +#endif + + +RtpScheduler *__ortp_scheduler; + + + +extern void av_profile_init(RtpProfile *profile); + +static void init_random_number_generator(){ + struct timeval t; + gettimeofday(&t,NULL); + srandom(t.tv_usec+t.tv_sec); +} + + +#ifdef WIN32 +static bool_t win32_init_sockets(void){ + WORD wVersionRequested; + WSADATA wsaData; + int i; + + wVersionRequested = MAKEWORD(1,1); + if( (i = WSAStartup(wVersionRequested, &wsaData))!=0) + { + ortp_error("Unable to initialize windows socket api, reason: %d",i); + return FALSE; + } + return TRUE; +} +#endif + +/** + * Initialize the oRTP library. You should call this function first before using + * oRTP API. +**/ +void ortp_init() +{ + static bool_t initialized=FALSE; + if (initialized) return; + initialized=TRUE; + +#ifdef WIN32 + win32_init_sockets(); +#endif + + av_profile_init(&av_profile); + ortp_global_stats_reset(); + init_random_number_generator(); + ortp_message("oRTP-" ORTP_VERSION " initialized."); +} + + +/** + * Initialize the oRTP scheduler. You only have to do that if you intend to use the + * scheduled mode of the #RtpSession in your application. + * +**/ +void ortp_scheduler_init() +{ + static bool_t initialized=FALSE; + if (initialized) return; + initialized=TRUE; +#ifdef __hpux + /* on hpux, we must block sigalrm on the main process, because signal delivery + is ?random?, well, sometimes the SIGALRM goes to both the main thread and the + scheduler thread */ + sigset_t set; + sigemptyset(&set); + sigaddset(&set,SIGALRM); + sigprocmask(SIG_BLOCK,&set,NULL); +#endif /* __hpux */ + + __ortp_scheduler=rtp_scheduler_new(); + rtp_scheduler_start(__ortp_scheduler); + //sleep(1); +} + + +/** + * Gracefully uninitialize the library, including shutdowning the scheduler if it was started. + * +**/ +void ortp_exit() +{ + if (__ortp_scheduler!=NULL) + { + rtp_scheduler_destroy(__ortp_scheduler); + __ortp_scheduler=NULL; + } +} + +RtpScheduler * ortp_get_scheduler() +{ + if (__ortp_scheduler==NULL) ortp_error("Cannot use the scheduled mode: the scheduler is not " + "started. Call ortp_scheduler_init() at the begginning of the application."); + return __ortp_scheduler; +} + + +static FILE *__log_file=0; + +/** + *@param file a FILE pointer where to output the ortp logs. + * +**/ +void ortp_set_log_file(FILE *file) +{ + __log_file=file; +} + +static void __ortp_logv_out(OrtpLogLevel lev, const char *fmt, va_list args); + +OrtpLogFunc ortp_logv_out=__ortp_logv_out; + +/** + *@param func: your logging function, compatible with the OrtpLogFunc prototype. + * +**/ +void ortp_set_log_handler(OrtpLogFunc func){ + ortp_logv_out=func; +} + + +unsigned int __ortp_log_mask=ORTP_WARNING|ORTP_ERROR|ORTP_FATAL; + +/** + * @ param levelmask a mask of ORTP_DEBUG, ORTP_MESSAGE, ORTP_WARNING, ORTP_ERROR + * ORTP_FATAL . +**/ +void ortp_set_log_level_mask(int levelmask){ + __ortp_log_mask=levelmask; +} + +static char * _strdup_vprintf(const char *fmt, va_list ap) +{ + /* Guess we need no more than 100 bytes. */ + int n, size = 200; + char *p,*np; +#ifdef __linux + va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/ +#endif + if ((p = (char *) ortp_malloc (size)) == NULL) + return NULL; + while (1) + { + /* Try to print in the allocated space. */ +#ifdef __linux + va_copy(cap,ap); + n = vsnprintf (p, size, fmt, cap); + va_end(cap); +#else + /*this works on 32 bits, luckily*/ + n = vsnprintf (p, size, fmt, ap); +#endif + /* If that worked, return the string. */ + if (n > -1 && n < size) + return p; + //printf("Reallocing space.\n"); + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if ((np = (char *) ortp_realloc (p, size)) == NULL) + { + free(p); + return NULL; + } + else + { + p = np; + } + } +} + +char *ortp_strdup_printf(const char *fmt,...){ + char *ret; + va_list args; + va_start (args, fmt); + ret=_strdup_vprintf(fmt, args); + va_end (args); + return ret; +} + +#if defined(WIN32) || defined(_WIN32_WCE) +#define ENDLINE "\r\n" +#else +#define ENDLINE "\n" +#endif + +#if defined(WIN32) || defined(_WIN32_WCE) +void ortp_logv(int level, const char *fmt, va_list args) +{ + if (ortp_logv_out!=NULL && ortp_log_level_enabled(level)) + ortp_logv_out(level,fmt,args); +#if !defined(_WIN32_WCE) + if ((level)==ORTP_FATAL) abort(); +#endif +} +#endif + +static void __ortp_logv_out(OrtpLogLevel lev, const char *fmt, va_list args){ + const char *lname="undef"; + char *msg; + if (__log_file==NULL) __log_file=stderr; + switch(lev){ + case ORTP_DEBUG: + lname="debug"; + break; + case ORTP_MESSAGE: + lname="message"; + break; + case ORTP_WARNING: + lname="warning"; + break; + case ORTP_ERROR: + lname="error"; + break; + case ORTP_FATAL: + lname="fatal"; + break; + default: + ortp_fatal("Bad level !"); + } + msg=_strdup_vprintf(fmt,args); + fprintf(__log_file,"ortp-%s-%s" ENDLINE,lname,msg); + ortp_free(msg); +} + +/** + * Display global statistics (cumulative for all RtpSession) +**/ +void ortp_global_stats_display() +{ + rtp_stats_display(&ortp_global_stats,"Global statistics"); +#ifdef ENABLE_MEMCHECK + printf("Unfreed allocations: %i\n",ortp_allocations); +#endif +} + +/** + * Print RTP statistics. +**/ +void rtp_stats_display(const rtp_stats_t *stats, const char *header) +{ +#ifndef WIN32 + ortp_log(ORTP_MESSAGE, + "oRTP-stats:\n %s :", + header); + ortp_log(ORTP_MESSAGE, + " number of rtp packet sent=%lld", + (long long)stats->packet_sent); + ortp_log(ORTP_MESSAGE, + " number of rtp bytes sent=%lld bytes", + (long long)stats->sent); + ortp_log(ORTP_MESSAGE, + " number of rtp packet received=%lld", + (long long)stats->packet_recv); + ortp_log(ORTP_MESSAGE, + " number of rtp bytes received=%lld bytes", + (long long)stats->hw_recv); + ortp_log(ORTP_MESSAGE, + " number of incoming rtp bytes successfully delivered to the application=%lld ", + (long long)stats->recv); + ortp_log(ORTP_MESSAGE, + " number of times the application queried a packet that didn't exist=%lld ", + (long long)stats->unavaillable); + ortp_log(ORTP_MESSAGE, + " number of rtp packet lost=%lld", + (long long) stats->cum_packet_loss); + ortp_log(ORTP_MESSAGE, + " number of rtp packets received too late=%lld", + (long long)stats->outoftime); + ortp_log(ORTP_MESSAGE, + " number of bad formatted rtp packets=%lld", + (long long)stats->bad); + ortp_log(ORTP_MESSAGE, + " number of packet discarded because of queue overflow=%lld", + (long long)stats->discarded); +#else + ortp_log(ORTP_MESSAGE, + "oRTP-stats:\n %s :", + header); + ortp_log(ORTP_MESSAGE, + " number of rtp packet sent=%I64d", + (uint64_t)stats->packet_sent); + ortp_log(ORTP_MESSAGE, + " number of rtp bytes sent=%I64d bytes", + (uint64_t)stats->sent); + ortp_log(ORTP_MESSAGE, + " number of rtp packet received=%I64d", + (uint64_t)stats->packet_recv); + ortp_log(ORTP_MESSAGE, + " number of rtp bytes received=%I64d bytes", + (uint64_t)stats->hw_recv); + ortp_log(ORTP_MESSAGE, + " number of incoming rtp bytes successfully delivered to the application=%I64d ", + (uint64_t)stats->recv); + ortp_log(ORTP_MESSAGE, + " number of times the application queried a packet that didn't exist=%I64d ", + (uint64_t)stats->unavaillable); + ortp_log(ORTP_MESSAGE, + " number of rtp packet lost=%I64d", + (uint64_t) stats->cum_packet_loss); + ortp_log(ORTP_MESSAGE, + " number of rtp packets received too late=%I64d", + (uint64_t)stats->outoftime); + ortp_log(ORTP_MESSAGE, + " number of bad formatted rtp packets=%I64d", + (uint64_t)stats->bad); + ortp_log(ORTP_MESSAGE, + " number of packet discarded because of queue overflow=%I64d", + (uint64_t)stats->discarded); +#endif +} + +void ortp_global_stats_reset(){ + memset(&ortp_global_stats,0,sizeof(rtp_stats_t)); +} + +rtp_stats_t *ortp_get_global_stats(){ + return &ortp_global_stats; +} + +void rtp_stats_reset(rtp_stats_t *stats){ + memset((void*)stats,0,sizeof(rtp_stats_t)); +} + + +/** + * This function give the opportunity to programs to check if the libortp they link to + * has the minimum version number they need. + * + * Returns: true if ortp has a version number greater or equal than the required one. +**/ +bool_t ortp_min_version_required(int major, int minor, int micro){ + return ((major*1000000) + (minor*1000) + micro) <= + ((ORTP_MAJOR_VERSION*1000000) + (ORTP_MINOR_VERSION*1000) + ORTP_MICRO_VERSION); +} diff --git a/linphone/oRTP/src/payloadtype.c b/linphone/oRTP/src/payloadtype.c new file mode 100644 index 000000000..53335736f --- /dev/null +++ b/linphone/oRTP/src/payloadtype.c @@ -0,0 +1,362 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/ortp.h" +#include "ortp/payloadtype.h" +#include "utils.h" + +char *payload_type_get_rtpmap(PayloadType *pt) +{ + int len=(int)strlen(pt->mime_type)+15; + char *rtpmap=(char *) ortp_malloc(len); + if (pt->channels>0) + snprintf(rtpmap,len,"%s/%i/%i",pt->mime_type,pt->clock_rate,pt->channels); + else + snprintf(rtpmap,len,"%s/%i",pt->mime_type,pt->clock_rate); + return rtpmap; +} + +PayloadType *payload_type_new() +{ + PayloadType *newpayload=(PayloadType *)ortp_new0(PayloadType,1); + newpayload->flags|=PAYLOAD_TYPE_ALLOCATED; + return newpayload; +} + + +PayloadType *payload_type_clone(PayloadType *payload) +{ + PayloadType *newpayload=(PayloadType *)ortp_new0(PayloadType,1); + memcpy(newpayload,payload,sizeof(PayloadType)); + newpayload->mime_type=ortp_strdup(payload->mime_type); + if (payload->recv_fmtp!=NULL) { + newpayload->recv_fmtp=ortp_strdup(payload->recv_fmtp); + } + if (payload->send_fmtp!=NULL){ + newpayload->send_fmtp=ortp_strdup(payload->send_fmtp); + } + newpayload->flags|=PAYLOAD_TYPE_ALLOCATED; + return newpayload; +} + +static bool_t canWrite(PayloadType *pt){ + if (!(pt->flags & PAYLOAD_TYPE_ALLOCATED)) { + ortp_error("Cannot change parameters of statically defined payload types: make your" + " own copy using payload_type_clone() first."); + return FALSE; + } + return TRUE; +} + +/** + * Sets a recv parameters (fmtp) for the PayloadType. + * This method is provided for applications using RTP with SDP, but + * actually the ftmp information is not used for RTP processing. +**/ +void payload_type_set_recv_fmtp(PayloadType *pt, const char *fmtp){ + if (canWrite(pt)){ + if (pt->recv_fmtp!=NULL) ortp_free(pt->recv_fmtp); + if (fmtp!=NULL) pt->recv_fmtp=ortp_strdup(fmtp); + else pt->recv_fmtp=NULL; + } +} + +/** + * Sets a send parameters (fmtp) for the PayloadType. + * This method is provided for applications using RTP with SDP, but + * actually the ftmp information is not used for RTP processing. +**/ +void payload_type_set_send_fmtp(PayloadType *pt, const char *fmtp){ + if (canWrite(pt)){ + if (pt->send_fmtp!=NULL) ortp_free(pt->send_fmtp); + if (fmtp!=NULL) pt->send_fmtp=ortp_strdup(fmtp); + else pt->send_fmtp=NULL; + } +} + + + +void payload_type_append_recv_fmtp(PayloadType *pt, const char *fmtp){ + if (canWrite(pt)){ + if (pt->recv_fmtp==NULL) + pt->recv_fmtp=ortp_strdup(fmtp); + else{ + char *tmp=ortp_strdup_printf("%s;%s",pt->recv_fmtp,fmtp); + ortp_free(pt->recv_fmtp); + pt->recv_fmtp=tmp; + } + } +} + +void payload_type_append_send_fmtp(PayloadType *pt, const char *fmtp){ + if (canWrite(pt)){ + if (pt->send_fmtp==NULL) + pt->send_fmtp=ortp_strdup(fmtp); + else{ + char *tmp=ortp_strdup_printf("%s;%s",pt->send_fmtp,fmtp); + ortp_free(pt->send_fmtp); + pt->send_fmtp=tmp; + } + } +} + + +/** + * Frees a PayloadType. +**/ +void payload_type_destroy(PayloadType *pt) +{ + if (pt->mime_type) ortp_free(pt->mime_type); + if (pt->recv_fmtp) ortp_free(pt->recv_fmtp); + if (pt->send_fmtp) ortp_free(pt->send_fmtp); + ortp_free(pt); +} + +/** + * Parses a fmtp string such as "profile=0;level=10", finds the value matching + * parameter param_name, and writes it into result. + * Despite fmtp strings are not used anywhere within oRTP, this function can + * be useful for people using RTP streams described from SDP. + * @param fmtp the fmtp line (format parameters) + * @param param_name the parameter to search for + * @param result the value given for the parameter (if found) + * @param result_len the size allocated to hold the result string + * @return TRUE if the parameter was found, else FALSE. +**/ +bool_t fmtp_get_value(const char *fmtp, const char *param_name, char *result, size_t result_len){ + const char *pos=strstr(fmtp,param_name); + if (pos){ + const char *equal=strchr(pos,'='); + if (equal){ + int copied; + const char *end=strchr(equal+1,';'); + if (end==NULL) end=fmtp+strlen(fmtp); /*assuming this is the last param */ + copied=MIN(result_len-1,end-(equal+1)); + strncpy(result,equal+1,copied); + result[copied]='\0'; + return TRUE; + } + } + return FALSE; +} + + +int rtp_profile_get_payload_number_from_mime(RtpProfile *profile,const char *mime) +{ + PayloadType *pt; + int i; + for (i=0;imime_type,mime)==0){ + return i; + } + } + } + return -1; +} + +int rtp_profile_find_payload_number(RtpProfile*profile,const char *mime,int rate,int channels) +{ + int i; + PayloadType *pt; + for (i=0;imime_type,mime)==0 && + pt->clock_rate==rate && + (pt->channels==channels || channels<=0 || pt->channels<=0)) { + /*we don't look at channels if it is undefined + ie a negative or zero value*/ + + return i; + } + } + } + return -1; +} + +int rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile,const char *rtpmap) +{ + int clock_rate, channels, ret; + char* subtype = ortp_strdup( rtpmap ); + char* rate_str = NULL; + char* chan_str = NULL; + + + /* find the slash after the subtype */ + rate_str = strchr(subtype, '/'); + if (rate_str && strlen(rate_str)>1) { + *rate_str = 0; + rate_str++; + + /* Look for another slash */ + chan_str = strchr(rate_str, '/'); + if (chan_str && strlen(chan_str)>1) { + *chan_str = 0; + chan_str++; + } else { + chan_str = NULL; + } + } else { + rate_str = NULL; + } + + // Use default clock rate if none given + if (rate_str) clock_rate = atoi(rate_str); + else clock_rate = 8000; + + // Use default number of channels if none given + if (chan_str) channels = atoi(chan_str); + else channels = -1; + + //printf("Searching for payload %s at freq %i with %i channels\n",subtype,clock_rate,ch1annels); + ret=rtp_profile_find_payload_number(profile,subtype,clock_rate,channels); + ortp_free(subtype); + return ret; +} + +PayloadType * rtp_profile_find_payload(RtpProfile *prof,const char *mime,int rate,int channels) +{ + int i; + i=rtp_profile_find_payload_number(prof,mime,rate,channels); + if (i>=0) return rtp_profile_get_payload(prof,i); + return NULL; +} + + +PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime) +{ + int pt; + pt=rtp_profile_get_payload_number_from_mime(profile,mime); + if (pt==-1) return NULL; + else return rtp_profile_get_payload(profile,pt); +} + + +PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap) +{ + int pt = rtp_profile_get_payload_number_from_rtpmap(profile,rtpmap); + if (pt==-1) return NULL; + else return rtp_profile_get_payload(profile,pt); +} + +int rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos){ + prof->payload[newpos]=prof->payload[oldpos]; + prof->payload[oldpos]=NULL; + return 0; +} + +RtpProfile * rtp_profile_new(const char *name) +{ + RtpProfile *prof=(RtpProfile*)ortp_new0(RtpProfile,1); + rtp_profile_set_name(prof,name); + return prof; +} + +/** + * Assign payload type number index to payload type desribed in pt for the RTP profile profile. + * @param profile a RTP profile + * @param idx the payload type number + * @param pt the payload type description + * +**/ +void rtp_profile_set_payload(RtpProfile *prof, int idx, PayloadType *pt){ + if (idx<0 || idx>=RTP_PROFILE_MAX_PAYLOADS) { + ortp_error("Bad index %i",idx); + return; + } + prof->payload[idx]=pt; +} + +/** + * Initialize the profile to the empty profile (all payload type are unassigned). + *@param profile a RTP profile + * +**/ +void rtp_profile_clear_all(RtpProfile *obj){ + int i; + for (i=0;ipayload[i]=0; + } +} + + +/** + * Set a name to the rtp profile. (This is not required) + * @param profile a rtp profile object + * @param nm a string + * +**/ +void rtp_profile_set_name(RtpProfile *obj, const char *name){ + if (obj->name!=NULL) ortp_free(obj->name); + obj->name=ortp_strdup(name); +} + +/* ! payload are not cloned*/ +RtpProfile * rtp_profile_clone(RtpProfile *prof) +{ + int i; + PayloadType *pt; + RtpProfile *newprof=rtp_profile_new(prof->name); + for (i=0;iname); + for (i=0;iname) { + ortp_free(prof->name); + prof->name = NULL; + } + for (i=0;iflags & PAYLOAD_TYPE_ALLOCATED)) + payload_type_destroy(payload); + } + ortp_free(prof); +} diff --git a/linphone/oRTP/src/port.c b/linphone/oRTP/src/port.c new file mode 100644 index 000000000..4b42b1c69 --- /dev/null +++ b/linphone/oRTP/src/port.c @@ -0,0 +1,336 @@ + +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif +#include "ortp/port.h" +#include "ortp/ortp.h" +#include "utils.h" + +#if defined(_WIN32) && !defined(_WIN32_WCE) +#include +#endif + +static void *ortp_libc_malloc(size_t sz){ + return malloc(sz); +} + +static void *ortp_libc_realloc(void *ptr, size_t sz){ + return realloc(ptr,sz); +} + +static void ortp_libc_free(void*ptr){ + free(ptr); +} + +static bool_t allocator_used=FALSE; + +static OrtpMemoryFunctions ortp_allocator={ + ortp_libc_malloc, + ortp_libc_realloc, + ortp_libc_free +}; + +void ortp_set_memory_functions(OrtpMemoryFunctions *functions){ + if (allocator_used){ + ortp_fatal("ortp_set_memory_functions() must be called before " + "first use of ortp_malloc or ortp_realloc"); + return; + } + ortp_allocator=*functions; +} + +void* ortp_malloc(size_t sz){ + allocator_used=TRUE; + return ortp_allocator.malloc_fun(sz); +} + +void* ortp_realloc(void *ptr, size_t sz){ + allocator_used=TRUE; + return ortp_allocator.realloc_fun(ptr,sz); +} + +void ortp_free(void* ptr){ + ortp_allocator.free_fun(ptr); +} + +void * ortp_malloc0(size_t size){ + void *ptr=ortp_malloc(size); + memset(ptr,0,size); + return ptr; +} + +char * ortp_strdup(const char *tmp){ + size_t sz; + char *ret; + if (tmp==NULL) + return NULL; + sz=strlen(tmp)+1; + ret=(char*)ortp_malloc(sz); + strcpy(ret,tmp); + ret[sz-1]='\0'; + return ret; +} + +/* + * this method is an utility method that calls fnctl() on UNIX or + * ioctlsocket on Win32. + * int retrun the result of the system method + */ +int set_non_blocking_socket (ortp_socket_t sock) +{ + + +#if !defined(_WIN32) && !defined(_WIN32_WCE) + return fcntl (sock, F_SETFL, O_NONBLOCK); +#else + unsigned long nonBlock = 1; + return ioctlsocket(sock, FIONBIO , &nonBlock); +#endif +} + + +/* + * this method is an utility method that calls close() on UNIX or + * closesocket on Win32. + * int retrun the result of the system method + */ +int close_socket(ortp_socket_t sock){ +#if !defined(_WIN32) && !defined(_WIN32_WCE) + return close (sock); +#else + return closesocket(sock); +#endif +} + + + +#if !defined(_WIN32) && !defined(_WIN32_WCE) + /* Use UNIX inet_aton method */ +#else + int inet_aton (const char * cp, struct in_addr * addr) + { + unsigned long retval; + + retval = inet_addr (cp); + + if (retval == INADDR_NONE) + { + return -1; + } + else + { + addr->S_un.S_addr = retval; + return 1; + } + } +#endif + +char *ortp_strndup(const char *str,int n){ + int min=MIN((int)strlen(str),n)+1; + char *ret=(char*)ortp_malloc(min); + strncpy(ret,str,n); + ret[min-1]='\0'; + return ret; +} + +#if !defined(_WIN32) && !defined(_WIN32_WCE) +int __ortp_thread_join(ortp_thread_t thread, void **ptr){ + int err=pthread_join(thread,ptr); + if (err!=0) { + ortp_error("pthread_join error: %s",strerror(err)); + } + return err; +} + +int __ortp_thread_create(pthread_t *thread, pthread_attr_t *attr, void * (*routine)(void*), void *arg){ + pthread_attr_t my_attr; + pthread_attr_init(&my_attr); + if (attr) + my_attr = *attr; +#ifdef ORTP_DEFAULT_THREAD_STACK_SIZE + if (ORTP_DEFAULT_THREAD_STACK_SIZE!=0) + pthread_attr_setstacksize(&my_attr, ORTP_DEFAULT_THREAD_STACK_SIZE); +#endif + return pthread_create(thread, &my_attr, routine, arg); +} + +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) + +int WIN_mutex_init(ortp_mutex_t *mutex, void *attr) +{ + *mutex=CreateMutex(NULL, FALSE, NULL); + return 0; +} + +int WIN_mutex_lock(ortp_mutex_t * hMutex) +{ + WaitForSingleObject(*hMutex, INFINITE); /* == WAIT_TIMEOUT; */ + return 0; +} + +int WIN_mutex_unlock(ortp_mutex_t * hMutex) +{ + ReleaseMutex(*hMutex); + return 0; +} + +int WIN_mutex_destroy(ortp_mutex_t * hMutex) +{ + CloseHandle(*hMutex); + return 0; +} + +typedef struct thread_param{ + void * (*func)(void *); + void * arg; +}thread_param_t; + +static unsigned WINAPI thread_starter(void *data){ + thread_param_t *params=(thread_param_t*)data; + void *ret=params->func(params->arg); + ortp_free(data); + return (DWORD)ret; +} + +#if defined _WIN32_WCE +# define _beginthreadex CreateThread +# define _endthreadex ExitThread +#endif + +int WIN_thread_create(ortp_thread_t *th, void *attr, void * (*func)(void *), void *data) +{ + thread_param_t *params=ortp_new(thread_param_t,1); + params->func=func; + params->arg=data; + *th=(HANDLE)_beginthreadex( NULL, 0, thread_starter, params, 0, NULL); + return 0; +} + +int WIN_thread_join(ortp_thread_t thread_h, void **unused) +{ + if (thread_h!=NULL) + { + WaitForSingleObject(thread_h, INFINITE); + CloseHandle(thread_h); + } + return 0; +} + +int WIN_cond_init(ortp_cond_t *cond, void *attr) +{ + *cond=CreateEvent(NULL, FALSE, FALSE, NULL); + return 0; +} + +int WIN_cond_wait(ortp_cond_t* hCond, ortp_mutex_t * hMutex) +{ + //gulp: this is not very atomic ! bug here ? + WIN_mutex_unlock(hMutex); + WaitForSingleObject(*hCond, INFINITE); + WIN_mutex_lock(hMutex); + return 0; +} + +int WIN_cond_signal(ortp_cond_t * hCond) +{ + SetEvent(*hCond); + return 0; +} + +int WIN_cond_broadcast(ortp_cond_t * hCond) +{ + WIN_cond_signal(hCond); + return 0; +} + +int WIN_cond_destroy(ortp_cond_t * hCond) +{ + CloseHandle(*hCond); + return 0; +} + + +#if defined(_WIN32_WCE) +#include + +int +gettimeofday (struct timeval *tv, void *tz) +{ + DWORD timemillis = GetTickCount(); + tv->tv_sec = timemillis/1000; + tv->tv_usec = (timemillis - (tv->tv_sec*1000)) * 1000; + return 0; +} + +#else + +int gettimeofday (struct timeval *tv, void* tz) +{ + union + { + __int64 ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME fileTime; + } now; + + GetSystemTimeAsFileTime (&now.fileTime); + tv->tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); + tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL); + return (0); +} + +#endif + +const char *getWinSocketError(int error) +{ + static char buf[80]; + + switch (error) + { + case WSANOTINITIALISED: return "Windows sockets not initialized : call WSAStartup"; + case WSAEADDRINUSE: return "Local Address already in use"; + case WSAEADDRNOTAVAIL: return "The specified address is not a valid address for this machine"; + case WSAEINVAL: return "The socket is already bound to an address."; + case WSAENOBUFS: return "Not enough buffers available, too many connections."; + case WSAENOTSOCK: return "The descriptor is not a socket."; + case WSAECONNRESET: return "Connection reset by peer"; + + default : + sprintf(buf, "Error code : %d", error); + return buf; + break; + } + + return buf; +} + +#ifdef _WORKAROUND_MINGW32_BUGS +char * WSAAPI gai_strerror(int errnum){ + return (char*)getWinSocketError(errnum); +} +#endif + +#endif + diff --git a/linphone/oRTP/src/posixtimer.c b/linphone/oRTP/src/posixtimer.c new file mode 100644 index 000000000..6330da00b --- /dev/null +++ b/linphone/oRTP/src/posixtimer.c @@ -0,0 +1,177 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif + +#include "ortp/ortp.h" +#include "rtptimer.h" + +#if !defined(_WIN32) && !defined(_WIN32_WCE) + +#ifdef __linux__ +#include +#endif + +#include +#include +#include + + +static struct timeval orig,cur; +static uint32_t posix_timer_time=0; /*in milisecond */ + +void posix_timer_init() +{ + posix_timer.state=RTP_TIMER_RUNNING; + gettimeofday(&orig,NULL); + posix_timer_time=0; +} + + + + +void posix_timer_do() +{ + int diff,time; + struct timeval tv; + gettimeofday(&cur,NULL); + time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 ); + if ( (diff=time-posix_timer_time)>50){ + ortp_warning("Must catchup %i miliseconds.",diff); + } + while((diff = posix_timer_time-time) > 0) + { + tv.tv_sec = diff/1000; + tv.tv_usec = (diff%1000)*1000; +#if defined(_WIN32) || defined(_WIN32_WCE) + /* this kind of select is not supported on windows */ + Sleep(tv.tv_usec/1000 + tv.tv_sec * 1000); +#else + select(0,NULL,NULL,NULL,&tv); +#endif + gettimeofday(&cur,NULL); + time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 ); + } + posix_timer_time+=POSIXTIMER_INTERVAL/1000; + +} + +void posix_timer_uninit() +{ + posix_timer.state=RTP_TIMER_STOPPED; +} + +RtpTimer posix_timer={ 0, + posix_timer_init, + posix_timer_do, + posix_timer_uninit, + {0,POSIXTIMER_INTERVAL}}; + + +#else //WIN32 + + +#include +#include + + +MMRESULT timerId; +HANDLE TimeEvent; +int late_ticks; + + +static DWORD posix_timer_time; +static DWORD offset_time; + + +#define TIME_INTERVAL 50 +#define TIME_RESOLUTION 10 +#define TIME_TIMEOUT 100 + + + +void CALLBACK timerCb(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) +{ + // Check timerId + if (timerId == uID) + { + SetEvent(TimeEvent); + posix_timer_time += TIME_INTERVAL; + } +} + + +void win_timer_init(void) +{ + timerId = timeSetEvent(TIME_INTERVAL,10,timerCb,0,TIME_PERIODIC | TIME_CALLBACK_FUNCTION); + TimeEvent = CreateEvent(NULL,FALSE,FALSE,NULL); + + late_ticks = 0; + + offset_time = GetTickCount(); + posix_timer_time=0; +} + + +void win_timer_do(void) +{ + DWORD diff; + + // If timer have expired while we where out of this method + // Try to run after lost time. + if (late_ticks > 0) + { + late_ticks--; + posix_timer_time+=TIME_INTERVAL; + return; + } + + + diff = GetTickCount() - posix_timer_time - offset_time; + if( diff>TIME_INTERVAL && (diff<(1<<31))) + { + late_ticks = diff/TIME_INTERVAL; + ortp_warning("we must catchup %i ticks.",late_ticks); + return; + } + + WaitForSingleObject(TimeEvent,TIME_TIMEOUT); + return; +} + + +void win_timer_close(void) +{ + timeKillEvent(timerId); +} + +RtpTimer toto; + +RtpTimer posix_timer={ 0, + win_timer_init, + win_timer_do, + win_timer_close, + {0,TIME_INTERVAL * 1000}}; + + +#endif // _WIN32 diff --git a/linphone/oRTP/src/rtcp.c b/linphone/oRTP/src/rtcp.c new file mode 100644 index 000000000..2d14813d5 --- /dev/null +++ b/linphone/oRTP/src/rtcp.c @@ -0,0 +1,412 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/*************************************************************************** + * rtcp.c + * + * Wed Dec 1 11:45:30 2004 + * Copyright 2004 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ +#include "ortp/ortp.h" +#include "ortp/rtpsession.h" +#include "ortp/rtcp.h" +#include "utils.h" +#include "rtpsession_priv.h" + +#define rtcp_bye_set_ssrc(b,pos,ssrc) (b)->ssrc[pos]=htonl(ssrc) +#define rtcp_bye_get_ssrc(b,pos) ntohl((b)->ssrc[pos]) + + +void rtcp_common_header_init(rtcp_common_header_t *ch, RtpSession *s,int type, int rc, int bytes_len){ + rtcp_common_header_set_version(ch,2); + rtcp_common_header_set_padbit(ch,0); + rtcp_common_header_set_packet_type(ch,type); + rtcp_common_header_set_rc(ch,rc); /* as we don't yet support multi source receiving */ + rtcp_common_header_set_length(ch,(bytes_len/4)-1); +} + +static mblk_t *sdes_chunk_new(uint32_t ssrc){ + mblk_t *m=allocb(RTCP_SDES_CHUNK_DEFAULT_SIZE,0); + sdes_chunk_t *sc=(sdes_chunk_t*)m->b_rptr; + sc->csrc=htonl(ssrc); + m->b_wptr+=sizeof(sc->csrc); + return m; +} + + +static mblk_t * sdes_chunk_append_item(mblk_t *m, rtcp_sdes_type_t sdes_type, const char *content) +{ + if ( content ) + { + sdes_item_t si; + si.item_type=sdes_type; + si.len=(uint8_t) MIN(strlen(content),RTCP_SDES_MAX_STRING_SIZE); + m=appendb(m,(char*)&si,RTCP_SDES_ITEM_HEADER_SIZE,FALSE); + m=appendb(m,content,si.len,FALSE); + } + return m; +} + +static void sdes_chunk_set_ssrc(mblk_t *m, uint32_t ssrc){ + sdes_chunk_t *sc=(sdes_chunk_t*)m->b_rptr; + sc->csrc=htonl(ssrc); +} + +#define sdes_chunk_get_ssrc(m) ntohl(((sdes_chunk_t*)((m)->b_rptr))->csrc) + +static mblk_t * sdes_chunk_pad(mblk_t *m){ + return appendb(m,"",1,TRUE); +} + +/** + * Set session's SDES item for automatic sending of RTCP compound packets. + * If some items are not specified, use NULL. +**/ +void rtp_session_set_source_description(RtpSession *session, + const char *cname, const char *name, const char *email, const char *phone, + const char *loc, const char *tool, const char *note){ + mblk_t *chunk = sdes_chunk_new(session->snd.ssrc); + mblk_t *m=chunk; + const char *_cname=cname; + if (_cname==NULL) + { + _cname="Unknown"; + } + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_CNAME, _cname); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NAME, name); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_EMAIL, email); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_PHONE, phone); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_LOC, loc); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_TOOL, tool); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NOTE, note); + chunk=sdes_chunk_pad(chunk); + if (session->sd!=NULL) freemsg(session->sd); + session->sd=m; +} + +void +rtp_session_add_contributing_source(RtpSession *session, uint32_t csrc, + const char *cname, const char *name, const char *email, const char *phone, + const char *loc, const char *tool, const char *note) +{ + mblk_t *chunk = sdes_chunk_new(csrc); + mblk_t *m=chunk; + char *_cname=(char*)cname; + if (_cname==NULL) + { + _cname="toto"; + } + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_CNAME, cname); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NAME, name); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_EMAIL, email); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_PHONE, phone); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_LOC, loc); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_TOOL, tool); + chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NOTE, note); + chunk=sdes_chunk_pad(chunk); + putq(&session->contributing_sources,m); +} + + + +mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session) +{ + mblk_t *mp=allocb(sizeof(rtcp_common_header_t),0); + rtcp_common_header_t *rtcp; + mblk_t *tmp,*m=mp; + queue_t *q; + int rc=0; + rtcp = (rtcp_common_header_t*)mp->b_wptr; + mp->b_wptr+=sizeof(rtcp_common_header_t); + + /* concatenate all sdes chunks */ + sdes_chunk_set_ssrc(session->sd,session->snd.ssrc); + m=concatb(m,dupmsg(session->sd)); + rc++; + + q=&session->contributing_sources; + for (tmp=qbegin(q); !qend(q,tmp); tmp=qnext(q,mp)){ + m=concatb(m,dupmsg(tmp)); + rc++; + } + rtcp_common_header_init(rtcp,session,RTCP_SDES,rc,msgdsize(mp)); + return mp; +} + + +mblk_t *rtcp_create_simple_bye_packet(uint32_t ssrc, const char *reason) +{ + int packet_size; + int strsize = 0; + int strpadding = 0; + mblk_t *mp; + rtcp_bye_t *rtcp; + + packet_size = RTCP_BYE_HEADER_SIZE; + if (reason!=NULL) { + strsize=(int)MIN(strlen(reason),RTCP_BYE_REASON_MAX_STRING_SIZE); + if (strsize > 0) { + strpadding = 3 - (strsize % 4); + packet_size += 1 + strsize + strpadding; + } + } + mp = allocb(packet_size, 0); + + rtcp = (rtcp_bye_t*)mp->b_rptr; + rtcp_common_header_init(&rtcp->ch,NULL,RTCP_BYE,1,packet_size); + rtcp->ssrc[0] = htonl(ssrc); + mp->b_wptr += RTCP_BYE_HEADER_SIZE; + /* append the reason if any*/ + if (reason!=NULL) { + const char pad[] = {0, 0, 0}; + unsigned char strsize_octet = (unsigned char)strsize; + + appendb(mp, (const char*)&strsize_octet, 1, FALSE); + appendb(mp, reason,strsize, FALSE); + appendb(mp, pad,strpadding, FALSE); + } + return mp; +} + +void rtp_session_remove_contributing_sources(RtpSession *session, uint32_t ssrc) +{ + queue_t *q=&session->contributing_sources; + mblk_t *tmp; + for (tmp=qbegin(q); !qend(q,tmp); tmp=qnext(q,tmp)){ + uint32_t csrc=sdes_chunk_get_ssrc(tmp); + if (csrc==ssrc) { + remq(q,tmp); + break; + } + } + tmp=rtcp_create_simple_bye_packet(ssrc, NULL); + rtp_session_rtcp_send(session,tmp); +} + +static void sender_info_init(sender_info_t *info, RtpSession *session){ + struct timeval tv; + uint32_t tmp; + gettimeofday(&tv,NULL); + info->ntp_timestamp_msw=htonl(tv.tv_sec + 0x83AA7E80); /* 0x83AA7E80 is the number of seconds from 1900 to 1970 */ +#if defined(_WIN32_WCE) + tmp=(uint32_t)((double)tv.tv_usec*(double)(((uint64_t)1)<<32)*1.0e-6); +#else + tmp=(uint32_t)((double)tv.tv_usec*(double)(1LL<<32)*1.0e-6); +#endif + info->ntp_timestamp_lsw=htonl(tmp); + info->rtp_timestamp=htonl(session->rtp.snd_last_ts); + info->senders_packet_count=(uint32_t) htonl((u_long) session->rtp.stats.packet_sent); + info->senders_octet_count=(uint32_t) htonl((u_long) session->rtp.sent_payload_bytes); + session->rtp.last_rtcp_packet_count=session->rtp.stats.packet_sent; +} + + + +static void report_block_init(report_block_t *b, RtpSession *session){ + int packet_loss=0; + uint8_t loss_fraction=0; + RtpStream *stream=&session->rtp; + uint32_t delay_snc_last_sr=0; + uint32_t fl_cnpl; + + /* compute the statistics */ + /*printf("hwrcv_extseq.one=%u, hwrcv_seq_at_last_SR=%u hwrcv_since_last_SR=%u\n", + stream->hwrcv_extseq.one, + stream->hwrcv_seq_at_last_SR, + stream->hwrcv_since_last_SR + );*/ + if (stream->hwrcv_seq_at_last_SR!=0){ + packet_loss=(stream->hwrcv_extseq - stream->hwrcv_seq_at_last_SR) - stream->hwrcv_since_last_SR; + if (packet_loss<0) + packet_loss=0; + stream->stats.cum_packet_loss+=packet_loss; + loss_fraction=(int)(256.0*(float)packet_loss/(float)stream->hwrcv_since_last_SR); + } + /* reset them */ + stream->hwrcv_since_last_SR=0; + stream->hwrcv_seq_at_last_SR=stream->hwrcv_extseq; + + if (stream->last_rcv_SR_time.tv_sec!=0){ + struct timeval now; + float delay; + gettimeofday(&now,NULL); + delay=(float) ((now.tv_sec-stream->last_rcv_SR_time.tv_sec)*1e6 ) + (now.tv_usec-stream->last_rcv_SR_time.tv_usec); + delay=(float) (delay*65536*1e-6); + delay_snc_last_sr=(uint32_t) delay; + } + + b->ssrc=htonl(session->rcv.ssrc); + fl_cnpl=((loss_fraction&0xFF)<<24) | (stream->stats.cum_packet_loss & 0xFFFFFF); + b->fl_cnpl=htonl(fl_cnpl); + b->interarrival_jitter=htonl((uint32_t) stream->jittctl.inter_jitter); + b->ext_high_seq_num_rec=htonl(stream->hwrcv_extseq); + b->lsr=htonl(stream->last_rcv_SR_ts); + b->delay_snc_last_sr=htonl(delay_snc_last_sr); +} + + + +static int rtcp_sr_init(RtpSession *session, uint8_t *buf, int size){ + rtcp_sr_t *sr=(rtcp_sr_t*)buf; + int rr=(session->rtp.stats.packet_recv>0); + int sr_size=sizeof(rtcp_sr_t)-sizeof(report_block_t)+(rr*sizeof(report_block_t)); + if (sizech,session,RTCP_SR,rr,sr_size); + sr->ssrc=htonl(session->snd.ssrc); + sender_info_init(&sr->si,session); + /*only include a report block if packets were received*/ + if (rr) + report_block_init(&sr->rb[0],session); + return sr_size; +} + +static int rtcp_rr_init(RtpSession *session, uint8_t *buf, int size){ + rtcp_rr_t *rr=(rtcp_rr_t*)buf; + if (sizech,session,RTCP_RR,1,sizeof(rtcp_rr_t)); + rr->ssrc=htonl(session->snd.ssrc); + report_block_init(&rr->rb[0],session); + return sizeof(rtcp_rr_t); +} + +static int rtcp_app_init(RtpSession *session, uint8_t *buf, uint8_t subtype, const char *name, int size){ + rtcp_app_t *app=(rtcp_app_t*)buf; + if (sizech,session,RTCP_APP,subtype,size); + app->ssrc=htonl(session->snd.ssrc); + memset(app->name,0,4); + strncpy(app->name,name,4); + return sizeof(rtcp_app_t); +} + +static mblk_t * make_rr(RtpSession *session){ + mblk_t *cm=NULL; + mblk_t *sdes=NULL; + + cm=allocb(sizeof(rtcp_sr_t),0); + cm->b_wptr+=rtcp_rr_init(session,cm->b_wptr,sizeof(rtcp_rr_t)); + /* make a SDES packet */ + if (session->sd!=NULL) + sdes=rtp_session_create_rtcp_sdes_packet(session); + /* link them */ + cm->b_cont=sdes; + return cm; +} + + +static mblk_t * make_sr(RtpSession *session){ + mblk_t *cm=NULL; + mblk_t *sdes=NULL; + + cm=allocb(sizeof(rtcp_sr_t),0); + cm->b_wptr+=rtcp_sr_init(session,cm->b_wptr,sizeof(rtcp_sr_t)); + /* make a SDES packet */ + if (session->sd!=NULL) + sdes=rtp_session_create_rtcp_sdes_packet(session); + /* link them */ + cm->b_cont=sdes; + return cm; +} + +void rtp_session_rtcp_process_send(RtpSession *session){ + RtpStream *st=&session->rtp; + mblk_t *m; + if (st->rcv_last_app_ts - st->last_rtcp_report_snt_r > st->rtcp_report_snt_interval + || st->snd_last_ts - st->last_rtcp_report_snt_s > st->rtcp_report_snt_interval){ + st->last_rtcp_report_snt_r=st->rcv_last_app_ts; + st->last_rtcp_report_snt_s=st->snd_last_ts; + m=make_sr(session); + /* send the compound packet */ + rtp_session_rtcp_send(session,m); + ortp_debug("Rtcp compound message sent."); + } +} + +void rtp_session_rtcp_process_recv(RtpSession *session){ + RtpStream *st=&session->rtp; + mblk_t *m=NULL; + if (st->rcv_last_app_ts - st->last_rtcp_report_snt_r > st->rtcp_report_snt_interval + || st->snd_last_ts - st->last_rtcp_report_snt_s > st->rtcp_report_snt_interval){ + st->last_rtcp_report_snt_r=st->rcv_last_app_ts; + st->last_rtcp_report_snt_s=st->snd_last_ts; + + if (session->rtp.last_rtcp_packet_countrtp.stats.packet_sent){ + m=make_sr(session); + session->rtp.last_rtcp_packet_count=session->rtp.stats.packet_sent; + }else if (session->rtp.stats.packet_recv>0){ + /*don't send RR when no packet are received yet*/ + m=make_rr(session); + } + if (m!=NULL){ + /* send the compound packet */ + rtp_session_rtcp_send(session,m); + ortp_debug("Rtcp compound message sent."); + } + } +} + +void rtp_session_send_rtcp_APP(RtpSession *session, uint8_t subtype, const char *name, const uint8_t *data, int datalen){ + mblk_t *h=allocb(sizeof(rtcp_app_t),0); + mblk_t *d; + h->b_wptr+=rtcp_app_init(session,h->b_wptr,subtype,name,datalen+sizeof(rtcp_app_t)); + d=esballoc((uint8_t*)data,datalen,0,NULL); + h->b_cont=d; + rtp_session_rtcp_send(session,h); +} + +/** + * Sends a RTCP bye packet. + *@param session RtpSession + *@param reason the reason phrase. +**/ +int +rtp_session_bye(RtpSession *session, const char *reason) +{ + mblk_t *cm; + mblk_t *sdes = NULL; + mblk_t *bye = NULL; + int ret; + + /* Make a BYE packet (will be on the end of the compund packet). */ + bye = rtcp_create_simple_bye_packet(session->snd.ssrc, reason); + + /* SR or RR is determined by the fact whether stream was sent*/ + if (session->rtp.stats.packet_sent>0) + { + cm = allocb(sizeof(rtcp_sr_t), 0); + cm->b_wptr += rtcp_sr_init(session,cm->b_wptr, sizeof(rtcp_sr_t)); + /* make a SDES packet */ + sdes = rtp_session_create_rtcp_sdes_packet(session); + /* link them */ + concatb(concatb(cm, sdes), bye); + } else if (session->rtp.stats.packet_recv>0){ + /* make a RR packet */ + cm = allocb(sizeof(rtcp_rr_t), 0); + cm->b_wptr += rtcp_rr_init(session, cm->b_wptr, sizeof(rtcp_rr_t)); + /* link them */ + cm->b_cont = bye; + }else cm=bye; + + /* Send compound packet. */ + ret = rtp_session_rtcp_send(session, cm); + + return ret; +} + diff --git a/linphone/oRTP/src/rtcpparse.c b/linphone/oRTP/src/rtcpparse.c new file mode 100644 index 000000000..64df2c776 --- /dev/null +++ b/linphone/oRTP/src/rtcpparse.c @@ -0,0 +1,541 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "ortp/ortp.h" +#include "utils.h" + + +/*in case of coumpound packet, set read pointer of m to the beginning of the next RTCP +packet */ +bool_t rtcp_next_packet(mblk_t *m){ + const rtcp_common_header_t *ch=rtcp_get_common_header(m); + if (ch){ + int nextlen=sizeof(rtcp_common_header_t)+ + (rtcp_common_header_get_length(ch)*4); + if (m->b_rptr+nextlenb_wptr){ + m->b_rptr+=nextlen; + return TRUE; + } + } + return FALSE; +} + +void rtcp_rewind(mblk_t *m){ + m->b_rptr=m->b_datap->db_base; +} + +/* get common header; this function will also check the sanity of the packet*/ +const rtcp_common_header_t * rtcp_get_common_header(const mblk_t *m){ + int size=msgdsize(m); + rtcp_common_header_t *ch; + if (m->b_cont!=NULL){ + ortp_fatal("RTCP parser does not work on fragmented mblk_t. Use msgpullup() before to re-assemble the packet."); + return NULL; + } + if (sizeb_rptr; + return ch; +} + +bool_t rtcp_is_SR(const mblk_t *m){ + const rtcp_common_header_t *ch=rtcp_get_common_header(m); + if (ch!=NULL && rtcp_common_header_get_packet_type(ch)==RTCP_SR){ + if (msgdsize(m)b_rptr; + return ntohl(sr->ssrc); +} + +const sender_info_t * rtcp_SR_get_sender_info(const mblk_t *m){ + rtcp_sr_t *sr=(rtcp_sr_t*)m->b_rptr; + return &sr->si; +} + +const report_block_t * rtcp_SR_get_report_block(const mblk_t *m, int idx){ + rtcp_sr_t *sr=(rtcp_sr_t*)m->b_rptr; + report_block_t *rb=&sr->rb[idx]; + int size=sizeof(rtcp_common_header_t)+(4*rtcp_common_header_get_length(&sr->ch)); + if ( ( (uint8_t*)rb)+sizeof(report_block_t) <= m->b_rptr + size ) { + return rb; + }else{ + if (idxch)){ + ortp_warning("RTCP packet should include a report_block_t at pos %i but has no space for it.",idx); + } + } + return NULL; +} + +/*Receiver report accessors*/ +bool_t rtcp_is_RR(const mblk_t *m){ + const rtcp_common_header_t *ch=rtcp_get_common_header(m); + if (ch!=NULL && rtcp_common_header_get_packet_type(ch)==RTCP_RR){ + if (msgdsize(m)b_rptr; + return ntohl(rr->ssrc); +} + +const report_block_t * rtcp_RR_get_report_block(const mblk_t *m,int idx){ + rtcp_rr_t *rr=(rtcp_rr_t*)m->b_rptr; + report_block_t *rb=&rr->rb[idx]; + int size=sizeof(rtcp_common_header_t)+(4*rtcp_common_header_get_length(&rr->ch)); + if ( ( (uint8_t*)rb)+sizeof(report_block_t) <= (m->b_rptr + size ) ){ + return rb; + }else{ + if (idxch)){ + ortp_warning("RTCP packet should include a report_block_t at pos %i but has no space for it.",idx); + } + } + return NULL; +} + +/*SDES accessors */ +bool_t rtcp_is_SDES(const mblk_t *m){ + const rtcp_common_header_t *ch=rtcp_get_common_header(m); + if (ch && rtcp_common_header_get_packet_type(ch)==RTCP_SDES){ + if (msgdsize(m)b_rptr+sizeof(rtcp_common_header_t); + const rtcp_common_header_t *ch=(rtcp_common_header_t*)m->b_rptr; + uint8_t *end=rptr+sizeof(rtcp_common_header_t)+ + (4*rtcp_common_header_get_length(ch)); + uint32_t ssrc=0; + int nchunk=0; + bool_t chunk_start=TRUE; + + if (end>(uint8_t*)m->b_wptr) end=(uint8_t*)m->b_wptr; + + while(rptrb_rptr; + int rc=rtcp_common_header_get_rc(&bye->ch); + int len=rtcp_common_header_get_length(&bye->ch); + if (idxssrc[idx]<=(m->b_rptr + +sizeof(rtcp_common_header_t)+len-4)) { + *ssrc=ntohl(bye->ssrc[idx]); + return TRUE; + }else{ + ortp_warning("RTCP BYE should contain %i ssrc, but there is not enough room for it."); + } + } + return FALSE; +} + +bool_t rtcp_BYE_get_reason(const mblk_t *m, const char **reason, int *reason_len){ + rtcp_bye_t *bye=(rtcp_bye_t*)m->b_rptr; + int rc=rtcp_common_header_get_rc(&bye->ch); + int len=rtcp_common_header_get_length(&bye->ch); + uint8_t *rptr=(uint8_t*)m->b_rptr+sizeof(rtcp_common_header_t)+rc*4; + uint8_t *end=(uint8_t*)(m->b_rptr+sizeof(rtcp_common_header_t)+len); + if (rptrb_rptr; + return rtcp_common_header_get_rc(&app->ch); +} + +uint32_t rtcp_APP_get_ssrc(const mblk_t *m){ + rtcp_app_t *app=(rtcp_app_t*)m->b_rptr; + return ntohl(app->ssrc); +} +/* name argument is supposed to be at least 4 characters (note: no '\0' written)*/ +void rtcp_APP_get_name(const mblk_t *m, char *name){ + rtcp_app_t *app=(rtcp_app_t*)m->b_rptr; + memcpy(name,app->name,4); +} +/* retrieve the data. when returning, data points directly into the mblk_t */ +void rtcp_APP_get_data(const mblk_t *m, uint8_t **data, int *len){ + rtcp_app_t *app=(rtcp_app_t*)m->b_rptr; + int datalen=sizeof(rtcp_common_header_t)+rtcp_common_header_get_length(&app->ch)-8; + if (datalen>0){ + *data=(uint8_t*)m->b_rptr+sizeof(rtcp_app_t); + *len=datalen; + }else{ + *len=0; + *data=NULL; + } +} + +/*old functions: deprecated, but some useful code parts can be reused */ +/* Start from now this source code file was written by Nicola Baldo as an extension of + the oRTP library. Copyright (C) 2005 Nicola Baldo nicola@baldo.biz*/ + +void report_block_parse(RtpSession *session, report_block_t *rb, struct timeval rcv_time_tv) +{ + rb->ssrc = ntohl(rb->ssrc); + + if ( rb->ssrc != session->snd.ssrc ) + + { + ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded"); + return; + } + + else + + { + uint32_t rcv_time_msw; + uint32_t rcv_time_lsw; + uint32_t rcv_time; + double rtt; + + rcv_time_msw = rcv_time_tv.tv_sec; +#if defined(_WIN32_WCE) + rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(((uint64_t)1)<<32)*1.0e-6); +#else + rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6); +#endif + rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16); + +/* + rb->cum_num_packet_lost = ntoh24(rb->cum_num_packet_lost); + rb->ext_high_seq_num_rec = ntohl(rb->ext_high_seq_num_rec); + rb->interarrival_jitter = ntohl(rb->interarrival_jitter); + rb->lsr = ntohl(rb->lsr); + rb->delay_snc_last_sr = ntohl(rb->delay_snc_last_sr); +*/ + + /* calculating Round Trip Time*/ + if (rb->lsr != 0) + { + rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr); + rtt = rtt/65536; + //printf("RTT = %f s\n",rtt); + } + + } + +} + +void rtp_session_rtcp_parse(RtpSession *session, mblk_t *mp) +{ + rtcp_common_header_t *rtcp; + int msgsize; + int rtcp_pk_size; + RtpStream *rtpstream=&session->rtp; + struct timeval rcv_time_tv; + + + gettimeofday(&rcv_time_tv,NULL); + + return_if_fail(mp!=NULL); + + msgsize=(int) (mp->b_wptr-mp->b_rptr); + + if (msgsize < RTCP_COMMON_HEADER_SIZE) + { + ortp_debug("Receiving too short rtcp packet... discarded"); + return; + } + + rtcp=(rtcp_common_header_t *)mp->b_rptr; + + /* compound rtcp packet can be composed by more than one rtcp message */ + while (msgsize >= RTCP_COMMON_HEADER_SIZE) + { + + if (rtcp->version!=2) + { + ortp_debug("Receiving rtcp packet with version number !=2...discarded"); + return; + } + + /* convert header data from network order to host order */ + rtcp->length = ntohs(rtcp->length); + + /* compute length */ + rtcp_pk_size = (rtcp->length + 1) * 4; + /* Sanity check of simple RTCP packet length. */ + if (rtcp_pk_size > msgsize) + { + ortp_debug("Receiving rtcp packet shorter than the specified length.. discared"); + return; + } + + switch (rtcp->packet_type) + + { + + case RTCP_SR: + + { + rtcp_sr_t *sr = (rtcp_sr_t *) rtcp; + report_block_t *rb; + int i; + + if ( ntohl(sr->ssrc) != session->rcv.ssrc ) + { + ortp_debug("Receiving rtcp sr packet from unknown ssrc.. discarded"); + return; + } + + if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + RTCP_SENDER_INFO_SIZE + (RTCP_REPORT_BLOCK_SIZE*sr->ch.rc)) + { + ortp_debug("Receiving too short rtcp sr packet... discarded"); + return; + } + + /* parsing RTCP Sender Info */ + sr->si.ntp_timestamp_msw = ntohl(sr->si.ntp_timestamp_msw); + sr->si.ntp_timestamp_lsw = ntohl(sr->si.ntp_timestamp_lsw); + sr->si.rtp_timestamp = ntohl(sr->si.rtp_timestamp); + sr->si.senders_packet_count = ntohl(sr->si.senders_packet_count); + sr->si.senders_octet_count = ntohl(sr->si.senders_octet_count); + + /* saving data to fill LSR and DLSR field in next RTCP report to be transmitted */ + rtpstream->last_rcv_SR_ts = (sr->si.ntp_timestamp_msw << 16) | (sr->si.ntp_timestamp_lsw >> 16); + rtpstream->last_rcv_SR_time.tv_usec = rcv_time_tv.tv_usec; + rtpstream->last_rcv_SR_time.tv_sec = rcv_time_tv.tv_sec; + + + /* parsing all RTCP report blocks */ + for (i=0; ich.rc; i++) + { + rb = &(sr->rb[i]); + report_block_parse(session, rb, rcv_time_tv); + } + + } + break; + + + + case RTCP_RR: + + { + rtcp_rr_t *rr = (rtcp_rr_t *) rtcp; + report_block_t *rb; + int i; + + if (session->rcv.ssrc == 0) + { + /* rcv.ssrc is not set, so we adopt the incoming one */ + session->rcv.ssrc = ntohl(rr->ssrc); + } + else if ( ntohl(rr->ssrc) != session->rcv.ssrc ) + { + ortp_debug("Receiving rtcp rr packet from unknown ssrc.. discarded"); + return; + } + + if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + (RTCP_REPORT_BLOCK_SIZE*rr->ch.rc)) + { + ortp_debug("Receiving too short rtcp sr packet... discarded"); + return; + } + + /* parsing all RTCP report blocks */ + for (i=0; ich.rc; i++) + { + rb = &(rr->rb[i]); + report_block_parse(session, rb, rcv_time_tv); + } + + } + break; + + + case RTCP_SDES: + /* to be implemented */ + break; + + + case RTCP_BYE: + { + rtcp_bye_t *bye = (rtcp_bye_t *) rtcp; + unsigned sclen = bye->ch.rc * 4; + int reason_space_len = rtcp_pk_size + - sizeof (rtcp_common_header_t) + - sclen; + int i; + char *reason = NULL; + bool_t rcv_ssrc_match = FALSE; + + if (reason_space_len < 0) { + ortp_debug("Receiving too short RTCP BYE packet... discarded"); + return; + } + for (i = 0; i < bye->ch.rc; i++) { + if (ntohl(bye->ssrc[i]) == session->rcv.ssrc) { + rcv_ssrc_match = TRUE; + break; + } + } + if (rcv_ssrc_match) { + if (session->on_rtcp_bye.count > 0) { + /* Get reason. */ + if (reason_space_len > 1) { + uint8_t *reasonbuf = (uint8_t *) rtcp + + sizeof (rtcp_common_header_t) + + sclen; + if (reasonbuf[0] <= reason_space_len-1) + reason = ortp_strndup((char *)(reasonbuf+1), reasonbuf[0]); + else + ortp_debug("Incorrect RTCP BYE reason length"); + } + rtp_signal_table_emit2(&session->on_rtcp_bye, + (long)reason); + if (reason) + ortp_free(reason); + } else { + ortp_debug("Got RTCP BYE without RTCP BYE handler"); + } + } else { + ortp_debug("No SSRC in the BYE packet matched our rcv.ssrc."); + } + break; + } + + case RTCP_APP: + /* to be implemented */ + break; + + + default: + + ortp_debug("Receiving unknown rtcp packet type... discarded"); + return; + + } + + + msgsize -= rtcp_pk_size; /* size of unparsed portion of UDP packet, in octets */ + rtcp = (rtcp_common_header_t *) (rtcp_pk_size + (char *) rtcp); /* pointer to next RTCP packet in current UDP packet */ + + } + + /* The function did not failed sanity checks, write down the RTPC/RTCP + reception time. */ + session->last_recv_time = rcv_time_tv; +} diff --git a/linphone/oRTP/src/rtpparse.c b/linphone/oRTP/src/rtpparse.c new file mode 100644 index 000000000..93c15cbbe --- /dev/null +++ b/linphone/oRTP/src/rtpparse.c @@ -0,0 +1,213 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include +#include "jitterctl.h" +#include "utils.h" +#include "rtpsession_priv.h" + +#define SSRC_CHANGED_THRESHOLD 50 + +static void queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded) +{ + mblk_t *tmp; + int header_size; + *discarded=0; + header_size=RTP_FIXED_HEADER_SIZE+ (4*rtp->cc); + if ((mp->b_wptr - mp->b_rptr)==header_size){ + ortp_debug("Rtp packet contains no data."); + (*discarded)++; + freemsg(mp); + return; + } + /* and then add the packet to the queue */ + + rtp_putq(q,mp); + /* make some checks: q size must not exceed RtpStream::max_rq_size */ + while (q->q_mcount > maxrqsz) + { + /* remove the oldest mblk_t */ + tmp=getq(q); + if (mp!=NULL) + { + ortp_debug("rtp_putq: Queue is full. Discarding message with ts=%i",((rtp_header_t*)mp->b_rptr)->timestamp); + freemsg(tmp); + (*discarded)++; + } + } +} + +void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, struct sockaddr *addr, socklen_t addrlen) +{ + int i; + rtp_header_t *rtp; + int msgsize; + RtpStream *rtpstream=&session->rtp; + rtp_stats_t *stats=&rtpstream->stats; + + msgsize=mp->b_wptr-mp->b_rptr; + + if (msgsizestats.bad++; + ortp_global_stats.bad++; + freemsg(mp); + return; + } + rtp=(rtp_header_t*)mp->b_rptr; + if (rtp->version!=2) + { + /* try to see if it is a STUN packet */ + uint16_t stunlen=*((uint16_t*)(mp->b_rptr + sizeof(uint16_t))); + stunlen = ntohs(stunlen); + if (stunlen+20==mp->b_wptr-mp->b_rptr){ + /* this looks like a stun packet */ + if (session->eventqs!=NULL){ + OrtpEvent *ev=ortp_event_new(ORTP_EVENT_STUN_PACKET_RECEIVED); + OrtpEventData *ed=ortp_event_get_data(ev); + ed->packet=mp; + ed->ep=rtp_endpoint_new(addr,addrlen); + rtp_session_dispatch_event(session,ev); + return; + } + }else{ + /* discard*/ + ortp_debug("Receiving rtp packet with version number !=2...discarded"); + stats->bad++; + ortp_global_stats.bad++; + freemsg(mp); + return; + } + } + + /* only count non-stun packets. */ + ortp_global_stats.packet_recv++; + stats->packet_recv++; + ortp_global_stats.hw_recv+=msgsize; + stats->hw_recv+=msgsize; + session->rtp.hwrcv_since_last_SR++; + + + /* convert all header data from network order to host order */ + rtp->seq_number=ntohs(rtp->seq_number); + rtp->timestamp=ntohl(rtp->timestamp); + rtp->ssrc=ntohl(rtp->ssrc); + /* convert csrc if necessary */ + if (rtp->cc*sizeof(uint32_t) > (uint32_t) (msgsize-RTP_FIXED_HEADER_SIZE)){ + ortp_debug("Receiving too short rtp packet."); + stats->bad++; + ortp_global_stats.bad++; + freemsg(mp); + return; + } + +#ifndef PERF + /* Write down the last RTP/RTCP packet reception time. */ + gettimeofday(&session->last_recv_time, NULL); +#endif + + for (i=0;icc;i++) + rtp->csrc[i]=ntohl(rtp->csrc[i]); + /*the goal of the following code is to lock on an incoming SSRC to avoid + receiving "mixed streams"*/ + if (session->ssrc_set){ + /*the ssrc is set, so we must check it */ + if (session->rcv.ssrc!=rtp->ssrc){ + if (session->inc_ssrc_candidate==rtp->ssrc){ + session->inc_same_ssrc_count++; + }else{ + session->inc_same_ssrc_count=0; + session->inc_ssrc_candidate=rtp->ssrc; + } + if (session->inc_same_ssrc_count>SSRC_CHANGED_THRESHOLD){ + session->rcv.ssrc=rtp->ssrc; + rtp_signal_table_emit(&session->on_ssrc_changed); + }else{ + /*discard the packet*/ + ortp_debug("Receiving packet with unknown ssrc."); + stats->bad++; + ortp_global_stats.bad++; + freemsg(mp); + return; + } + } + }else{ + session->ssrc_set=TRUE; + session->rcv.ssrc=rtp->ssrc; + } + + /* update some statistics */ + { + poly32_t *extseq=(poly32_t*)&rtpstream->hwrcv_extseq; + if (rtp->seq_number>extseq->split.lo){ + extseq->split.lo=rtp->seq_number; + }else if (rtp->seq_number<200 && extseq->split.lo>((1<<16) - 200)){ + /* this is a check for sequence number looping */ + extseq->split.lo=rtp->seq_number; + extseq->split.hi++; + } + } + + /* check for possible telephone events */ + if (rtp->paytype==session->rcv.telephone_events_pt){ + queue_packet(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&i); + stats->discarded+=i; + ortp_global_stats.discarded+=i; + return; + } + + /* check for possible payload type change, in order to update accordingly our clock-rate dependant + parameters */ + if (session->hw_recv_pt!=rtp->paytype){ + rtp_session_update_payload_type(session,rtp->paytype); + } + + jitter_control_new_packet(&session->rtp.jittctl,rtp->timestamp,local_str_ts); + + if (session->flags & RTP_SESSION_FIRST_PACKET_DELIVERED) { + /* detect timestamp important jumps in the future, to workaround stupid rtp senders */ + if (RTP_TIMESTAMP_IS_NEWER_THAN(rtp->timestamp,session->rtp.rcv_last_ts+session->rtp.ts_jump)){ + ortp_debug("rtp_parse: timestamp jump ?"); + rtp_signal_table_emit2(&session->on_timestamp_jump,(long)&rtp->timestamp); + } + else if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(session->rtp.rcv_last_ts,rtp->timestamp)){ + /* don't queue packets older than the last returned packet to the application*/ + /* Call timstamp jumb in case of + * large negative Ts jump or if ts is set to 0 + */ + + if ( RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(session->rtp.rcv_last_ts, rtp->timestamp + session->rtp.ts_jump) ){ + ortp_warning("rtp_parse: negative timestamp jump"); + rtp_signal_table_emit2(&session->on_timestamp_jump, + (long)&rtp->timestamp); + } + ortp_debug("rtp_parse: discarding too old packet (ts=%i)",rtp->timestamp); + freemsg(mp); + stats->outoftime++; + ortp_global_stats.outoftime++; + return; + } + } + + queue_packet(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&i); + stats->discarded+=i; + ortp_global_stats.discarded+=i; +} + diff --git a/linphone/oRTP/src/rtpsession.c b/linphone/oRTP/src/rtpsession.c new file mode 100644 index 000000000..f773dcb86 --- /dev/null +++ b/linphone/oRTP/src/rtpsession.c @@ -0,0 +1,1596 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif + +#include "ortp/ortp.h" +#include "ortp/telephonyevents.h" +#include "ortp/rtcp.h" +#include "jitterctl.h" +#include "scheduler.h" +#include "utils.h" +#include "rtpsession_priv.h" + +extern mblk_t *rtcp_create_simple_bye_packet(uint32_t ssrc, const char *reason); +extern int rtcp_sr_init(RtpSession *session, char *buf, int size); +extern int rtcp_rr_init(RtpSession *session, char *buf, int size); + + + +/* this function initialize all session parameter's that depend on the payload type */ +static void payload_type_changed(RtpSession *session, PayloadType *pt){ + jitter_control_set_payload(&session->rtp.jittctl,pt); + session->rtp.rtcp_report_snt_interval=RTCP_DEFAULT_REPORT_INTERVAL*pt->clock_rate; + rtp_session_set_time_jump_limit(session,session->rtp.time_jump); + if (pt->type==PAYLOAD_VIDEO){ + session->permissive=TRUE; + ortp_message("Using permissive algorithm"); + } + else session->permissive=FALSE; +} + +void wait_point_init(WaitPoint *wp){ + ortp_mutex_init(&wp->lock,NULL); + ortp_cond_init(&wp->cond,NULL); + wp->time=0; + wp->wakeup=FALSE; +} +void wait_point_uninit(WaitPoint *wp){ + ortp_cond_destroy(&wp->cond); + ortp_mutex_destroy(&wp->lock); +} + +#define wait_point_lock(wp) ortp_mutex_lock(&(wp)->lock) +#define wait_point_unlock(wp) ortp_mutex_unlock(&(wp)->lock) + +void wait_point_wakeup_at(WaitPoint *wp, uint32_t t, bool_t dosleep){ + wp->time=t; + wp->wakeup=TRUE; + if (dosleep) ortp_cond_wait(&wp->cond,&wp->lock); +} + + +bool_t wait_point_check(WaitPoint *wp, uint32_t t){ + bool_t ok=FALSE; + + if (wp->wakeup){ + if (TIME_IS_NEWER_THAN(t,wp->time)){ + wp->wakeup=FALSE; + ok=TRUE; + + } + } + return ok; +} +#define wait_point_wakeup(wp) ortp_cond_signal(&(wp)->cond); + +extern void rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, + struct sockaddr *addr, socklen_t addrlen); + + +static uint32_t uint32_t_random(){ + return random(); +} + + +#define RTP_SEQ_IS_GREATER(seq1,seq2)\ + ((uint16_t)((uint16_t)(seq1) - (uint16_t)(seq2))< (uint16_t)(1<<15)) + +/* put an rtp packet in queue. It is called by rtp_parse()*/ +void rtp_putq(queue_t *q, mblk_t *mp) +{ + mblk_t *tmp; + rtp_header_t *rtp=(rtp_header_t*)mp->b_rptr,*tmprtp; + /* insert message block by increasing time stamp order : the last (at the bottom) + message of the queue is the newest*/ + ortp_debug("rtp_putq(): Enqueuing packet with ts=%i and seq=%i",rtp->timestamp,rtp->seq_number); + + if (qempty(q)) { + putq(q,mp); + return; + } + tmp=qlast(q); + /* we look at the queue from bottom to top, because enqueued packets have a better chance + to be enqueued at the bottom, since there are surely newer */ + while (!qend(q,tmp)) + { + tmprtp=(rtp_header_t*)tmp->b_rptr; + ortp_debug("rtp_putq(): Seeing packet with seq=%i",tmprtp->seq_number); + + if (rtp->seq_number == tmprtp->seq_number) + { + /* this is a duplicated packet. Don't queue it */ + ortp_debug("rtp_putq: duplicated message."); + freemsg(mp); + return; + }else if (RTP_SEQ_IS_GREATER(rtp->seq_number,tmprtp->seq_number)){ + + insq(q,tmp->b_next,mp); + return; + } + tmp=tmp->b_prev; + } + /* this packet is the oldest, it has to be + placed on top of the queue */ + insq(q,qfirst(q),mp); + +} + + + +mblk_t *rtp_getq(queue_t *q,uint32_t timestamp, int *rejected) +{ + mblk_t *tmp,*ret=NULL,*old=NULL; + rtp_header_t *tmprtp; + uint32_t ts_found=0; + + *rejected=0; + ortp_debug("rtp_getq(): Timestamp %i wanted.",timestamp); + + if (qempty(q)) + { + /*ortp_debug("rtp_getq: q is empty.");*/ + return NULL; + } + /* return the packet with ts just equal or older than the asked timestamp */ + /* packets with older timestamps are discarded */ + while ((tmp=qfirst(q))!=NULL) + { + tmprtp=(rtp_header_t*)tmp->b_rptr; + ortp_debug("rtp_getq: Seeing packet with ts=%i",tmprtp->timestamp); + if ( RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,tmprtp->timestamp) ) + { + if (ret!=NULL && tmprtp->timestamp==ts_found) { + /* we've found two packets with same timestamp. return the first one */ + break; + } + if (old!=NULL) { + ortp_debug("rtp_getq: discarding too old packet with ts=%i",ts_found); + (*rejected)++; + freemsg(old); + } + ret=getq(q); /* dequeue the packet, since it has an interesting timestamp*/ + ts_found=tmprtp->timestamp; + ortp_debug("rtp_getq: Found packet with ts=%i",tmprtp->timestamp); + old=ret; + } + else + { + break; + } + } + return ret; +} + +mblk_t *rtp_getq_permissive(queue_t *q,uint32_t timestamp, int *rejected) +{ + mblk_t *tmp,*ret=NULL; + rtp_header_t *tmprtp; + + *rejected=0; + ortp_debug("rtp_getq_permissive(): Timestamp %i wanted.",timestamp); + + if (qempty(q)) + { + /*ortp_debug("rtp_getq: q is empty.");*/ + return NULL; + } + /* return the packet with the older timestamp (provided that it is older than + the asked timestamp) */ + tmp=qfirst(q); + tmprtp=(rtp_header_t*)tmp->b_rptr; + ortp_debug("rtp_getq_permissive: Seeing packet with ts=%i",tmprtp->timestamp); + if ( RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,tmprtp->timestamp) ) + { + ret=getq(q); /* dequeue the packet, since it has an interesting timestamp*/ + ortp_debug("rtp_getq_permissive: Found packet with ts=%i",tmprtp->timestamp); + } + return ret; +} + + +void +rtp_session_init (RtpSession * session, int mode) +{ + JBParameters jbp; + memset (session, 0, sizeof (RtpSession)); + session->mode = (RtpSessionMode) mode; + if ((mode == RTP_SESSION_RECVONLY) || (mode == RTP_SESSION_SENDRECV)) + { + rtp_session_set_flag (session, RTP_SESSION_RECV_SYNC); + rtp_session_set_flag (session, RTP_SESSION_RECV_NOT_STARTED); + + } + if ((mode == RTP_SESSION_SENDONLY) || (mode == RTP_SESSION_SENDRECV)) + { + rtp_session_set_flag (session, RTP_SESSION_SEND_NOT_STARTED); + session->snd.ssrc=uint32_t_random(); + /* set default source description */ + rtp_session_set_source_description(session,"unknown@unknown",NULL,NULL, + NULL,NULL,"oRTP-" ORTP_VERSION,"This is free sofware (LGPL) !"); + } + session->snd.telephone_events_pt=-1; /* not defined a priori */ + session->rcv.telephone_events_pt=-1; /* not defined a priori */ + rtp_session_set_profile (session, &av_profile); /*the default profile to work with */ + session->rtp.socket=-1; + session->rtcp.socket=-1; +#ifndef WIN32 + session->rtp.snd_socket_size=0; /*use OS default value unless on windows where they are definitely too short*/ + session->rtp.rcv_socket_size=0; +#else + session->rtp.snd_socket_size=session->rtp.rcv_socket_size=65536; +#endif + session->dscp=RTP_DEFAULT_DSCP; + session->multicast_ttl=RTP_DEFAULT_MULTICAST_TTL; + session->multicast_loopback=RTP_DEFAULT_MULTICAST_LOOPBACK; + qinit(&session->rtp.rq); + qinit(&session->rtp.tev_rq); + qinit(&session->contributing_sources); + session->eventqs=NULL; + /* init signal tables */ + rtp_signal_table_init (&session->on_ssrc_changed, session,"ssrc_changed"); + rtp_signal_table_init (&session->on_payload_type_changed, session,"payload_type_changed"); + rtp_signal_table_init (&session->on_telephone_event, session,"telephone-event"); + rtp_signal_table_init (&session->on_telephone_event_packet, session,"telephone-event_packet"); + rtp_signal_table_init (&session->on_timestamp_jump,session,"timestamp_jump"); + rtp_signal_table_init (&session->on_network_error,session,"network_error"); + rtp_signal_table_init (&session->on_rtcp_bye,session,"rtcp_bye"); + wait_point_init(&session->snd.wp); + wait_point_init(&session->rcv.wp); + /*defaults send payload type to 0 (pcmu)*/ + rtp_session_set_send_payload_type(session,0); + /*sets supposed recv payload type to undefined */ + rtp_session_set_recv_payload_type(session,-1); + /* configure jitter buffer with working default parameters */ + jbp.min_size=RTP_DEFAULT_JITTER_TIME; + jbp.nom_size=RTP_DEFAULT_JITTER_TIME; + jbp.max_size=-1; + jbp.max_packets= 100;/* maximum number of packet allowed to be queued */ + jbp.adaptive=TRUE; + rtp_session_enable_jitter_buffer(session,TRUE); + rtp_session_set_jitter_buffer_params(session,&jbp); + rtp_session_set_time_jump_limit(session,5000); + rtp_session_enable_rtcp(session,TRUE); + session->recv_buf_size = UDP_MAX_SIZE; + session->symmetric_rtp = FALSE; + session->permissive=FALSE; + msgb_allocator_init(&session->allocator); +} + + +/** + * Creates a new rtp session. + * If the session is able to send data (RTP_SESSION_SENDONLY or + * RTP_SESSION_SENDRECV), then a random SSRC number is choosed for + * the outgoing stream. + * @param mode One of the RtpSessionMode flags. + * + * @return the newly created rtp session. +**/ +RtpSession * +rtp_session_new (int mode) +{ + RtpSession *session; + session = (RtpSession *) ortp_malloc (sizeof (RtpSession)); + rtp_session_init (session, mode); + return session; +} + +/** + * Sets the scheduling mode of the rtp session. If @yesno is TRUE, the rtp session is in + * the scheduled mode, that means that you can use session_set_select() to block until it's time + * to receive or send on this session according to the timestamp passed to the respective functions. + * You can also use blocking mode (see rtp_session_set_blocking_mode() ), to simply block within + * the receive and send functions. + * If @yesno is FALSE, the ortp scheduler will not manage those sessions, meaning that blocking mode + * and the use of session_set_select() for this session are disabled. + *@param session a rtp session. + *@param yesno a boolean to indicate the scheduling mode. + * + * +**/ +void +rtp_session_set_scheduling_mode (RtpSession * session, int yesno) +{ + if (yesno) + { + RtpScheduler *sched; + sched = ortp_get_scheduler (); + if (sched != NULL) + { + rtp_session_set_flag (session, RTP_SESSION_SCHEDULED); + session->sched = sched; + rtp_scheduler_add_session (sched, session); + } + else + ortp_warning + ("rtp_session_set_scheduling_mode: Cannot use scheduled mode because the " + "scheduler is not started. Use ortp_scheduler_init() before."); + } + else + rtp_session_unset_flag (session, RTP_SESSION_SCHEDULED); +} + + +/** + * This function implicitely enables the scheduling mode if yesno is TRUE. + * rtp_session_set_blocking_mode() defines the behaviour of the rtp_session_recv_with_ts() and + * rtp_session_send_with_ts() functions. If @yesno is TRUE, rtp_session_recv_with_ts() + * will block until it is time for the packet to be received, according to the timestamp + * passed to the function. After this time, the function returns. + * For rtp_session_send_with_ts(), it will block until it is time for the packet to be sent. + * If @yesno is FALSE, then the two functions will return immediately. + * + * @param session a rtp session + * @param yesno a boolean +**/ +void +rtp_session_set_blocking_mode (RtpSession * session, int yesno) +{ + if (yesno){ + rtp_session_set_scheduling_mode(session,TRUE); + rtp_session_set_flag (session, RTP_SESSION_BLOCKING_MODE); + }else + rtp_session_unset_flag (session, RTP_SESSION_BLOCKING_MODE); +} + +/** + * Set the RTP profile to be used for the session. By default, all session are created by + * rtp_session_new() are initialized with the AV profile, as defined in RFC 3551. The application + * can set any other profile instead using that function. + * + * @param session a rtp session + * @param profile a rtp profile +**/ + +void +rtp_session_set_profile (RtpSession * session, RtpProfile * profile) +{ + session->snd.profile = profile; + session->rcv.profile = profile; + rtp_session_telephone_events_supported(session); +} + +/** + * By default oRTP automatically sends RTCP SR or RR packets. If + * yesno is set to FALSE, the RTCP sending of packet is disabled. + * This functionnality might be needed for some equipments that do not + * support RTCP, leading to a traffic of ICMP errors on the network. + * It can also be used to save bandwidth despite the RTCP bandwidth is + * actually and usually very very low. +**/ +void rtp_session_enable_rtcp(RtpSession *session, bool_t yesno){ + session->rtcp.enabled=yesno; +} + +/** + * Set the RTP profile to be used for the sending by this session. By default, all session are created by + * rtp_session_new() are initialized with the AV profile, as defined in RFC 3551. The application + * can set any other profile instead using that function. + * @param session a rtp session + * @param profile a rtp profile + * +**/ + +void +rtp_session_set_send_profile (RtpSession * session, RtpProfile * profile) +{ + session->snd.profile = profile; + rtp_session_send_telephone_events_supported(session); +} + + + +/** + * Set the RTP profile to be used for the receiveing by this session. By default, all session are created by + * rtp_session_new() are initialized with the AV profile, as defined in RFC 3551. The application + * can set any other profile instead using that function. + * + * @param session a rtp session + * @param profile a rtp profile +**/ + +void +rtp_session_set_recv_profile (RtpSession * session, RtpProfile * profile) +{ + session->rcv.profile = profile; + rtp_session_recv_telephone_events_supported(session); +} + +/** + *@param session a rtp session + * + * DEPRECATED! Returns current send profile. + * Use rtp_session_get_send_profile() or rtp_session_get_recv_profile() + * +**/ +RtpProfile *rtp_session_get_profile(RtpSession *session){ + return session->snd.profile; +} + + +/** + *@param session a rtp session + * + * Returns current send profile. + * +**/ +RtpProfile *rtp_session_get_send_profile(RtpSession *session){ + return session->snd.profile; +} + +/** + *@param session a rtp session + * + * Returns current receive profile. + * +**/ +RtpProfile *rtp_session_get_recv_profile(RtpSession *session){ + return session->rcv.profile; +} + +/** + * The default value is UDP_MAX_SIZE bytes, a value which is working for mostly everyone. + * However if your application can make assumption on the sizes of received packet, + * it can be interesting to set it to a lower value in order to save memory. + * + * @param session a rtp session + * @param bufsize max size in bytes for receiving packets +**/ +void rtp_session_set_recv_buf_size(RtpSession *session, int bufsize){ + session->recv_buf_size=bufsize; +} + +/** + * Set kernel send maximum buffer size for the rtp socket. + * A value of zero defaults to the operating system default. +**/ +void rtp_session_set_rtp_socket_send_buffer_size(RtpSession * session, unsigned int size){ + session->rtp.snd_socket_size=size; +} + +/** + * Set kernel recv maximum buffer size for the rtp socket. + * A value of zero defaults to the operating system default. +**/ +void rtp_session_set_rtp_socket_recv_buffer_size(RtpSession * session, unsigned int size){ + session->rtp.rcv_socket_size=size; +} + +/** + * This function provides the way for an application to be informed of various events that + * may occur during a rtp session. @signal is a string identifying the event, and @cb is + * a user supplied function in charge of processing it. The application can register + * several callbacks for the same signal, in the limit of #RTP_CALLBACK_TABLE_MAX_ENTRIES. + * Here are name and meaning of supported signals types: + * + * "ssrc_changed" : the SSRC of the incoming stream has changed. + * + * "payload_type_changed" : the payload type of the incoming stream has changed. + * + * "telephone-event_packet" : a telephone-event rtp packet (RFC2833) is received. + * + * "telephone-event" : a telephone event has occured. This is a high-level shortcut for "telephone-event_packet". + * + * "network_error" : a network error happened on a socket. Arguments of the callback functions are + * a const char * explaining the error, an int errno error code and the user_data as usual. + * + * "timestamp_jump" : we have received a packet with timestamp in far future compared to last timestamp received. + * The farness of far future is set by rtp_sesssion_set_time_jump_limit() + * "rtcp_bye": we have received a RTCP bye packet. Arguments of the callback + * functions are a const char * containing the leaving reason and + * the user_data. + * + * Returns: 0 on success, -EOPNOTSUPP if the signal does not exists, -1 if no more callbacks + * can be assigned to the signal type. + * + * @param session a rtp session + * @param signal_name the name of a signal + * @param cb a RtpCallback + * @param user_data a pointer to any data to be passed when invoking the callback. + * +**/ +int +rtp_session_signal_connect (RtpSession * session, const char *signal_name, + RtpCallback cb, unsigned long user_data) +{ + OList *elem; + for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){ + RtpSignalTable *s=(RtpSignalTable*) elem->data; + if (strcmp(signal_name,s->signal_name)==0){ + return rtp_signal_table_add(s,cb,user_data); + } + } + ortp_warning ("rtp_session_signal_connect: inexistant signal %s",signal_name); + return -1; +} + + +/** + * Removes callback function @cb to the list of callbacks for signal @signal. + * + * @param session a rtp session + * @param signal_name a signal name + * @param cb a callback function. + * @return: 0 on success, a negative value if the callback was not found. +**/ +int +rtp_session_signal_disconnect_by_callback (RtpSession * session, const char *signal_name, + RtpCallback cb) +{ + OList *elem; + for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){ + RtpSignalTable *s=(RtpSignalTable*) elem->data; + if (strcmp(signal_name,s->signal_name)==0){ + return rtp_signal_table_remove_by_callback(s,cb); + } + } + ortp_warning ("rtp_session_signal_connect: inexistant signal %s",signal_name); + return -1; +} + + +/** + * sets the initial sequence number of a sending session. + * @param session a rtp session freshly created. + * @param addr a 16 bit unsigned number. + * +**/ +void rtp_session_set_seq_number(RtpSession *session, uint16_t seq){ + session->rtp.snd_seq=seq; +} + + +uint16_t rtp_session_get_seq_number(RtpSession *session){ + return session->rtp.snd_seq; +} + + +/** + * Sets the SSRC for the outgoing stream. + * If not done, a random ssrc is used. + * + * @param session a rtp session. + * @param ssrc an unsigned 32bit integer representing the synchronisation source identifier (SSRC). +**/ +void +rtp_session_set_ssrc (RtpSession * session, uint32_t ssrc) +{ + session->snd.ssrc = ssrc; +} + + +void rtp_session_update_payload_type(RtpSession *session, int paytype){ + /* check if we support this payload type */ + PayloadType *pt=rtp_profile_get_payload(session->rcv.profile,paytype); + session->hw_recv_pt=paytype; + if (pt!=0){ + ortp_message ("payload type changed to %i(%s) !", + paytype,pt->mime_type); + payload_type_changed(session,pt); + }else{ + ortp_warning("Receiving packet with unknown payload type %i.",paytype); + } +} +/** + * Sets the payload type of the rtp session. It decides of the payload types written in the + * of the rtp header for the outgoing stream, if the session is SENDRECV or SENDONLY. + * For payload type in incoming packets, the application can be informed by registering + * for the "payload_type_changed" signal, so that it can make the necessary changes + * on the downstream decoder that deals with the payload of the packets. + * + * @param session a rtp session + * @param paytype the payload type number + * @return 0 on success, -1 if the payload is not defined. +**/ + +int +rtp_session_set_send_payload_type (RtpSession * session, int paytype) +{ + session->snd.pt=paytype; + return 0; +} + +/** + *@param session a rtp session + * + *@return the payload type currently used in outgoing rtp packets +**/ +int rtp_session_get_send_payload_type(const RtpSession *session){ + return session->snd.pt; +} + +/** + * + * Sets the expected payload type for incoming packets. + * If the actual payload type in incoming packets is different that this expected payload type, thus + * the "payload_type_changed" signal is emitted. + * + *@param session a rtp session + *@param paytype the payload type number + *@return 0 on success, -1 if the payload is not defined. +**/ + +int +rtp_session_set_recv_payload_type (RtpSession * session, int paytype) +{ + PayloadType *pt; + session->rcv.pt=paytype; + session->hw_recv_pt=paytype; + pt=rtp_profile_get_payload(session->rcv.profile,paytype); + if (pt!=NULL){ + payload_type_changed(session,pt); + } + return 0; +} + +/** + *@param session a rtp session + * + * @return the payload type currently used in incoming rtp packets +**/ +int rtp_session_get_recv_payload_type(const RtpSession *session){ + return session->rcv.pt; +} + +/** + * Sets the expected payload type for incoming packets and payload type to be used for outgoing packets. + * If the actual payload type in incoming packets is different that this expected payload type, thus + * the "payload_type_changed" signal is emitted. + * + * @param session a rtp session + * @param paytype the payload type number + * @return 0 on success, -1 if the payload is not defined. +**/ +int rtp_session_set_payload_type(RtpSession *session, int pt){ + if (rtp_session_set_send_payload_type(session,pt)<0) return -1; + if (rtp_session_set_recv_payload_type(session,pt)<0) return -1; + return 0; +} + + +static void rtp_header_init_from_session(rtp_header_t *rtp, RtpSession *session){ + rtp->version = 2; + rtp->padbit = 0; + rtp->extbit = 0; + rtp->markbit= 0; + rtp->cc = 0; + rtp->paytype = session->snd.pt; + rtp->ssrc = session->snd.ssrc; + rtp->timestamp = 0; /* set later, when packet is sended */ + /* set a seq number */ + rtp->seq_number=session->rtp.snd_seq; +} + +/** + * Allocates a new rtp packet. In the header, ssrc and payload_type according to the session's + * context. Timestamp and seq number are not set, there will be set when the packet is going to be + * sent with rtp_session_sendm_with_ts(). + * If payload_size is zero, thus an empty packet (just a RTP header) is returned. + * + *@param session a rtp session. + *@param header_size the rtp header size. For standart size (without extensions), it is RTP_FIXED_HEADER_SIZE + *@param payload data to be copied into the rtp packet. + *@param payload_size size of data carried by the rtp packet. + *@return a rtp packet in a mblk_t (message block) structure. +**/ +mblk_t * rtp_session_create_packet(RtpSession *session,int header_size, const uint8_t *payload, int payload_size) +{ + mblk_t *mp; + int msglen=header_size+payload_size; + rtp_header_t *rtp; + + mp=allocb(msglen,BPRI_MED); + rtp=(rtp_header_t*)mp->b_rptr; + rtp_header_init_from_session(rtp,session); + /*copy the payload, if any */ + mp->b_wptr+=header_size; + if (payload_size){ + memcpy(mp->b_wptr,payload,payload_size); + mp->b_wptr+=payload_size; + } + return mp; +} + +/** + * Creates a new rtp packet using the given payload buffer (no copy). The header will be allocated separetely. + * In the header, ssrc and payload_type according to the session's + * context. Timestamp and seq number are not set, there will be set when the packet is going to be + * sent with rtp_session_sendm_with_ts(). + * oRTP will send this packet using libc's sendmsg() (if this function is availlable!) so that there will be no + * packet concatenation involving copies to be done in user-space. + * @freefn can be NULL, in that case payload will be kept untouched. + * + * @param session a rtp session. + * @param payload the data to be sent with this packet + * @param payload_size size of data + * @param freefn a function that will be called when the payload buffer is no more needed. + * @return: a rtp packet in a mblk_t (message block) structure. +**/ + +mblk_t * rtp_session_create_packet_with_data(RtpSession *session, uint8_t *payload, int payload_size, void (*freefn)(void*)) +{ + mblk_t *mp,*mpayload; + int header_size=RTP_FIXED_HEADER_SIZE; /* revisit when support for csrc is done */ + rtp_header_t *rtp; + + mp=allocb(header_size,BPRI_MED); + rtp=(rtp_header_t*)mp->b_rptr; + rtp_header_init_from_session(rtp,session); + mp->b_wptr+=header_size; + /* create a mblk_t around the user supplied payload buffer */ + mpayload=esballoc(payload,payload_size,BPRI_MED,freefn); + mpayload->b_wptr+=payload_size; + /* link it with the header */ + mp->b_cont=mpayload; + return mp; +} + + +/** + * Creates a new rtp packet using the buffer given in arguments (no copy). + * In the header, ssrc and payload_type according to the session's + *context. Timestamp and seq number are not set, there will be set when the packet is going to be + * sent with rtp_session_sendm_with_ts(). + * @freefn can be NULL, in that case payload will be kept untouched. + * + * @param session a rtp session. + * @param buffer a buffer that contains first just enough place to write a RTP header, then the data to send. + * @param size the size of the buffer + * @param freefn a function that will be called once the buffer is no more needed (the data has been sent). + * @return a rtp packet in a mblk_t (message block) structure. +**/ +mblk_t * rtp_session_create_packet_in_place(RtpSession *session,uint8_t *buffer, int size, void (*freefn)(void*) ) +{ + mblk_t *mp; + rtp_header_t *rtp; + + mp=esballoc(buffer,size,BPRI_MED,freefn); + + rtp=(rtp_header_t*)mp->b_rptr; + rtp_header_init_from_session(rtp,session); + return mp; +} + + +int +__rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, uint32_t packet_ts, uint32_t send_ts) +{ + rtp_header_t *rtp; + uint32_t packet_time; + int error = 0; + int packsize; + RtpScheduler *sched=session->sched; + RtpStream *stream=&session->rtp; + + if (session->flags & RTP_SESSION_SEND_NOT_STARTED) + { + session->rtp.snd_ts_offset = send_ts; + /* Set initial last_rcv_time to first send time. */ + if ((session->flags & RTP_SESSION_RECV_NOT_STARTED) + || session->mode == RTP_SESSION_SENDONLY) + { + gettimeofday(&session->last_recv_time, NULL); + } + if (session->flags & RTP_SESSION_SCHEDULED) + { + session->rtp.snd_time_offset = sched->time_; + } + rtp_session_unset_flag (session,RTP_SESSION_SEND_NOT_STARTED); + } + /* if we are in blocking mode, then suspend the process until the scheduler it's time to send the + * next packet */ + /* if the timestamp of the packet queued is older than current time, then you we must + * not block */ + if (session->flags & RTP_SESSION_SCHEDULED) + { + packet_time = + rtp_session_ts_to_time (session, + send_ts - + session->rtp.snd_ts_offset) + + session->rtp.snd_time_offset; + /*ortp_message("rtp_session_send_with_ts: packet_time=%i time=%i",packet_time,sched->time_);*/ + wait_point_lock(&session->snd.wp); + if (TIME_IS_STRICTLY_NEWER_THAN (packet_time, sched->time_)) + { + wait_point_wakeup_at(&session->snd.wp,packet_time,(session->flags & RTP_SESSION_BLOCKING_MODE)!=0); + session_set_clr(&sched->w_sessions,session); /* the session has written */ + } + else session_set_set(&sched->w_sessions,session); /*to indicate select to return immediately */ + wait_point_unlock(&session->snd.wp); + } + + if(mp==NULL) {/*for people who just want to be blocked but + do not want to send anything.*/ + session->rtp.snd_last_ts = packet_ts; + return 0; + } + + rtp=(rtp_header_t*)mp->b_rptr; + + packsize = msgdsize(mp) ; + + rtp->timestamp=packet_ts; + if (session->snd.telephone_events_pt==rtp->paytype) + { + session->rtp.snd_seq++; + rtp->seq_number = session->rtp.snd_seq; + } + else + session->rtp.snd_seq=rtp->seq_number+1; + session->rtp.snd_last_ts = packet_ts; + + + ortp_global_stats.sent += packsize; + stream->sent_payload_bytes+=packsize-RTP_FIXED_HEADER_SIZE; + stream->stats.sent += packsize; + ortp_global_stats.packet_sent++; + stream->stats.packet_sent++; + + error = rtp_session_rtp_send (session, mp); + /*send RTCP packet if needed */ + rtp_session_rtcp_process_send(session); + /* receives rtcp packet if session is send-only*/ + /*otherwise it is done in rtp_session_recvm_with_ts */ + if (session->mode==RTP_SESSION_SENDONLY) rtp_session_rtcp_recv(session); + return error; +} + +/** + * Send the rtp datagram @mp to the destination set by rtp_session_set_remote_addr() + * with timestamp @timestamp. For audio data, the timestamp is the number + * of the first sample resulting of the data transmitted. See rfc1889 for details. + * The packet (@mp) is freed once it is sended. + * + *@param session a rtp session. + *@param mp a rtp packet presented as a mblk_t. + *@param timestamp the timestamp of the data to be sent. + * @return the number of bytes sent over the network. +**/ + +int rtp_session_sendm_with_ts(RtpSession *session, mblk_t *packet, uint32_t timestamp){ + return __rtp_session_sendm_with_ts(session,packet,timestamp,timestamp); +} + + + + +/** + * Send a rtp datagram to the destination set by rtp_session_set_remote_addr() containing + * the data from @buffer with timestamp @userts. This is a high level function that uses + * rtp_session_create_packet() and rtp_session_sendm_with_ts() to send the data. + * + *@param session a rtp session. + *@param buffer a buffer containing the data to be sent in a rtp packet. + *@param len the length of the data buffer, in bytes. + *@param userts the timestamp of the data to be sent. Refer to the rfc to know what it is. + * + *@param return the number of bytes sent over the network. +**/ +int +rtp_session_send_with_ts (RtpSession * session, const uint8_t * buffer, int len, + uint32_t userts) +{ + mblk_t *m; + int err; +#ifdef USE_SENDMSG + m=rtp_session_create_packet_with_data(session,(uint8_t*)buffer,len,NULL); +#else + m = rtp_session_create_packet(session,RTP_FIXED_HEADER_SIZE,(uint8_t*)buffer,len); +#endif + err=rtp_session_sendm_with_ts(session,m,userts); + return err; +} + + + +extern void rtcp_parse(RtpSession *session, mblk_t *mp); + + + +static void payload_type_changed_notify(RtpSession *session, int paytype){ + session->rcv.pt = paytype; + rtp_signal_table_emit (&session->on_payload_type_changed); +} + + +/** + * Try to get a rtp packet presented as a mblk_t structure from the rtp session. + * The @user_ts parameter is relative to the first timestamp of the incoming stream. In other + * words, the application does not have to know the first timestamp of the stream, it can + * simply call for the first time this function with @user_ts=0, and then incrementing it + * as it want. The RtpSession takes care of synchronisation between the stream timestamp + * and the user timestamp given here. + * + * This function returns the entire packet (with header). + * + * The behaviour of this function has changed since version 0.15.0. Previously the payload data could be + * accessed using mblk_t::b_cont::b_rptr field of the returned mblk_t. + * This is no more the case. + * The convenient way of accessing the payload data is to use rtp_get_payload() : + * @code + * unsigned char *payload; + * int payload_size; + * payload_size=rtp_get_payload(mp,&payload); + * @endcode + * OR simply skip the header this way, the data is then comprised between mp->b_rptr and mp->b_wptr: + * @code + * rtp_get_payload(mp,&mp->b_rptr); + * @endcode + * + * + * @param session a rtp session. + * @param user_ts a timestamp. + * + * @return a rtp packet presented as a mblk_t. +**/ + +mblk_t * +rtp_session_recvm_with_ts (RtpSession * session, uint32_t user_ts) +{ + mblk_t *mp = NULL; + rtp_header_t *rtp; + uint32_t ts; + uint32_t packet_time; + RtpScheduler *sched=session->sched; + RtpStream *stream=&session->rtp; + int rejected=0; + bool_t read_socket=TRUE; + + /* if we are scheduled, remember the scheduler time at which the application has + * asked for its first timestamp */ + + if (session->flags & RTP_SESSION_RECV_NOT_STARTED) + { + session->rtp.rcv_query_ts_offset = user_ts; + /* Set initial last_rcv_time to first recv time. */ + if ((session->flags & RTP_SESSION_SEND_NOT_STARTED) + || session->mode == RTP_SESSION_RECVONLY){ + gettimeofday(&session->last_recv_time, NULL); + } + if (session->flags & RTP_SESSION_SCHEDULED) + { + session->rtp.rcv_time_offset = sched->time_; + //ortp_message("setting snd_time_offset=%i",session->rtp.snd_time_offset); + } + rtp_session_unset_flag (session,RTP_SESSION_RECV_NOT_STARTED); + }else{ + /*prevent reading from the sockets when two + consecutives calls for a same timestamp*/ + if (user_ts==session->rtp.rcv_last_app_ts) + read_socket=FALSE; + } + session->rtp.rcv_last_app_ts = user_ts; + if (read_socket){ + rtp_session_rtp_recv (session, user_ts); + rtp_session_rtcp_recv(session); + } + /* check for telephone event first */ + mp=getq(&session->rtp.tev_rq); + if (mp!=NULL){ + int msgsize=msgdsize(mp); + ortp_global_stats.recv += msgsize; + stream->stats.recv += msgsize; + rtp_signal_table_emit2(&session->on_telephone_event_packet,(long)mp); + rtp_session_check_telephone_events(session,mp); + freemsg(mp); + mp=NULL; + } + + /* then now try to return a media packet, if possible */ + /* first condition: if the session is starting, don't return anything + * until the queue size reaches jitt_comp */ + + if (session->flags & RTP_SESSION_RECV_SYNC) + { + queue_t *q = &session->rtp.rq; + if (qempty(q)) + { + ortp_debug ("Queue is empty."); + goto end; + } + rtp = (rtp_header_t *) qfirst(q)->b_rptr; + session->rtp.rcv_ts_offset = rtp->timestamp; + session->rtp.rcv_last_ret_ts = user_ts; /* just to have an init value */ + session->rcv.ssrc = rtp->ssrc; + /* delete the recv synchronisation flag */ + rtp_session_unset_flag (session, RTP_SESSION_RECV_SYNC); + } + + /*calculate the stream timestamp from the user timestamp */ + ts = jitter_control_get_compensated_timestamp(&session->rtp.jittctl,user_ts); + if (session->rtp.jittctl.enabled==TRUE){ + if (session->permissive) + mp = rtp_getq_permissive(&session->rtp.rq, ts,&rejected); + else{ + mp = rtp_getq(&session->rtp.rq, ts,&rejected); + } + }else mp=getq(&session->rtp.rq);/*no jitter buffer at all*/ + + stream->stats.outoftime+=rejected; + ortp_global_stats.outoftime+=rejected; + + goto end; + + end: + if (mp != NULL) + { + int msgsize = msgdsize (mp); /* evaluate how much bytes (including header) is received by app */ + uint32_t packet_ts; + ortp_global_stats.recv += msgsize; + stream->stats.recv += msgsize; + rtp = (rtp_header_t *) mp->b_rptr; + packet_ts=rtp->timestamp; + ortp_debug("Returning mp with ts=%i", packet_ts); + /* check for payload type changes */ + if (session->rcv.pt != rtp->paytype) + { + payload_type_changed_notify(session, rtp->paytype); + } + /* update the packet's timestamp so that it corrected by the + adaptive jitter buffer mechanism */ + if (session->rtp.jittctl.adaptive){ + uint32_t changed_ts; + /* only update correction offset between packets of different + timestamps*/ + if (packet_ts!=session->rtp.rcv_last_ts) + jitter_control_update_corrective_slide(&session->rtp.jittctl); + changed_ts=packet_ts+session->rtp.jittctl.corrective_slide; + rtp->timestamp=changed_ts; + /*ortp_debug("Returned packet has timestamp %u, with clock slide compensated it is %u",packet_ts,rtp->timestamp);*/ + } + session->rtp.rcv_last_ts = packet_ts; + if (!(session->flags & RTP_SESSION_FIRST_PACKET_DELIVERED)){ + rtp_session_set_flag(session,RTP_SESSION_FIRST_PACKET_DELIVERED); + } + } + else + { + ortp_debug ("No mp for timestamp queried"); + stream->stats.unavaillable++; + ortp_global_stats.unavaillable++; + } + rtp_session_rtcp_process_recv(session); + + if (session->flags & RTP_SESSION_SCHEDULED) + { + /* if we are in blocking mode, then suspend the calling process until timestamp + * wanted expires */ + /* but we must not block the process if the timestamp wanted by the application is older + * than current time */ + packet_time = + rtp_session_ts_to_time (session, + user_ts - + session->rtp.rcv_query_ts_offset) + + session->rtp.rcv_time_offset; + ortp_debug ("rtp_session_recvm_with_ts: packet_time=%i, time=%i",packet_time, sched->time_); + wait_point_lock(&session->rcv.wp); + if (TIME_IS_STRICTLY_NEWER_THAN (packet_time, sched->time_)) + { + wait_point_wakeup_at(&session->rcv.wp,packet_time, (session->flags & RTP_SESSION_BLOCKING_MODE)!=0); + session_set_clr(&sched->r_sessions,session); + } + else session_set_set(&sched->r_sessions,session); /*to unblock _select() immediately */ + wait_point_unlock(&session->rcv.wp); + } + return mp; +} + + +/** + * NOTE: use of this function is discouraged when sending payloads other than + * pcm/pcmu/pcma/adpcm types. + * rtp_session_recvm_with_ts() does better job. + * + * Tries to read the bytes of the incoming rtp stream related to timestamp ts. In case + * where the user supplied buffer @buffer is not large enough to get all the data + * related to timestamp ts, then *( have_more) is set to 1 to indicate that the application + * should recall the function with the same timestamp to get more data. + * + * When the rtp session is scheduled (see rtp_session_set_scheduling_mode() ), and the + * blocking mode is on (see rtp_session_set_blocking_mode() ), then the calling thread + * is suspended until the timestamp given as argument expires, whatever a received packet + * fits the query or not. + * + * Important note: it is clear that the application cannot know the timestamp of the first + * packet of the incoming stream, because it can be random. The @ts timestamp given to the + * function is used relatively to first timestamp of the stream. In simple words, 0 is a good + * value to start calling this function. + * + * This function internally calls rtp_session_recvm_with_ts() to get a rtp packet. The content + * of this packet is then copied into the user supplied buffer in an intelligent manner: + * the function takes care of the size of the supplied buffer and the timestamp given in + * argument. Using this function it is possible to read continous audio data (e.g. pcma,pcmu...) + * with for example a standart buffer of size of 160 with timestamp incrementing by 160 while the incoming + * stream has a different packet size. + * + *Returns: if a packet was availlable with the corresponding timestamp supplied in argument + * then the number of bytes written in the user supplied buffer is returned. If no packets + * are availlable, either because the sender has not started to send the stream, or either + * because silence packet are not transmitted, or either because the packet was lost during + * network transport, then the function returns zero. + *@param session a rtp session. + *@param buffer a user supplied buffer to write the data. + *@param len the length in bytes of the user supplied buffer. + *@param ts the timestamp wanted. + *@param have_more the address of an integer to indicate if more data is availlable for the given timestamp. + * +**/ +int rtp_session_recv_with_ts (RtpSession * session, uint8_t * buffer, + int len, uint32_t ts, int * have_more){ + mblk_t *mp=NULL; + int plen,blen=0; + *have_more=0; + while(1){ + if (session->pending){ + mp=session->pending; + session->pending=NULL; + }else { + mp=rtp_session_recvm_with_ts(session,ts); + if (mp!=NULL) rtp_get_payload(mp,&mp->b_rptr); + } + if (mp){ + plen=mp->b_wptr-mp->b_rptr; + if (plen<=len){ + memcpy(buffer,mp->b_rptr,plen); + buffer+=plen; + blen+=plen; + len-=plen; + freemsg(mp); + mp=NULL; + }else{ + memcpy(buffer,mp->b_rptr,len); + mp->b_rptr+=len; + buffer+=len; + blen+=len; + len=0; + session->pending=mp; + *have_more=1; + break; + } + }else break; + } + return blen; +} +/** + * When the rtp session is scheduled and has started to send packets, this function + * computes the timestamp that matches to the present time. Using this function can be + * usefull when sending discontinuous streams. Some time can be elapsed between the end + * of a stream burst and the begin of a new stream burst, and the application may be not + * not aware of this elapsed time. In order to get a valid (current) timestamp to pass to + * #rtp_session_send_with_ts() or #rtp_session_sendm_with_ts(), the application may + * use rtp_session_get_current_send_ts(). + * + * @param session a rtp session. + * @return the current send timestamp for the rtp session. +**/ +uint32_t rtp_session_get_current_send_ts(RtpSession *session) +{ + uint32_t userts; + uint32_t session_time; + RtpScheduler *sched=session->sched; + PayloadType *payload; + payload=rtp_profile_get_payload(session->snd.profile,session->snd.pt); + return_val_if_fail(payload!=NULL, 0); + if ( (session->flags & RTP_SESSION_SCHEDULED)==0 ){ + ortp_warning("can't guess current timestamp because session is not scheduled."); + return 0; + } + session_time=sched->time_-session->rtp.snd_time_offset; + userts= (uint32_t)( ( (double)(session_time) * (double) payload->clock_rate )/ 1000.0) + + session->rtp.snd_ts_offset; + return userts; +} + +/** + * Same thing as rtp_session_get_current_send_ts() except that it's for an incoming stream. + * Works only on scheduled mode. + * + * @param session a rtp session. + * @return the theoritical that would have to be receive now. + * +**/ +uint32_t rtp_session_get_current_recv_ts(RtpSession *session){ + uint32_t userts; + uint32_t session_time; + RtpScheduler *sched=ortp_get_scheduler(); + PayloadType *payload; + payload=rtp_profile_get_payload(session->rcv.profile,session->rcv.pt); + return_val_if_fail(payload!=NULL, 0); + if ( (session->flags & RTP_SESSION_SCHEDULED)==0 ){ + ortp_warning("can't guess current timestamp because session is not scheduled."); + return 0; + } + session_time=sched->time_-session->rtp.rcv_time_offset; + userts= (uint32_t)( ( (double)(session_time) * (double) payload->clock_rate )/ 1000.0) + + session->rtp.rcv_ts_offset; + return userts; +} + +/** + * oRTP has the possibility to inform the application through a callback registered + * with rtp_session_signal_connect about crazy incoming RTP stream that jumps from + * a timestamp N to N+some_crazy_value. This lets the opportunity for the application + * to reset the session in order to resynchronize, or any other action like stopping the call + * and reporting an error. + * @param session the rtp session + * @param ts_step a time interval in miliseconds + * +**/ +void rtp_session_set_time_jump_limit(RtpSession *session, int milisecs){ + uint32_t ts; + session->rtp.time_jump=milisecs; + ts=rtp_session_time_to_ts(session,milisecs); + if (ts==0) session->rtp.ts_jump=1<<31; /* do not detect ts jump */ + else session->rtp.ts_jump=ts; +} + +/** + * Closes the rtp and rtcp sockets. +**/ +void rtp_session_release_sockets(RtpSession *session){ + if (session->rtp.socket>=0) close_socket (session->rtp.socket); + if (session->rtcp.socket>=0) close_socket (session->rtcp.socket); + session->rtp.socket=-1; + session->rtcp.socket=-1; + if (session->rtp.tr!=NULL) + ortp_free(session->rtp.tr); + if (session->rtcp.tr!=NULL) + ortp_free(session->rtcp.tr); + session->rtp.tr = 0; + session->rtcp.tr = 0; + + /* don't discard remote addresses, then can be preserved for next use. + session->rtp.rem_addrlen=0; + session->rtcp.rem_addrlen=0; + */ +} + +ortp_socket_t rtp_session_get_rtp_socket(const RtpSession *session){ + return rtp_session_using_transport(session, rtp) ? (session->rtp.tr->t_getsocket)(session->rtp.tr) : session->rtp.socket; +} + +ortp_socket_t rtp_session_get_rtcp_socket(const RtpSession *session){ + return rtp_session_using_transport(session, rtcp) ? (session->rtcp.tr->t_getsocket)(session->rtcp.tr) : session->rtcp.socket; +} + +/** + * Register an event queue. + * An application can use an event queue to get informed about various RTP events. +**/ +void rtp_session_register_event_queue(RtpSession *session, OrtpEvQueue *q){ + session->eventqs=o_list_append(session->eventqs,q); +} + +void rtp_session_unregister_event_queue(RtpSession *session, OrtpEvQueue *q){ + session->eventqs=o_list_remove(session->eventqs,q); +} + +void rtp_session_dispatch_event(RtpSession *session, OrtpEvent *ev){ + OList *it; + int i; + for(i=0,it=session->eventqs;it!=NULL;it=it->next,++i){ + ortp_ev_queue_put((OrtpEvQueue*)it->data,ortp_event_dup(ev)); + } + ortp_event_destroy(ev); +} + + +void rtp_session_uninit (RtpSession * session) +{ + /* first of all remove the session from the scheduler */ + if (session->flags & RTP_SESSION_SCHEDULED) + { + rtp_scheduler_remove_session (session->sched,session); + } + /*flush all queues */ + flushq(&session->rtp.rq, FLUSHALL); + flushq(&session->rtp.tev_rq, FLUSHALL); + + if (session->eventqs!=NULL) o_list_free(session->eventqs); + /* close sockets */ + rtp_session_release_sockets(session); + + wait_point_uninit(&session->snd.wp); + wait_point_uninit(&session->rcv.wp); + if (session->current_tev!=NULL) freemsg(session->current_tev); + if (session->rtp.cached_mp!=NULL) freemsg(session->rtp.cached_mp); + if (session->rtcp.cached_mp!=NULL) freemsg(session->rtcp.cached_mp); + if (session->sd!=NULL) freemsg(session->sd); + + session->signal_tables = o_list_free(session->signal_tables); + msgb_allocator_uninit(&session->allocator); +} + +/** + * Resynchronize to the incoming RTP streams. + * This can be useful to handle discoutinuous timestamps. + * For example, call this function from the timestamp_jump signal handler. + * @param session the rtp session +**/ +void rtp_session_resync(RtpSession *session){ + flushq (&session->rtp.rq, FLUSHALL); + rtp_session_set_flag(session, RTP_SESSION_RECV_SYNC); + rtp_session_unset_flag(session,RTP_SESSION_FIRST_PACKET_DELIVERED); + jitter_control_init(&session->rtp.jittctl,-1,NULL); +} + +/** + * Reset the session: local and remote addresses are kept. It resets timestamp, sequence + * number, and calls rtp_session_resync(). + * + * @param session a rtp session. +**/ +void rtp_session_reset (RtpSession * session) +{ + rtp_session_set_flag (session, RTP_SESSION_RECV_NOT_STARTED); + rtp_session_set_flag (session, RTP_SESSION_SEND_NOT_STARTED); + //session->ssrc=0; + session->rtp.snd_time_offset = 0; + session->rtp.snd_ts_offset = 0; + session->rtp.snd_rand_offset = 0; + session->rtp.snd_last_ts = 0; + session->rtp.rcv_time_offset = 0; + session->rtp.rcv_ts_offset = 0; + session->rtp.rcv_query_ts_offset = 0; + session->rtp.rcv_last_ts = 0; + session->rtp.rcv_last_app_ts = 0; + session->rtp.hwrcv_extseq = 0; + session->rtp.hwrcv_since_last_SR=0; + session->rtp.snd_seq = 0; + session->rtp.sent_payload_bytes=0; + rtp_session_clear_send_error_code(session); + rtp_session_clear_recv_error_code(session); + rtp_stats_reset(&session->rtp.stats); + rtp_session_resync(session); +} + +/** + * Retrieve the session's statistics. +**/ +const rtp_stats_t * rtp_session_get_stats(const RtpSession *session){ + return &session->rtp.stats; +} + +void rtp_session_reset_stats(RtpSession *session){ + memset(&session->rtp.stats,0,sizeof(rtp_stats_t)); +} + +/** + * Stores some application specific data into the session, so that it is easy to retrieve it from the signal callbacks using rtp_session_get_data(). + * @param session a rtp session + * @param data an opaque pointer to be stored in the session +**/ + +void rtp_session_set_data(RtpSession *session, void *data){ + session->user_data=data; +} + +/** + * @param session a rtp session + * @return the void pointer previously set using rtp_session_set_data() +**/ +void *rtp_session_get_data(const RtpSession *session){ + return session->user_data; +} + +/** + * Enable or disable the "rtp symmetric" hack which consists of the following: + * after the first packet is received, the source address of the packet + * is set to be the destination address for all next packets. + * This is useful to pass-through firewalls. + * @param session a rtp session + * @param yesno a boolean to enable or disable the feature + * +**/ +void +rtp_session_set_symmetric_rtp (RtpSession * session, bool_t yesno) +{ + session->symmetric_rtp =yesno; +} + +/** + * If yesno is TRUE, thus a connect() syscall is done on the socket to + * the destination address set by rtp_session_set_remote_addr(), or + * if the session does symmetric rtp (see rtp_session_set_symmetric_rtp()) + * a the connect() is done to the source address of the first packet received. + * Connecting a socket has effect of rejecting all incoming packets that + * don't come from the address specified in connect(). + * It also makes ICMP errors (such as connection refused) available to the + * application. + * @param session a rtp session + * @param yesno a boolean to enable or disable the feature + * +**/ +void rtp_session_set_connected_mode(RtpSession *session, bool_t yesno){ + session->use_connect=yesno; +} + +static float compute_bw(struct timeval *orig, unsigned int bytes){ + struct timeval current; + float bw; + float time; + if (bytes==0) return 0; + gettimeofday(¤t,NULL); + time=(float)(current.tv_sec - orig->tv_sec) + + ((float)(current.tv_usec - orig->tv_usec)*1e-6); + bw=((float)bytes)*8/(time+0.001); + /*+0.0001 avoids a division by zero without changing the results significatively*/ + return bw; +} + +float rtp_session_compute_recv_bandwidth(RtpSession *session){ + float bw; + bw=compute_bw(&session->rtp.recv_bw_start,session->rtp.recv_bytes); + session->rtp.recv_bytes=0; + return bw; +} + +float rtp_session_compute_send_bandwidth(RtpSession *session){ + float bw; + bw=compute_bw(&session->rtp.send_bw_start,session->rtp.sent_bytes); + session->rtp.sent_bytes=0; + return bw; +} + +int rtp_session_get_last_send_error_code(RtpSession *session){ + return session->rtp.send_errno; +} + +void rtp_session_clear_send_error_code(RtpSession *session){ + session->rtp.send_errno=0; +} + +int rtp_session_get_last_recv_error_code(RtpSession *session){ + return session->rtp.recv_errno; +} + +void rtp_session_clear_recv_error_code(RtpSession *session){ + session->rtp.send_errno=0; +} + +/** + * Destroys a rtp session. + * All memory allocated for the RtpSession is freed. + * + * @param session a rtp session. +**/ +void rtp_session_destroy (RtpSession * session) +{ + rtp_session_uninit (session); + ortp_free (session); +} + +void rtp_session_make_time_distorsion(RtpSession *session, int milisec) +{ + session->rtp.snd_time_offset+=milisec; +} + + +/* packet api */ + +void rtp_add_csrc(mblk_t *mp, uint32_t csrc) +{ + rtp_header_t *hdr=(rtp_header_t*)mp->b_rptr; + hdr->csrc[hdr->cc]=csrc; + hdr->cc++; +} + +/** + * Get a pointer to the beginning of the payload data of the RTP packet. + * @param packet a RTP packet represented as a mblk_t + * @param start a pointer to the beginning of the payload data, pointing inside the packet. + * @return the length of the payload data. +**/ +int rtp_get_payload(mblk_t *packet, unsigned char **start){ + unsigned char *tmp; + int header_len=RTP_FIXED_HEADER_SIZE+(rtp_get_cc(packet)*4); + tmp=packet->b_rptr+header_len; + if (tmp>packet->b_wptr){ + if (packet->b_cont!=NULL){ + tmp=packet->b_cont->b_rptr+(header_len- (packet->b_wptr-packet->b_rptr)); + if (tmp<=packet->b_cont->b_wptr){ + *start=tmp; + return packet->b_cont->b_wptr-tmp; + } + } + ortp_warning("Invalid RTP packet"); + return -1; + } + *start=tmp; + return packet->b_wptr-tmp; +} + + +/** + * Gets last time a valid RTP or RTCP packet was received. + * @param session RtpSession to get last receive time from. + * @param tv Pointer to struct timeval to fill. + * +**/ +void +rtp_session_get_last_recv_time(RtpSession *session, struct timeval *tv) +{ +#ifdef PERF + ortp_error("rtp_session_get_last_recv_time() feature disabled."); +#else + *tv = session->last_recv_time; +#endif +} + + + +uint32_t rtp_session_time_to_ts(RtpSession *session, int millisecs){ + PayloadType *payload; + payload = + rtp_profile_get_payload (session->snd.profile, + session->snd.pt); + if (payload == NULL) + { + ortp_warning + ("rtp_session_ts_to_t: use of unsupported payload type %d.", session->snd.pt); + return 0; + } + /* the return value is in milisecond */ + return (uint32_t) (payload->clock_rate*(double) (millisecs/1000.0f)); +} + +/* function used by the scheduler only:*/ +uint32_t rtp_session_ts_to_time (RtpSession * session, uint32_t timestamp) +{ + PayloadType *payload; + payload = + rtp_profile_get_payload (session->snd.profile, + session->snd.pt); + if (payload == NULL) + { + ortp_warning + ("rtp_session_ts_to_t: use of unsupported payload type %d.", session->snd.pt); + return 0; + } + /* the return value is in milisecond */ + return (uint32_t) (1000.0 * + ((double) timestamp / + (double) payload->clock_rate)); +} + + +/* time is the number of miliseconds elapsed since the start of the scheduler */ +void rtp_session_process (RtpSession * session, uint32_t time, RtpScheduler *sched) +{ + wait_point_lock(&session->snd.wp); + if (wait_point_check(&session->snd.wp,time)){ + session_set_set(&sched->w_sessions,session); + wait_point_wakeup(&session->snd.wp); + } + wait_point_unlock(&session->snd.wp); + + wait_point_lock(&session->rcv.wp); + if (wait_point_check(&session->rcv.wp,time)){ + session_set_set(&sched->r_sessions,session); + wait_point_wakeup(&session->rcv.wp); + } + wait_point_unlock(&session->rcv.wp); +} + diff --git a/linphone/oRTP/src/rtpsession_inet.c b/linphone/oRTP/src/rtpsession_inet.c new file mode 100644 index 000000000..e8e95f4b8 --- /dev/null +++ b/linphone/oRTP/src/rtpsession_inet.c @@ -0,0 +1,1028 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/ortp.h" +#include "utils.h" +#include "ortp/rtpsession.h" +#include "rtpsession_priv.h" + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" /*needed for HAVE_SYS_UIO_H */ +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#define USE_SENDMSG 1 +#endif + +#define can_connect(s) ( (s)->use_connect && !(s)->symmetric_rtp) + +static bool_t try_connect(int fd, const struct sockaddr *dest, socklen_t addrlen){ + if (connect(fd,dest,addrlen)<0){ + ortp_warning("Could not connect() socket: %s",getSocketError()); + return FALSE; + } + return TRUE; +} + +static ortp_socket_t create_and_bind(const char *addr, int port, int *sock_family, bool_t reuse_addr){ + int err; + int optval = 1; + ortp_socket_t sock=-1; +#ifdef ORTP_INET6 + char num[8]; + struct addrinfo hints, *res0, *res; +#else + struct sockaddr_in saddr; +#endif + +#ifdef ORTP_INET6 + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + snprintf(num, sizeof(num), "%d",port); + err = getaddrinfo(addr,num, &hints, &res0); + if (err!=0) { + ortp_warning ("Error in getaddrinfo on (addr=%s port=%i): %s", addr, port, gai_strerror(err)); + return -1; + } + + for (res = res0; res; res = res->ai_next) { + sock = socket(res->ai_family, res->ai_socktype, 0); + if (sock < 0) + continue; + if (reuse_addr){ + err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (SOCKET_OPTION_VALUE)&optval, sizeof (optval)); + if (err < 0) + { + ortp_warning ("Fail to set rtp address reusable: %s.", getSocketError()); + } + } + + *sock_family=res->ai_family; + err = bind (sock, res->ai_addr, res->ai_addrlen); + if (err != 0) + { + ortp_warning ("Fail to bind rtp socket to (addr=%s port=%i) : %s.", addr,port, getSocketError()); + close_socket (sock); + sock=-1; + continue; + } +#ifndef __hpux + switch (res->ai_family) + { + case AF_INET: + if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr))) + { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr; + mreq.imr_interface.s_addr = INADDR_ANY; + err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (SOCKET_OPTION_VALUE) &mreq, sizeof(mreq)); + if (err < 0) + { + ortp_warning ("Fail to join address group: %s.", getSocketError()); + close_socket (sock); + sock=-1; + continue; + } + } + break; + case AF_INET6: + if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr))) + { + struct ipv6_mreq mreq; + mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; + mreq.ipv6mr_interface = 0; + err = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (SOCKET_OPTION_VALUE)&mreq, sizeof(mreq)); + if (err < 0) + { + ortp_warning ("Fail to join address group: %s.", getSocketError()); + close_socket (sock); + sock=-1; + continue; + } + } + break; + } +#endif /*hpux*/ + break; + } + freeaddrinfo(res0); +#else + saddr.sin_family = AF_INET; + *sock_family=AF_INET; + err = inet_aton (addr, &saddr.sin_addr); + if (err < 0) + { + ortp_warning ("Error in socket address:%s.", getSocketError()); + return err; + } + saddr.sin_port = htons (port); + + sock = socket (PF_INET, SOCK_DGRAM, 0); + + if (sock<0) return -1; + if (reuse_addr){ + err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (SOCKET_OPTION_VALUE)&optval, sizeof (optval)); + if (err < 0) + { + ortp_warning ("Fail to set rtp address reusable: %s.",getSocketError()); + } + } + + err = bind (sock, + (struct sockaddr *) &saddr, + sizeof (saddr)); + + if (err != 0) + { + ortp_warning ("Fail to bind rtp socket to port %i: %s.", port, getSocketError()); + close_socket (sock); + return -1; + } +#endif + if (sock>=0){ + set_non_blocking_socket (sock); + } + return sock; +} + +static void set_socket_sizes(int sock, unsigned int sndbufsz, unsigned int rcvbufsz){ + int err; + bool_t done=FALSE; + if (sndbufsz>0){ +#ifdef SO_SNDBUFFORCE + err = setsockopt(sock, SOL_SOCKET, SO_SNDBUFFORCE, (void *)&sndbufsz, sizeof(sndbufsz)); + if (err == -1) { + ortp_error("Fail to increase socket's send buffer size with SO_SNDBUFFORCE: %s.", getSocketError()); + }else done=TRUE; +#endif + if (!done){ + err = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&sndbufsz, sizeof(sndbufsz)); + if (err == -1) { + ortp_error("Fail to increase socket's send buffer size with SO_SNDBUF: %s.", getSocketError()); + } + } + } + done=FALSE; + if (rcvbufsz>0){ +#ifdef SO_RCVBUFFORCE + err = setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, (void *)&rcvbufsz, sizeof(rcvbufsz)); + if (err == -1) { + ortp_error("Fail to increase socket's recv buffer size with SO_RCVBUFFORCE: %s.", getSocketError()); + } +#endif + if (!done){ + err = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbufsz, sizeof(rcvbufsz)); + if (err == -1) { + ortp_error("Fail to increase socket's recv buffer size with SO_RCVBUF: %s.", getSocketError()); + } + } + + } +} + +static ortp_socket_t create_and_bind_random(const char *localip, int *sock_family, int *port){ + int retry; + ortp_socket_t sock = -1; + for (retry=0;retry<100;retry++) + { + int localport; + do + { + localport = (rand () + 5000) & 0xfffe; + } + while ((localport < 5000) || (localport > 0xffff)); + /*do not set REUSEADDR in case of random allocation */ + sock = create_and_bind(localip, localport, sock_family,FALSE); + if (sock>=0) { + *port=localport; + return sock; + } + } + ortp_warning("create_and_bind_random: Could not find a random port for %s !",localip); + return -1; +} + +/** + *rtp_session_set_local_addr: + *@session: a rtp session freshly created. + *@addr: a local IP address in the xxx.xxx.xxx.xxx form. + *@port: a local port or -1 to let oRTP choose the port randomly + * + * Specify the local addr to be use to listen for rtp packets or to send rtp packet from. + * In case where the rtp session is send-only, then it is not required to call this function: + * when calling rtp_session_set_remote_addr(), if no local address has been set, then the + * default INADRR_ANY (0.0.0.0) IP address with a random port will be used. Calling + * rtp_sesession_set_local_addr() is mandatory when the session is recv-only or duplex. + * + * Returns: 0 on success. +**/ + +int +rtp_session_set_local_addr (RtpSession * session, const char * addr, int port) +{ + ortp_socket_t sock; + int sockfamily; + if (session->rtp.socket>=0){ + /* don't rebind, but close before*/ + rtp_session_release_sockets(session); + } + /* try to bind the rtp port */ + if (port>0) + sock=create_and_bind(addr,port,&sockfamily,TRUE); + else + sock=create_and_bind_random(addr,&sockfamily,&port); + if (sock>=0){ + set_socket_sizes(sock,session->rtp.snd_socket_size,session->rtp.rcv_socket_size); + session->rtp.sockfamily=sockfamily; + session->rtp.socket=sock; + session->rtp.loc_port=port; + /*try to bind rtcp port */ + sock=create_and_bind(addr,port+1,&sockfamily,TRUE); + if (sock>=0){ + session->rtcp.sockfamily=sockfamily; + session->rtcp.socket=sock; + }else{ + ortp_warning("Could not create and bind rtcp socket."); + } + + /* set socket options (but don't change chosen states) */ + rtp_session_set_dscp( session, -1 ); + rtp_session_set_multicast_ttl( session, -1 ); + rtp_session_set_multicast_loopback( session, -1 ); + + return 0; + } + return -1; +} + + +/** + *rtp_session_set_multicast_ttl: + *@session: a rtp session + *@ttl: desired Multicast Time-To-Live + * + * Sets the TTL (Time-To-Live) for outgoing multicast packets. + * + * Returns: 0 on success. + * +**/ +int rtp_session_set_multicast_ttl(RtpSession *session, int ttl) +{ + int retval; + + // Store new TTL if one is specified + if (ttl>0) session->multicast_ttl = ttl; + + // Don't do anything if socket hasn't been created yet + if (session->rtp.socket < 0) return 0; + + switch (session->rtp.sockfamily) { + case AF_INET: { + + retval= setsockopt(session->rtp.socket, IPPROTO_IP, IP_MULTICAST_TTL, + (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl)); + + if (retval<0) break; + + retval= setsockopt(session->rtcp.socket, IPPROTO_IP, IP_MULTICAST_TTL, + (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl)); + + } break; + + case AF_INET6: { + + retval= setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + (SOCKET_OPTION_VALUE)&session->multicast_ttl, sizeof(session->multicast_ttl)); + + if (retval<0) break; + + retval= setsockopt(session->rtcp.socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl)); + + } break; + + default: + retval=-1; + } + + if (retval<0) + ortp_warning("Failed to set multicast TTL on socket."); + + + return retval; +} + + +/** + *rtp_session_get_multicast_ttl: + *@session: a rtp session + * + * Returns the TTL (Time-To-Live) for outgoing multicast packets. + * +**/ +int rtp_session_get_multicast_ttl(RtpSession *session) +{ + return session->multicast_ttl; +} + + +/** + *rtp_session_set_multicast_loopback: + *@session: a rtp session + *@ttl: desired Multicast Time-To-Live + * + * Sets the TTL (Time-To-Live) for outgoing multicast packets. + * + * Returns: 0 on success. + * +**/ +int rtp_session_set_multicast_loopback(RtpSession *session, int yesno) +{ + int retval; + + // Store new loopback state if one is specified + if (yesno==0) { + // Don't loop back + session->multicast_loopback = 0; + } else if (yesno>0) { + // Do loop back + session->multicast_loopback = 1; + } + + // Don't do anything if socket hasn't been created yet + if (session->rtp.socket < 0) return 0; + + switch (session->rtp.sockfamily) { + case AF_INET: { + + retval= setsockopt(session->rtp.socket, IPPROTO_IP, IP_MULTICAST_LOOP, + (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback)); + + if (retval<0) break; + + retval= setsockopt(session->rtcp.socket, IPPROTO_IP, IP_MULTICAST_LOOP, + (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback)); + + } break; + + case AF_INET6: { + + retval= setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback)); + + if (retval<0) break; + + retval= setsockopt(session->rtcp.socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback)); + + } break; + + default: + retval=-1; + } + + if (retval<0) + ortp_warning("Failed to set multicast loopback on socket."); + + + return retval; +} + + +/** + *rtp_session_get_multicast_loopback: + *@session: a rtp session + * + * Returns the multicast loopback state of rtp session (true or false). + * +**/ +int rtp_session_get_multicast_loopback(RtpSession *session) +{ + return session->multicast_loopback; +} + +/** + *rtp_session_set_dscp: + *@session: a rtp session + *@dscp: desired DSCP PHB value + * + * Sets the DSCP (Differentiated Services Code Point) for outgoing RTP packets. + * + * Returns: 0 on success. + * +**/ +int rtp_session_set_dscp(RtpSession *session, int dscp){ + int retval=0; + int tos; + + // Store new DSCP value if one is specified + if (dscp>=0) session->dscp = dscp; + + // Don't do anything if socket hasn't been created yet + if (session->rtp.socket < 0) return 0; + + // DSCP value is in the upper six bits of the TOS field + tos = (session->dscp << 2) & 0xFC; + switch (session->rtp.sockfamily) { + case AF_INET: + retval = setsockopt(session->rtp.socket, IPPROTO_IP, IP_TOS, (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); + break; +#ifdef ORTP_INET6 + case AF_INET6: +# ifdef IPV6_TCLASS /*seems not defined by my libc*/ + retval = setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_TCLASS, + (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); +# else + /*in case that works:*/ + retval = setsockopt(session->rtp.socket, IPPROTO_IPV6, IP_TOS, + (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); +#endif + break; +#endif + default: + retval=-1; + } + if (retval<0) + ortp_warning("Failed to set DSCP value on socket."); + + return retval; +} + + +/** + *rtp_session_get_dscp: + *@session: a rtp session + * + * Returns the DSCP (Differentiated Services Code Point) for outgoing RTP packets. + * +**/ +int rtp_session_get_dscp(const RtpSession *session) +{ + return session->dscp; +} + + +/** + *rtp_session_get_local_port: + *@session: a rtp session for which rtp_session_set_local_addr() or rtp_session_set_remote_addr() has been called + * + * This function can be useful to retrieve the local port that was randomly choosen by + * rtp_session_set_remote_addr() when rtp_session_set_local_addr() was not called. + * + * Returns: the local port used to listen for rtp packets, -1 if not set. +**/ + +int rtp_session_get_local_port(const RtpSession *session){ + return (session->rtp.loc_port>0) ? session->rtp.loc_port : -1; +} + + +static char * ortp_inet_ntoa(struct sockaddr *addr, int addrlen, char *dest, int destlen){ +#ifdef ORTP_INET6 + int err; + dest[0]=0; + err=getnameinfo(addr,addrlen,dest,destlen,NULL,0,NI_NUMERICHOST); + if (err!=0){ + ortp_warning("getnameinfo error: %s",gai_strerror(err)); + } +#else + char *tmp=inet_ntoa(((struct sockaddr_in*)addr)->sin_addr); + strncpy(dest,tmp,destlen); + dest[destlen-1]='\0'; +#endif + return dest; +} + +/** + *rtp_session_set_remote_addr: + *@session: a rtp session freshly created. + *@addr: a local IP address in the xxx.xxx.xxx.xxx form. + *@port: a local port. + * + * Sets the remote address of the rtp session, ie the destination address where rtp packet + * are sent. If the session is recv-only or duplex, it also sets the origin of incoming RTP + * packets. Rtp packets that don't come from addr:port are discarded. + * + * Returns: 0 on success. +**/ +int +rtp_session_set_remote_addr (RtpSession * session, const char * addr, int port){ + return rtp_session_set_remote_addr_full (session, addr, port, port+1); +} + +/** + *rtp_session_set_remote_addr_full: + *@session: a rtp session freshly created. + *@addr: a local IP address in the xxx.xxx.xxx.xxx form. + *@rtp_port: a local rtp port. + *@rtcp_port: a local rtcp port. + * + * Sets the remote address of the rtp session, ie the destination address where rtp packet + * are sent. If the session is recv-only or duplex, it also sets the origin of incoming RTP + * packets. Rtp packets that don't come from addr:port are discarded. + * + * Returns: 0 on success. +**/ + +int +rtp_session_set_remote_addr_full (RtpSession * session, const char * addr, int rtp_port, int rtcp_port) +{ + int err; +#ifdef ORTP_INET6 + struct addrinfo hints, *res0, *res; + char num[8]; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + snprintf(num, sizeof(num), "%d", rtp_port); + err = getaddrinfo(addr, num, &hints, &res0); + if (err) { + ortp_warning ("Error in socket address: %s", gai_strerror(err)); + return -1; + } +#endif + if (session->rtp.socket == -1){ + /* the session has not its socket bound, do it */ + ortp_message ("Setting random local addresses."); +#ifdef ORTP_INET6 + /* bind to an address type that matches the destination address */ + if (res0->ai_addr->sa_family==AF_INET6) + err = rtp_session_set_local_addr (session, "::", -1); + else err=rtp_session_set_local_addr (session, "0.0.0.0", -1); +#else + err = rtp_session_set_local_addr (session, "0.0.0.0", -1); +#endif + if (err<0) return -1; + } + +#ifdef ORTP_INET6 + err=1; + for (res = res0; res; res = res->ai_next) { + /* set a destination address that has the same type as the local address */ + if (res->ai_family==session->rtp.sockfamily ) { + memcpy( &session->rtp.rem_addr, res->ai_addr, res->ai_addrlen); + session->rtp.rem_addrlen=res->ai_addrlen; + err=0; + break; + } + } + freeaddrinfo(res0); + if (err) { + ortp_warning("Could not set destination for RTP socket to %s:%i.",addr,rtp_port); + return -1; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + snprintf(num, sizeof(num), "%d", rtcp_port); + err = getaddrinfo(addr, num, &hints, &res0); + if (err) { + ortp_warning ("Error: %s", gai_strerror(err)); + return err; + } + err=1; + for (res = res0; res; res = res->ai_next) { + /* set a destination address that has the same type as the local address */ + if (res->ai_family==session->rtp.sockfamily ) { + err=0; + memcpy( &session->rtcp.rem_addr, res->ai_addr, res->ai_addrlen); + session->rtcp.rem_addrlen=res->ai_addrlen; + break; + } + } + freeaddrinfo(res0); + if (err) { + ortp_warning("Could not set destination for RCTP socket to %s:%i.",addr,rtcp_port); + return -1; + } +#else + session->rtp.rem_addrlen=sizeof(session->rtp.rem_addr); + session->rtp.rem_addr.sin_family = AF_INET; + + err = inet_aton (addr, &session->rtp.rem_addr.sin_addr); + if (err < 0) + { + ortp_warning ("Error in socket address:%s.", getSocketError()); + return err; + } + session->rtp.rem_addr.sin_port = htons (rtp_port); + + memcpy (&session->rtcp.rem_addr, &session->rtp.rem_addr, + sizeof (struct sockaddr_in)); + session->rtcp.rem_addr.sin_port = htons (rtcp_port); + session->rtcp.rem_addrlen=sizeof(session->rtcp.rem_addr); +#endif + if (can_connect(session)){ + if (try_connect(session->rtp.socket,(struct sockaddr*)&session->rtp.rem_addr,session->rtp.rem_addrlen)) + session->flags|=RTP_SOCKET_CONNECTED; + if (session->rtcp.socket>=0){ + if (try_connect(session->rtcp.socket,(struct sockaddr*)&session->rtcp.rem_addr,session->rtcp.rem_addrlen)) + session->flags|=RTCP_SOCKET_CONNECTED; + } + }else if (session->flags & RTP_SOCKET_CONNECTED){ + /*must dissolve association done by connect(). + See connect(2) manpage*/ + struct sockaddr sa; + sa.sa_family=AF_UNSPEC; + if (connect(session->rtp.socket,&sa,sizeof(sa))<0){ + ortp_error("Cannot dissolve connect() association for rtp socket: %s", getSocketError()); + } + if (connect(session->rtcp.socket,&sa,sizeof(sa))<0){ + ortp_error("Cannot dissolve connect() association for rtcp socket: %s", getSocketError()); + } + session->flags&=~RTP_SOCKET_CONNECTED; + session->flags&=~RTCP_SOCKET_CONNECTED; + } + return 0; +} + +int +rtp_session_set_remote_addr_and_port(RtpSession * session, const char * addr, int rtp_port, int rtcp_port){ + return rtp_session_set_remote_addr_full(session,addr,rtp_port,rtcp_port); +} + +void rtp_session_set_sockets(RtpSession *session, int rtpfd, int rtcpfd) +{ + if (rtpfd>=0) set_non_blocking_socket(rtpfd); + if (rtcpfd>=0) set_non_blocking_socket(rtcpfd); + session->rtp.socket=rtpfd; + session->rtcp.socket=rtcpfd; + if (rtpfd>=0 || rtcpfd>=0 ) + session->flags|=(RTP_SESSION_USING_EXT_SOCKETS|RTP_SOCKET_CONNECTED|RTCP_SOCKET_CONNECTED); + else session->flags&=~(RTP_SESSION_USING_EXT_SOCKETS|RTP_SOCKET_CONNECTED|RTCP_SOCKET_CONNECTED); +} + +void rtp_session_set_transports(RtpSession *session, struct _RtpTransport *rtptr, struct _RtpTransport *rtcptr) +{ + session->rtp.tr = rtptr; + session->rtcp.tr = rtcptr; + if (rtptr) + rtptr->session=session; + if (rtcptr) + rtcptr->session=session; + + if (rtptr || rtcptr ) + session->flags|=(RTP_SESSION_USING_TRANSPORT); + else session->flags&=~(RTP_SESSION_USING_TRANSPORT); +} + + + +/** + *rtp_session_flush_sockets: + *@session: a rtp session + * + * Flushes the sockets for all pending incoming packets. + * This can be usefull if you did not listen to the stream for a while + * and wishes to start to receive again. During the time no receive is made + * packets get bufferised into the internal kernel socket structure. + * +**/ +void rtp_session_flush_sockets(RtpSession *session){ + unsigned char trash[4096]; +#ifdef ORTP_INET6 + struct sockaddr_storage from; +#else + struct sockaddr from; +#endif + socklen_t fromlen=sizeof(from); + if (rtp_session_using_transport(session, rtp)) + { + mblk_t *trashmp=esballoc(trash,sizeof(trash),0,NULL); + + while (session->rtp.tr->t_recvfrom(session->rtp.tr,trashmp,0,(struct sockaddr *)&from,&fromlen)>0){}; + + if (session->rtcp.tr) + while (session->rtcp.tr->t_recvfrom(session->rtcp.tr,trashmp,0,(struct sockaddr *)&from,&fromlen)>0){}; + freemsg(trashmp); + return; + } + + if (session->rtp.socket>=0){ + while (recvfrom(session->rtp.socket,trash,sizeof(trash),0,(struct sockaddr *)&from,&fromlen)>0){}; + } + if (session->rtcp.socket>=0){ + while (recvfrom(session->rtcp.socket,trash,sizeof(trash),0,(struct sockaddr*)&from,&fromlen)>0){}; + } +} + + +#ifdef USE_SENDMSG +#define MAX_IOV 30 +static int rtp_sendmsg(int sock,mblk_t *m, struct sockaddr *rem_addr, int addr_len){ + int error; + struct msghdr msg; + struct iovec iov[MAX_IOV]; + int iovlen; + for(iovlen=0; iovlenb_cont,iovlen++){ + iov[iovlen].iov_base=m->b_rptr; + iov[iovlen].iov_len=m->b_wptr-m->b_rptr; + } + if (iovlen==MAX_IOV){ + ortp_error("Too long msgb, didn't fit into iov, end discarded."); + } + msg.msg_name=(void*)rem_addr; + msg.msg_namelen=addr_len; + msg.msg_iov=&iov[0]; + msg.msg_iovlen=iovlen; + msg.msg_control=NULL; + msg.msg_controllen=0; + msg.msg_flags=0; + error=sendmsg(sock,&msg,0); + return error; +} +#endif + +#define IP_UDP_OVERHEAD (20+8) + +static void update_sent_bytes(RtpSession*s, int nbytes){ + if (s->rtp.sent_bytes==0){ + gettimeofday(&s->rtp.send_bw_start,NULL); + } + s->rtp.sent_bytes+=nbytes+IP_UDP_OVERHEAD; +} + +static void update_recv_bytes(RtpSession*s, int nbytes){ + if (s->rtp.recv_bytes==0){ + gettimeofday(&s->rtp.recv_bw_start,NULL); + } + s->rtp.recv_bytes+=nbytes+IP_UDP_OVERHEAD; +} + +int +rtp_session_rtp_send (RtpSession * session, mblk_t * m) +{ + int error; + int i; + rtp_header_t *hdr; + struct sockaddr *destaddr=(struct sockaddr*)&session->rtp.rem_addr; + socklen_t destlen=session->rtp.rem_addrlen; + ortp_socket_t sockfd=session->rtp.socket; + + hdr = (rtp_header_t *) m->b_rptr; + /* perform host to network conversions */ + hdr->ssrc = htonl (hdr->ssrc); + hdr->timestamp = htonl (hdr->timestamp); + hdr->seq_number = htons (hdr->seq_number); + for (i = 0; i < hdr->cc; i++) + hdr->csrc[i] = htonl (hdr->csrc[i]); + + if (session->flags & RTP_SOCKET_CONNECTED) { + destaddr=NULL; + destlen=0; + } + + if (rtp_session_using_transport(session, rtp)){ + error = (session->rtp.tr->t_sendto) (session->rtp.tr,m,0,destaddr,destlen); + }else{ +#ifdef USE_SENDMSG + error=rtp_sendmsg(sockfd,m,destaddr,destlen); +#else + if (m->b_cont!=NULL) + msgpullup(m,-1); + error = sendto (sockfd, m->b_rptr, (int) (m->b_wptr - m->b_rptr), + 0,destaddr,destlen); +#endif + } + if (error < 0){ + if (session->on_network_error.count>0){ + rtp_signal_table_emit3(&session->on_network_error,(long)"Error sending RTP packet",INT_TO_POINTER(getSocketErrorCode())); + }else ortp_warning ("Error sending rtp packet: %s ; socket=%i", getSocketError(), sockfd); + session->rtp.send_errno=getSocketErrorCode(); + }else{ + update_sent_bytes(session,error); + } + freemsg (m); + return error; +} + +int +rtp_session_rtcp_send (RtpSession * session, mblk_t * m) +{ + int error=0; + ortp_socket_t sockfd=session->rtcp.socket; + struct sockaddr *destaddr=(struct sockaddr*)&session->rtcp.rem_addr; + socklen_t destlen=session->rtcp.rem_addrlen; + bool_t using_connected_socket=(session->flags & RTCP_SOCKET_CONNECTED)!=0; + + if (using_connected_socket) { + destaddr=NULL; + destlen=0; + } + + if (session->rtcp.enabled && + ( (sockfd>=0 && (session->rtcp.rem_addrlen>0 ||using_connected_socket)) + || rtp_session_using_transport(session, rtcp) ) ){ + if (rtp_session_using_transport(session, rtcp)){ + error = (session->rtcp.tr->t_sendto) (session->rtcp.tr, m, 0, + destaddr, destlen); + } + else{ +#ifdef USE_SENDMSG + error=rtp_sendmsg(sockfd,m,destaddr, destlen); +#else + if (m->b_cont!=NULL){ + msgpullup(m,-1); + } + error = sendto (sockfd, m->b_rptr, + (int) (m->b_wptr - m->b_rptr), 0, + destaddr, destlen); +#endif + } + if (error < 0){ + char host[65]; + if (session->on_network_error.count>0){ + rtp_signal_table_emit3(&session->on_network_error,(long)"Error sending RTCP packet",INT_TO_POINTER(getSocketErrorCode())); + }else ortp_warning ("Error sending rtcp packet: %s ; socket=%i; addr=%s", getSocketError(), session->rtcp.socket, ortp_inet_ntoa((struct sockaddr*)&session->rtcp.rem_addr,session->rtcp.rem_addrlen,host,sizeof(host)) ); + } + }else ortp_message("Not sending rtcp report: sockfd=%i, rem_addrlen=%i, connected=%i",sockfd,session->rtcp.rem_addrlen,using_connected_socket); + freemsg (m); + return error; +} + +int +rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts) +{ + int error; + ortp_socket_t sockfd=session->rtp.socket; +#ifdef ORTP_INET6 + struct sockaddr_storage remaddr; +#else + struct sockaddr remaddr; +#endif + socklen_t addrlen = sizeof (remaddr); + mblk_t *mp; + + if ((sockfd<0) && !rtp_session_using_transport(session, rtp)) return -1; /*session has no sockets for the moment*/ + + while (1) + { + int bufsz; + bool_t sock_connected=!!(session->flags & RTP_SOCKET_CONNECTED); + + if (session->rtp.cached_mp==NULL) + session->rtp.cached_mp = msgb_allocator_alloc(&session->allocator,session->recv_buf_size); + mp=session->rtp.cached_mp; + bufsz=(int) (mp->b_datap->db_lim - mp->b_datap->db_base); + if (sock_connected){ + error=recv(sockfd,mp->b_wptr,bufsz,0); + }else if (rtp_session_using_transport(session, rtp)) + error = (session->rtp.tr->t_recvfrom)(session->rtp.tr, mp, 0, + (struct sockaddr *) &remaddr, + &addrlen); + else error = recvfrom(sockfd, mp->b_wptr, + bufsz, 0, + (struct sockaddr *) &remaddr, + &addrlen); + if (error > 0){ + if (session->symmetric_rtp && !sock_connected){ + /* store the sender rtp address to do symmetric RTP */ + memcpy(&session->rtp.rem_addr,&remaddr,addrlen); + session->rtp.rem_addrlen=addrlen; + if (session->use_connect){ + if (try_connect(sockfd,(struct sockaddr*)&remaddr,addrlen)) + session->flags|=RTP_SOCKET_CONNECTED; + } + } + /* then parse the message and put on queue */ + mp->b_wptr+=error; + rtp_session_rtp_parse (session, mp, user_ts, (struct sockaddr*)&remaddr,addrlen); + session->rtp.cached_mp=NULL; + /*for bandwidth measurements:*/ + update_recv_bytes(session,error); + } + else + { + int errnum=getSocketErrorCode(); + + if (error == 0) + { + ortp_warning + ("rtp_recv: strange... recv() returned zero."); + } + else if (!is_would_block_error(errnum)) + { + if (session->on_network_error.count>0){ + rtp_signal_table_emit3(&session->on_network_error,(long)"Error receiving RTP packet",INT_TO_POINTER(getSocketErrorCode())); + }else ortp_warning("Error receiving RTP packet: %s.",getSocketError()); + } + /* don't free the cached_mp, it will be reused next time */ + return -1; /* avoids an infinite loop ! */ + } + } + return error; +} + +void rtp_session_notify_inc_rtcp(RtpSession *session, mblk_t *m){ + if (session->eventqs!=NULL){ + OrtpEvent *ev=ortp_event_new(ORTP_EVENT_RTCP_PACKET_RECEIVED); + OrtpEventData *d=ortp_event_get_data(ev); + d->packet=m; + rtp_session_dispatch_event(session,ev); + } + else freemsg(m); /* avoid memory leak */ +} + +int +rtp_session_rtcp_recv (RtpSession * session) +{ + int error; +#ifdef ORTP_INET6 + struct sockaddr_storage remaddr; +#else + struct sockaddr remaddr; +#endif + socklen_t addrlen=0; + mblk_t *mp; + + if (session->rtcp.socket<0 && !rtp_session_using_transport(session, rtcp)) return -1; /*session has no rtcp sockets for the moment*/ + + + while (1) + { + bool_t sock_connected=!!(session->flags & RTCP_SOCKET_CONNECTED); + if (session->rtcp.cached_mp==NULL) + session->rtcp.cached_mp = allocb (RTCP_MAX_RECV_BUFSIZE, 0); + + mp=session->rtcp.cached_mp; + if (sock_connected){ + error=recv(session->rtcp.socket,mp->b_wptr,RTCP_MAX_RECV_BUFSIZE,0); + }else { + addrlen=sizeof (remaddr); + + if (rtp_session_using_transport(session, rtcp)) + error=(session->rtcp.tr->t_recvfrom)(session->rtcp.tr, mp, 0, + (struct sockaddr *) &remaddr, + &addrlen); + else + error=recvfrom (session->rtcp.socket, mp->b_wptr, + RTCP_MAX_RECV_BUFSIZE, 0, + (struct sockaddr *) &remaddr, + &addrlen); + } + if (error > 0) + { + mp->b_wptr += error; + /* post an event to notify the application*/ + { + rtp_session_notify_inc_rtcp(session,mp); + } + session->rtcp.cached_mp=NULL; + if (session->symmetric_rtp && !sock_connected){ + /* store the sender rtp address to do symmetric RTP */ + memcpy(&session->rtcp.rem_addr,&remaddr,addrlen); + session->rtcp.rem_addrlen=addrlen; + if (session->use_connect){ + if (try_connect(session->rtcp.socket,(struct sockaddr*)&remaddr,addrlen)) + session->flags|=RTCP_SOCKET_CONNECTED; + } + } + } + else + { + int errnum=getSocketErrorCode(); + + if (error == 0) + { + ortp_warning + ("rtcp_recv: strange... recv() returned zero."); + } + else if (!is_would_block_error(errnum)) + { + if (session->on_network_error.count>0){ + rtp_signal_table_emit3(&session->on_network_error,(long)"Error receiving RTCP packet",INT_TO_POINTER(errnum)); + }else ortp_warning("Error receiving RTCP packet: %s.",getSocketError()); + session->rtp.recv_errno=errnum; + } + /* don't free the cached_mp, it will be reused next time */ + return -1; /* avoids an infinite loop ! */ + } + } + return error; +} + diff --git a/linphone/oRTP/src/rtpsession_priv.h b/linphone/oRTP/src/rtpsession_priv.h new file mode 100644 index 000000000..24e955669 --- /dev/null +++ b/linphone/oRTP/src/rtpsession_priv.h @@ -0,0 +1,54 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef rtpsession_priv_h +#define rtpsession_priv_h + +#include "ortp/rtpsession.h" + +typedef enum { + RTP_SESSION_RECV_SYNC=1, /* the rtp session is synchronising in the incoming stream */ + RTP_SESSION_FIRST_PACKET_DELIVERED=1<<1, + RTP_SESSION_SCHEDULED=1<<2,/* the scheduler controls this session*/ + RTP_SESSION_BLOCKING_MODE=1<<3, /* in blocking mode */ + RTP_SESSION_RECV_NOT_STARTED=1<<4, /* the application has not started to try to recv */ + RTP_SESSION_SEND_NOT_STARTED=1<<5, /* the application has not started to send something */ + RTP_SESSION_IN_SCHEDULER=1<<6, /* the rtp session is in the scheduler list */ + RTP_SESSION_USING_EXT_SOCKETS=1<<7, /* the session is using externaly supplied sockets */ + RTP_SOCKET_CONNECTED=1<<8, + RTCP_SOCKET_CONNECTED=1<<9, + RTP_SESSION_USING_TRANSPORT=1<<10 +}RtpSessionFlags; + +#define rtp_session_using_transport(s, stream) (((s)->flags & RTP_SESSION_USING_TRANSPORT) && (s->stream.tr != 0)) + +void rtp_session_update_payload_type(RtpSession * session, int pt); +void rtp_putq(queue_t *q, mblk_t *mp); +mblk_t * rtp_getq(queue_t *q, uint32_t ts, int *rejected); +int rtp_session_rtp_recv(RtpSession * session, uint32_t ts); +int rtp_session_rtcp_recv(RtpSession * session); +int rtp_session_rtp_send (RtpSession * session, mblk_t * m); +int rtp_session_rtcp_send (RtpSession * session, mblk_t * m); + +void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, struct sockaddr *addr, socklen_t addrlen); +void rtp_session_rtcp_parse(RtpSession *session, mblk_t *mp); + +void rtp_session_dispatch_event(RtpSession *session, OrtpEvent *ev); + +#endif diff --git a/linphone/oRTP/src/rtpsignaltable.c b/linphone/oRTP/src/rtpsignaltable.c new file mode 100644 index 000000000..14d8587b9 --- /dev/null +++ b/linphone/oRTP/src/rtpsignaltable.c @@ -0,0 +1,98 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + + +#include +#include "utils.h" + + +void rtp_signal_table_init(RtpSignalTable *table,RtpSession *session, const char *signal_name) +{ + memset(table,0,sizeof(RtpSignalTable)); + table->session=session; + table->signal_name=signal_name; + session->signal_tables=o_list_append(session->signal_tables,(void*)table); +} + +int rtp_signal_table_add(RtpSignalTable *table,RtpCallback cb, unsigned long user_data) +{ + int i; + + for (i=0;icallback[i]==NULL){ + table->callback[i]=cb; + table->user_data[i]=user_data; + table->count++; + return 0; + } + } + return -1; +} + +void rtp_signal_table_emit(RtpSignalTable *table) +{ + int i,c; + + for (i=0,c=0;ccount;i++){ + if (table->callback[i]!=NULL){ + c++; /*I like it*/ + table->callback[i](table->session,table->user_data[i]); + } + } +} + +void rtp_signal_table_emit2(RtpSignalTable *table,unsigned long arg) +{ + int i,c; + + for (i=0,c=0;ccount;i++){ + if (table->callback[i]!=NULL){ + c++; /*I like it*/ + table->callback[i](table->session,arg,table->user_data[i]); + } + } +} + +void rtp_signal_table_emit3(RtpSignalTable *table, unsigned long arg1, unsigned long arg2) +{ + int i,c; + + for (i=0,c=0;ccount;i++){ + if (table->callback[i]!=NULL){ + c++; /*I like it*/ + table->callback[i](table->session,arg1,arg2,table->user_data[i]); + } + } +} + +int rtp_signal_table_remove_by_callback(RtpSignalTable *table,RtpCallback cb) +{ + int i; + + for (i=0;icallback[i]==cb){ + table->callback[i]=NULL; + table->user_data[i]=0; + table->count--; + return 0; + } + } + return -1; +} diff --git a/linphone/oRTP/src/rtptimer.c b/linphone/oRTP/src/rtptimer.c new file mode 100644 index 000000000..261be48ff --- /dev/null +++ b/linphone/oRTP/src/rtptimer.c @@ -0,0 +1,33 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/ortp.h" +#include "rtptimer.h" + +void rtp_timer_set_interval(RtpTimer *timer, struct timeval *interval) +{ + if (timer->state==RTP_TIMER_RUNNING){ + ortp_warning("Cannot change timer interval while it is running.\n"); + return; + } + timer->interval.tv_sec=interval->tv_sec; + timer->interval.tv_usec=interval->tv_usec; +} + + diff --git a/linphone/oRTP/src/rtptimer.h b/linphone/oRTP/src/rtptimer.h new file mode 100644 index 000000000..c4a01a456 --- /dev/null +++ b/linphone/oRTP/src/rtptimer.h @@ -0,0 +1,52 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef RTPTIMER_H +#define RTPTIMER_H + +#if !defined(_WIN32) && !defined(_WIN32_WCE) +#include +#else +#include +#include "winsock2.h" +#endif + +#include + + +typedef void (*RtpTimerFunc)(void); + +struct _RtpTimer +{ + int state; +#define RTP_TIMER_RUNNING 1 +#define RTP_TIMER_STOPPED 0 + RtpTimerFunc timer_init; + RtpTimerFunc timer_do; + RtpTimerFunc timer_uninit; + struct timeval interval; +}; + +typedef struct _RtpTimer RtpTimer; + +void rtp_timer_set_interval(RtpTimer *timer, struct timeval *interval); + +extern RtpTimer posix_timer; + +#endif diff --git a/linphone/oRTP/src/scheduler.c b/linphone/oRTP/src/scheduler.c new file mode 100644 index 000000000..0e53c7bfb --- /dev/null +++ b/linphone/oRTP/src/scheduler.c @@ -0,0 +1,212 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "utils.h" +#include "scheduler.h" +#include "rtpsession_priv.h" + +// To avoid warning during compile +extern void rtp_session_process (RtpSession * session, uint32_t time, RtpScheduler *sched); + + +void rtp_scheduler_init(RtpScheduler *sched) +{ + sched->list=0; + sched->time_=0; + /* default to the posix timer */ + rtp_scheduler_set_timer(sched,&posix_timer); + ortp_mutex_init(&sched->lock,NULL); + ortp_cond_init(&sched->unblock_select_cond,NULL); + sched->max_sessions=sizeof(SessionSet)*8; + session_set_init(&sched->all_sessions); + sched->all_max=0; + session_set_init(&sched->r_sessions); + sched->r_max=0; + session_set_init(&sched->w_sessions); + sched->w_max=0; + session_set_init(&sched->e_sessions); + sched->e_max=0; +} + +RtpScheduler * rtp_scheduler_new() +{ + RtpScheduler *sched=(RtpScheduler *) ortp_malloc(sizeof(RtpScheduler)); + memset(sched,0,sizeof(RtpScheduler)); + rtp_scheduler_init(sched); + return sched; +} + +void rtp_scheduler_set_timer(RtpScheduler *sched,RtpTimer *timer) +{ + if (sched->thread_running){ + ortp_warning("Cannot change timer while the scheduler is running !!"); + return; + } + sched->timer=timer; + /* report the timer increment */ + sched->timer_inc=(timer->interval.tv_usec/1000) + (timer->interval.tv_sec*1000); +} + +void rtp_scheduler_start(RtpScheduler *sched) +{ + if (sched->thread_running==0){ + sched->thread_running=1; + ortp_mutex_lock(&sched->lock); + ortp_thread_create(&sched->thread, NULL, rtp_scheduler_schedule,(void*)sched); + ortp_cond_wait(&sched->unblock_select_cond,&sched->lock); + ortp_mutex_unlock(&sched->lock); + } + else ortp_warning("Scheduler thread already running."); + +} +void rtp_scheduler_stop(RtpScheduler *sched) +{ + if (sched->thread_running==1) + { + sched->thread_running=0; + ortp_thread_join(sched->thread, NULL); + } + else ortp_warning("Scheduler thread is not running."); +} + +void rtp_scheduler_destroy(RtpScheduler *sched) +{ + if (sched->thread_running) rtp_scheduler_stop(sched); + ortp_mutex_destroy(&sched->lock); + //g_mutex_free(sched->unblock_select_mutex); + ortp_cond_destroy(&sched->unblock_select_cond); + ortp_free(sched); +} + +void * rtp_scheduler_schedule(void * psched) +{ + RtpScheduler *sched=(RtpScheduler*) psched; + RtpTimer *timer=sched->timer; + RtpSession *current; + + /* take this lock to prevent the thread to start until g_thread_create() returns + because we need sched->thread to be initialized */ + ortp_mutex_lock(&sched->lock); + ortp_cond_signal(&sched->unblock_select_cond); /* unblock the starting thread */ + ortp_mutex_unlock(&sched->lock); + timer->timer_init(); + while(sched->thread_running) + { + /* do the processing here: */ + ortp_mutex_lock(&sched->lock); + + current=sched->list; + /* processing all scheduled rtp sessions */ + while (current!=NULL) + { + ortp_debug("scheduler: processing session=0x%x.\n",current); + rtp_session_process(current,sched->time_,sched); + current=current->next; + } + /* wake up all the threads that are sleeping in _select() */ + ortp_cond_broadcast(&sched->unblock_select_cond); + ortp_mutex_unlock(&sched->lock); + + /* now while the scheduler is going to sleep, the other threads can compute their + result mask and see if they have to leave, or to wait for next tick*/ + //ortp_message("scheduler: sleeping."); + timer->timer_do(); + sched->time_+=sched->timer_inc; + } + /* when leaving the thread, stop the timer */ + timer->timer_uninit(); + return NULL; +} + +void rtp_scheduler_add_session(RtpScheduler *sched, RtpSession *session) +{ + RtpSession *oldfirst; + int i; + if (session->flags & RTP_SESSION_IN_SCHEDULER){ + /* the rtp session is already scheduled, so return silently */ + return; + } + rtp_scheduler_lock(sched); + /* enqueue the session to the list of scheduled sessions */ + oldfirst=sched->list; + sched->list=session; + session->next=oldfirst; + if (sched->max_sessions==0){ + ortp_error("rtp_scheduler_add_session: max_session=0 !"); + } + /* find a free pos in the session mask*/ + for (i=0;imax_sessions;i++){ + if (!ORTP_FD_ISSET(i,&sched->all_sessions.rtpset)){ + session->mask_pos=i; + session_set_set(&sched->all_sessions,session); + /* make a new session scheduled not blockable if it has not started*/ + if (session->flags & RTP_SESSION_RECV_NOT_STARTED) + session_set_set(&sched->r_sessions,session); + if (session->flags & RTP_SESSION_SEND_NOT_STARTED) + session_set_set(&sched->w_sessions,session); + if (i>sched->all_max){ + sched->all_max=i; + } + break; + } + } + + rtp_session_set_flag(session,RTP_SESSION_IN_SCHEDULER); + rtp_scheduler_unlock(sched); +} + +void rtp_scheduler_remove_session(RtpScheduler *sched, RtpSession *session) +{ + RtpSession *tmp; + int cond=1; + return_if_fail(session!=NULL); + if (!(session->flags & RTP_SESSION_IN_SCHEDULER)){ + /* the rtp session is not scheduled, so return silently */ + return; + } + + rtp_scheduler_lock(sched); + tmp=sched->list; + if (tmp==session){ + sched->list=tmp->next; + rtp_session_unset_flag(session,RTP_SESSION_IN_SCHEDULER); + session_set_clr(&sched->all_sessions,session); + rtp_scheduler_unlock(sched); + return; + } + /* go the position of session in the list */ + while(cond){ + if (tmp!=NULL){ + if (tmp->next==session){ + tmp->next=tmp->next->next; + cond=0; + } + else tmp=tmp->next; + }else { + /* the session was not found ! */ + ortp_warning("rtp_scheduler_remove_session: the session was not found in the scheduler list!"); + cond=0; + } + } + rtp_session_unset_flag(session,RTP_SESSION_IN_SCHEDULER); + /* delete the bit in the mask */ + session_set_clr(&sched->all_sessions,session); + rtp_scheduler_unlock(sched); +} diff --git a/linphone/oRTP/src/scheduler.h b/linphone/oRTP/src/scheduler.h new file mode 100644 index 000000000..5e15751a2 --- /dev/null +++ b/linphone/oRTP/src/scheduler.h @@ -0,0 +1,69 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SCHEDULER_H +#define SCHEDULER_H + +#include "ortp/rtpsession.h" +#include "ortp/sessionset.h" +#include "rtptimer.h" + + +struct _RtpScheduler { + + RtpSession *list; /* list of scheduled sessions*/ + SessionSet all_sessions; /* mask of scheduled sessions */ + int all_max; /* the highest pos in the all mask */ + SessionSet r_sessions; /* mask of sessions that have a recv event */ + int r_max; + SessionSet w_sessions; /* mask of sessions that have a send event */ + int w_max; + SessionSet e_sessions; /* mask of session that have error event */ + int e_max; + int max_sessions; /* the number of position in the masks */ + /* GMutex *unblock_select_mutex; */ + ortp_cond_t unblock_select_cond; + ortp_mutex_t lock; + ortp_thread_t thread; + int thread_running; + struct _RtpTimer *timer; + uint32_t time_; /*number of miliseconds elapsed since the start of the thread */ + uint32_t timer_inc; /* the timer increment in milisec */ +}; + +typedef struct _RtpScheduler RtpScheduler; + +RtpScheduler * rtp_scheduler_new(void); +void rtp_scheduler_set_timer(RtpScheduler *sched,RtpTimer *timer); +void rtp_scheduler_start(RtpScheduler *sched); +void rtp_scheduler_stop(RtpScheduler *sched); +void rtp_scheduler_destroy(RtpScheduler *sched); + +void rtp_scheduler_add_session(RtpScheduler *sched, RtpSession *session); +void rtp_scheduler_remove_session(RtpScheduler *sched, RtpSession *session); + +void * rtp_scheduler_schedule(void * sched); + +#define rtp_scheduler_lock(sched) ortp_mutex_lock(&(sched)->lock) +#define rtp_scheduler_unlock(sched) ortp_mutex_unlock(&(sched)->lock) + +/* void rtp_scheduler_add_set(RtpScheduler *sched, SessionSet *set); */ + +RtpScheduler * ortp_get_scheduler(void); +#endif diff --git a/linphone/oRTP/src/sessionset.c b/linphone/oRTP/src/sessionset.c new file mode 100644 index 000000000..3a7ad1cfd --- /dev/null +++ b/linphone/oRTP/src/sessionset.c @@ -0,0 +1,148 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "scheduler.h" + + +/** + * Allocates and initialize a new empty session set. + * + * @return the empty session set. +**/ +SessionSet * session_set_new() +{ + SessionSet *set=(SessionSet *) ortp_malloc(sizeof(SessionSet)); + session_set_init(set); + return set; +} + + +/** + * Destroys a session set. + * +**/ + +void session_set_destroy(SessionSet *set) +{ + ortp_free(set); +} + +int session_set_and(SessionSet *sched_set, int maxs, SessionSet *user_set, SessionSet *result_set) +{ + uint32_t *mask1,*mask2,*mask3; + int i=0; + int j,ret=0; + mask1=(uint32_t*)(void*)&sched_set->rtpset; + mask2=(uint32_t*)(void*)&user_set->rtpset; + mask3=(uint32_t*)(void*)&result_set->rtpset; + while(i>j) & 1){ + ret++; + } + } + } + i+=32; + mask1++; + mask2++; + mask3++; + } + //printf("session_set_and: ret=%i\n",ret); + return ret; +} + +/** + * This function performs similarly as libc select() function, but performs on #RtpSession + * instead of file descriptors. + * session_set_select() suspends the calling process until some events arrive on one of the + * three sets passed in argument. Two of the sets can be NULL. + * The first set @recvs is interpreted as a set of RtpSession waiting for receive events: + * a new buffer (perhaps empty) is availlable on one or more sessions of the set, or the last + * receive operation with rtp_session_recv_with_ts() would have finished if it were in + * blocking mode. + * The second set is interpreted as a set of RtpSession waiting for send events, i.e. the last + * rtp_session_send_with_ts() call on a session would have finished if it were in blocking mode. + * + * When some events arrived on some of sets, then the function returns and sets are changed + * to indicate the sessions where events happened. + * Sessions can be added to sets using session_set_set(), a session has to be tested to be + * part of a set using session_set_is_set(). + * + * @param recvs a set of rtp sessions to be watched for read events + * @param sends a set of rtp sessions to be watched for write events + * @param errors a set of rtp sessions to be watched for errors + * @return: the number of sessions on which the selected events happened. +**/ +int session_set_select(SessionSet *recvs, SessionSet *sends, SessionSet *errors) +{ + int ret=0,bits; + SessionSet temp; + RtpScheduler *sched=ortp_get_scheduler(); + + /*lock the scheduler to not read the masks while they are being modified by the scheduler*/ + rtp_scheduler_lock(sched); + + while(1){ + /* computes the SessionSet intersection (in the other words mask intersection) between + the mask given by the user and scheduler masks */ + if (recvs!=NULL){ + session_set_init(&temp); + bits=session_set_and(&sched->r_sessions,sched->all_max,recvs,&temp); + ret+=bits; + /* copy the result set in the given user set (might be empty) */ + if (ret>0) session_set_copy(recvs,&temp); + } + if (sends!=NULL){ + session_set_init(&temp); + bits=session_set_and(&sched->w_sessions,sched->all_max,sends,&temp); + ret+=bits; + if (ret>0){ + /* copy the result set in the given user set (might be empty)*/ + session_set_copy(sends,&temp); + } + } + if (errors!=NULL){ + session_set_init(&temp); + bits=session_set_and(&sched->e_sessions,sched->all_max,errors,&temp); + ret+=bits; + if (ret>0){ + /* copy the result set in the given user set */ + session_set_copy(errors,&temp); + } + } + if (ret>0){ + /* there are set file descriptors, return immediately */ + //printf("There are %i sessions set, returning.\n",ret); + rtp_scheduler_unlock(sched); + return ret; + } + //printf("There are %i sessions set.\n",ret); + /* else we wait until the next loop of the scheduler*/ + ortp_cond_wait(&sched->unblock_select_cond,&sched->lock); + } + + return -1; +} + diff --git a/linphone/oRTP/src/srtp.c b/linphone/oRTP/src/srtp.c new file mode 100644 index 000000000..f1dfd24b6 --- /dev/null +++ b/linphone/oRTP/src/srtp.c @@ -0,0 +1,203 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if defined(WIN32) || defined(_WIN32_WCE) +#include "ortp-config-win32.h" +#else +#include "ortp-config.h" +#endif +#include "ortp/ortp.h" + +#ifdef HAVE_SRTP + +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include "ortp/srtp.h" + +#define SRTP_PAD_BYTES 64 /*?? */ + +static int srtp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){ + srtp_t srtp=(srtp_t)t->data; + int slen; + err_status_t err; + /* enlarge the buffer for srtp to write its data */ + msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES); + slen=m->b_wptr-m->b_rptr; + err=srtp_protect(srtp,m->b_rptr,&slen); + if (err==err_status_ok){ + return sendto(t->session->rtp.socket,m->b_rptr,slen,flags,to,tolen); + } + ortp_error("srtp_protect() failed"); + return -1; +} + +static int srtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){ + srtp_t srtp=(srtp_t)t->data; + int err; + int slen; + err=recvfrom(t->session->rtp.socket,m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + if (err>0){ + + /* keep NON-RTP data unencrypted */ + rtp_header_t *rtp; + if (err>=RTP_FIXED_HEADER_SIZE) + { + rtp = (rtp_header_t*)m->b_wptr; + if (rtp->version!=2) + { + return err; + } + } + + slen=err; + if (srtp_unprotect(srtp,m->b_wptr,&slen)==err_status_ok) + return slen; + else { + ortp_error("srtp_unprotect() failed"); + return -1; + } + } + return err; +} + +static int srtcp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){ + srtp_t srtp=(srtp_t)t->data; + int slen; + /* enlarge the buffer for srtp to write its data */ + msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES); + slen=m->b_wptr-m->b_rptr; + if (srtp_protect_rtcp(srtp,m->b_rptr,&slen)==err_status_ok){ + return sendto(t->session->rtcp.socket,m->b_rptr,slen,flags,to,tolen); + } + ortp_error("srtp_protect_rtcp() failed"); + return -1; +} + +static int srtcp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){ + srtp_t srtp=(srtp_t)t->data; + int err; + int slen; + err=recvfrom(t->session->rtcp.socket,m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + if (err>0){ + slen=err; + if (srtp_unprotect_rtcp(srtp,m->b_wptr,&slen)==err_status_ok) + return slen; + else { + ortp_error("srtp_unprotect_rtcp() failed"); + return -1; + } + } + return err; +} + +ortp_socket_t +srtp_getsocket(RtpTransport *t) +{ + return t->session->rtp.socket; +} + +ortp_socket_t +srtcp_getsocket(RtpTransport *t) +{ + return t->session->rtcp.socket; +} + +/** + * Creates a pair of Secure-RTP/Secure-RTCP RtpTransport's. + * oRTP relies on libsrtp (see http://srtp.sf.net ) for secure RTP encryption. + * This function creates a RtpTransport object to be used to the RtpSession using + * rtp_session_set_transport(). + * @srtp: the srtp_t session to be used + * +**/ +int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt ){ + if (rtpt) { + (*rtpt)=ortp_new(RtpTransport,1); + (*rtpt)->data=srtp; + (*rtpt)->t_getsocket=srtp_getsocket; + (*rtpt)->t_sendto=srtp_sendto; + (*rtpt)->t_recvfrom=srtp_recvfrom; + } + if (rtcpt) { + (*rtcpt)=ortp_new(RtpTransport,1); + (*rtcpt)->data=srtp; + (*rtcpt)->t_getsocket=srtcp_getsocket; + (*rtcpt)->t_sendto=srtcp_sendto; + (*rtcpt)->t_recvfrom=srtcp_recvfrom; + } + return 0; +} + +err_status_t ortp_srtp_init(void) +{ + return srtp_init(); +} + +err_status_t ortp_srtp_create(srtp_t *session, const srtp_policy_t *policy) +{ + int i; + i = srtp_create(session, policy); + return i; +} + +err_status_t ortp_srtp_dealloc(srtp_t session) +{ + return srtp_dealloc(session); +} + +err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy) +{ + return srtp_add_stream(session, policy); +} + +bool_t ortp_srtp_supported(void){ + return TRUE; +} + +#else + +int srtp_transport_new(void *i, RtpTransport **rtpt, RtpTransport **rtcpt ){ + ortp_error("srtp_transport_new: oRTP has not been compiled with SRTP support."); + return -1; +} + +bool_t ortp_srtp_supported(void){ + return FALSE; +} + +int ortp_srtp_create(void *i, const void *policy) +{ + return -1; +} + +int ortp_srtp_dealloc(void *session) +{ + return -1; +} + +int ortp_srtp_add_stream(void *session, const void *policy) +{ + return -1; +} + +#endif + diff --git a/linphone/oRTP/src/str_utils.c b/linphone/oRTP/src/str_utils.c new file mode 100644 index 000000000..09ebad9a6 --- /dev/null +++ b/linphone/oRTP/src/str_utils.c @@ -0,0 +1,337 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/ortp.h" +#include "ortp/rtp.h" +#include "ortp/str_utils.h" +#include "utils.h" + +void qinit(queue_t *q){ + mblk_init(&q->_q_stopper); + q->_q_stopper.b_next=&q->_q_stopper; + q->_q_stopper.b_prev=&q->_q_stopper; + q->q_mcount=0; +} + +void mblk_init(mblk_t *mp) +{ + mp->b_cont=mp->b_prev=mp->b_next=NULL; + mp->b_rptr=mp->b_wptr=NULL; + mp->reserved1=0; + mp->reserved2=0; +} + +dblk_t *datab_alloc(int size){ + dblk_t *db; + int total_size=sizeof(dblk_t)+size; + db=(dblk_t *) ortp_malloc(total_size); + db->db_base=(uint8_t*)db+sizeof(dblk_t); + db->db_lim=db->db_base+size; + db->db_ref=1; + db->db_freefn=NULL; /* the buffer pointed by db_base must never be freed !*/ + return db; +} + +static inline void datab_ref(dblk_t *d){ + d->db_ref++; +} + +static inline void datab_unref(dblk_t *d){ + d->db_ref--; + if (d->db_ref==0){ + if (d->db_freefn!=NULL) + d->db_freefn(d->db_base); + ortp_free(d); + } +} + + +mblk_t *allocb(int size, int pri) +{ + mblk_t *mp; + dblk_t *datab; + + mp=(mblk_t *) ortp_malloc(sizeof(mblk_t)); + mblk_init(mp); + datab=datab_alloc(size); + + mp->b_datap=datab; + mp->b_rptr=mp->b_wptr=datab->db_base; + mp->b_next=mp->b_prev=mp->b_cont=NULL; + return mp; +} + +mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*) ) +{ + mblk_t *mp; + dblk_t *datab; + + mp=(mblk_t *) ortp_malloc(sizeof(mblk_t)); + mblk_init(mp); + datab=(dblk_t *) ortp_malloc(sizeof(dblk_t)); + + + datab->db_base=buf; + datab->db_lim=buf+size; + datab->db_ref=1; + datab->db_freefn=freefn; + + mp->b_datap=datab; + mp->b_rptr=mp->b_wptr=buf; + mp->b_next=mp->b_prev=mp->b_cont=NULL; + return mp; +} + + +void freeb(mblk_t *mp) +{ + return_if_fail(mp->b_datap!=NULL); + return_if_fail(mp->b_datap->db_base!=NULL); + + datab_unref(mp->b_datap); + ortp_free(mp); +} + +void freemsg(mblk_t *mp) +{ + mblk_t *tmp1,*tmp2; + tmp1=mp; + while(tmp1!=NULL) + { + tmp2=tmp1->b_cont; + freeb(tmp1); + tmp1=tmp2; + } +} + +mblk_t *dupb(mblk_t *mp) +{ + mblk_t *newm; + return_val_if_fail(mp->b_datap!=NULL,NULL); + return_val_if_fail(mp->b_datap->db_base!=NULL,NULL); + + datab_ref(mp->b_datap); + newm=(mblk_t *) ortp_malloc(sizeof(mblk_t)); + mblk_init(newm); + newm->b_datap=mp->b_datap; + newm->b_rptr=mp->b_rptr; + newm->b_wptr=mp->b_wptr; + return newm; +} + +/* duplicates a complex mblk_t */ +mblk_t *dupmsg(mblk_t* m) +{ + mblk_t *newm=NULL,*mp,*prev; + prev=newm=dupb(m); + m=m->b_cont; + while (m!=NULL){ + mp=dupb(m); + prev->b_cont=mp; + prev=mp; + m=m->b_cont; + } + return newm; +} + +void putq(queue_t *q,mblk_t *mp) +{ + q->_q_stopper.b_prev->b_next=mp; + mp->b_prev=q->_q_stopper.b_prev; + mp->b_next=&q->_q_stopper; + q->_q_stopper.b_prev=mp; + q->q_mcount++; +} + +mblk_t *getq(queue_t *q) +{ + mblk_t *tmp; + tmp=q->_q_stopper.b_next; + if (tmp==&q->_q_stopper) return NULL; + q->_q_stopper.b_next=tmp->b_next; + tmp->b_next->b_prev=&q->_q_stopper; + tmp->b_prev=NULL; + tmp->b_next=NULL; + q->q_mcount--; + return tmp; +} + +mblk_t * peekq(queue_t *q){ + mblk_t *tmp; + tmp=q->_q_stopper.b_next; + if (tmp==&q->_q_stopper) return NULL; + return tmp; +} + +/* insert mp in q just before emp */ +void insq(queue_t *q,mblk_t *emp, mblk_t *mp) +{ + if (emp==NULL){ + putq(q,mp); + return; + } + q->q_mcount++; + emp->b_prev->b_next=mp; + mp->b_prev=emp->b_prev; + emp->b_prev=mp; + mp->b_next=emp; +} + +void remq(queue_t *q, mblk_t *mp){ + q->q_mcount--; + mp->b_prev->b_next=mp->b_next; + mp->b_next->b_prev=mp->b_prev; + mp->b_next=NULL; + mp->b_prev=NULL; +} + +/* remove and free all messages in the q */ +void flushq(queue_t *q, int how) +{ + mblk_t *mp; + + while ((mp=getq(q))!=NULL) + { + freemsg(mp); + } +} + +int msgdsize(const mblk_t *mp) +{ + int msgsize=0; + while(mp!=NULL){ + msgsize+=(int) (mp->b_wptr-mp->b_rptr); + mp=mp->b_cont; + } + return msgsize; +} + +void msgpullup(mblk_t *mp,int len) +{ + mblk_t *firstm=mp; + dblk_t *db; + int wlen=0; + + if (mp->b_cont==NULL && len==-1) return; /*nothing to do, message is not fragmented */ + + if (len==-1) len=msgdsize(mp); + db=datab_alloc(len); + while(wlenb_wptr-mp->b_rptr; + if (mlen<=remain){ + memcpy(&db->db_base[wlen],mp->b_rptr,mlen); + wlen+=mlen; + mp=mp->b_cont; + }else{ + memcpy(&db->db_base[wlen],mp->b_rptr,remain); + wlen+=remain; + } + } + /*set firstm to point to the new datab */ + freemsg(firstm->b_cont); + firstm->b_cont=NULL; + datab_unref(firstm->b_datap); + firstm->b_datap=db; + firstm->b_rptr=db->db_base; + firstm->b_wptr=firstm->b_rptr+wlen; +} + + +mblk_t *copyb(mblk_t *mp) +{ + mblk_t *newm; + int len=(int) (mp->b_wptr-mp->b_rptr); + newm=allocb(len,BPRI_MED); + memcpy(newm->b_wptr,mp->b_rptr,len); + newm->b_wptr+=len; + return newm; +} + +mblk_t *copymsg(mblk_t *mp) +{ + mblk_t *newm=0,*m; + m=newm=copyb(mp); + mp=mp->b_cont; + while(mp!=NULL){ + m->b_cont=copyb(mp); + m=m->b_cont; + mp=mp->b_cont; + } + return newm; +} + +mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad){ + int padcnt=0; + int i; + if (pad){ + padcnt= (int)(4L-( (long)(((long)mp->b_wptr)+size) % 4L)) % 4L; + } + if ((mp->b_wptr + size +padcnt) > mp->b_datap->db_lim){ + /* buffer is not large enough: append a new block (with the same size ?)*/ + int plen=(int)((char*)mp->b_datap->db_lim - (char*) mp->b_datap->db_base); + mp->b_cont=allocb(MAX(plen,size),0); + mp=mp->b_cont; + } + if (size) memcpy(mp->b_wptr,data,size); + mp->b_wptr+=size; + for (i=0;ib_wptr[0]=0; + mp->b_wptr++; + } + return mp; +} + +void msgappend(mblk_t *mp, const char *data, int size, bool_t pad){ + while(mp->b_cont!=NULL) mp=mp->b_cont; + appendb(mp,data,size,pad); +} + +mblk_t *concatb(mblk_t *mp, mblk_t *newm){ + while (mp->b_cont!=NULL) mp=mp->b_cont; + mp->b_cont=newm; + while(newm->b_cont!=NULL) newm=newm->b_cont; + return newm; +} + +void msgb_allocator_init(msgb_allocator_t *a){ + qinit(&a->q); +} + +mblk_t *msgb_allocator_alloc(msgb_allocator_t *a, int size){ + queue_t *q=&a->q; + mblk_t *m,*found=NULL; + + /*lookup for an unused msgb (data block with ref count ==1)*/ + for(m=qbegin(q);!qend(q,m);m=qnext(q,m)){ + if (m->b_datap->db_ref==1 && m->b_datap->db_lim-m->b_datap->db_base>=size){ + found=m; + break; + } + } + if (found==NULL){ + found=allocb(size,0); + putq(q,found); + } + return dupb(found); +} + +void msgb_allocator_uninit(msgb_allocator_t *a){ + flushq(&a->q,-1); +} diff --git a/linphone/oRTP/src/stun.c b/linphone/oRTP/src/stun.c new file mode 100644 index 000000000..a0e34a471 --- /dev/null +++ b/linphone/oRTP/src/stun.c @@ -0,0 +1,2641 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ + +#ifndef _WIN32_WCE +#include +#endif + +#include + +#if defined(WIN32) || defined(_WIN32_WCE) +#include +#include +/* #include */ +#include +#include /*for isdigit() */ +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + + +#define NOSSL +/* + #if defined(__sparc__) || defined(WIN32) + #define NOSSL + #endif + #define NOSSL +*/ + +#include "ortp/stun_udp.h" +#include "ortp/stun.h" +#include "ortp/ortp.h" + +static char *ipaddr(const StunAddress4 *addr) +{ + static char tmp[512]; + struct in_addr inaddr; + char *atmp; + inaddr.s_addr = htonl(addr->addr); + atmp = (char *)inet_ntoa(inaddr); + + snprintf(tmp, 512, "%s:%i", atmp, addr->port); + return tmp; +} + +static void +computeHmac(char* hmac, const char* input, int length, const char* key, int keySize); + +static bool_t +stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress4 *result ) +{ + if ( hdrLen != 8 ) + { + ortp_error("stun: hdrLen wrong for Address\n"); + return FALSE; + } + result->pad = *body++; + result->family = *body++; + if (result->family == IPv4Family) + { + UInt16 nport; + UInt32 naddr; + memcpy(&nport, body, 2); body+=2; + result->ipv4.port = ntohs(nport); + + memcpy(&naddr, body, 4); body+=4; + result->ipv4.addr = ntohl(naddr); + return TRUE; + } + else if (result->family == IPv6Family) + { + ortp_error("stun: ipv6 not supported\n"); + } + else + { + ortp_error("stun: bad address family: %i\n", result->family); + } + + return FALSE; +} + +static bool_t +stunParseAtrChangeRequest( char* body, unsigned int hdrLen, StunAtrChangeRequest *result ) +{ + if ( hdrLen != 4 ) + { + /* ortp_error("stun: hdr length = %i expecting %i\n",hdrLen, sizeof(result)); */ + + ortp_error("stun: Incorrect size for ChangeRequest"); + return FALSE; + } + else + { + memcpy(&result->value, body, 4); + result->value = ntohl(result->value); + return TRUE; + } +} + +static bool_t +stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError *result ) +{ + if ( hdrLen >= sizeof(result) ) + { + ortp_error("stun: head on Error too large"); + return FALSE; + } + else + { + memcpy(&result->pad, body, 2); body+=2; + result->pad = ntohs(result->pad); + result->errorClass = *body++; + result->number = *body++; + + result->sizeReason = hdrLen - 4; + memcpy(&result->reason, body, result->sizeReason); + result->reason[result->sizeReason] = 0; + return TRUE; + } +} + +static bool_t +stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown *result ) +{ + if ( hdrLen >= sizeof(result) ) + { + return FALSE; + } + else + { + int i; + if (hdrLen % 4 != 0) return FALSE; + result->numAttributes = hdrLen / 4; + for (i=0; inumAttributes; i++) + { + memcpy(&result->attrType[i], body, 2); body+=2; + result->attrType[i] = ntohs(result->attrType[i]); + } + return TRUE; + } +} + + +static bool_t +stunParseAtrString( char* body, unsigned int hdrLen, StunAtrString *result ) +{ + if ( hdrLen >= STUN_MAX_STRING ) + { + ortp_error("stun: String is too large"); + return FALSE; + } + else + { + if (hdrLen % 4 != 0) + { + ortp_error("stun: Bad length string %i\n", hdrLen); + return FALSE; + } + + result->sizeValue = hdrLen; + memcpy(&result->value, body, hdrLen); + result->value[hdrLen] = 0; + return TRUE; + } +} + + +static bool_t +stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity *result ) +{ + if ( hdrLen != 20) + { + ortp_error("stun: MessageIntegrity must be 20 bytes"); + return FALSE; + } + else + { + memcpy(&result->hash, body, hdrLen); + return TRUE; + } +} + + +bool_t +stunParseMessage( char* buf, unsigned int bufLen, StunMessage *msg, bool_t verbose) +{ + char* body; + unsigned int size; + if (verbose) + ortp_message("stun: Received stun message: %i bytes\n", bufLen); + memset(msg, 0, sizeof(msg)); + + if (sizeof(StunMsgHdr) > bufLen) + { + ortp_warning("stun: Bad message\n"); + return FALSE; + } + + memcpy(&msg->msgHdr, buf, sizeof(StunMsgHdr)); + msg->msgHdr.msgType = ntohs(msg->msgHdr.msgType); + msg->msgHdr.msgLength = ntohs(msg->msgHdr.msgLength); + + if (msg->msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen) + { + ortp_warning("stun: Message header length doesn't match message size: %i - %i\n", msg->msgHdr.msgLength, bufLen); + return FALSE; + } + + body = buf + sizeof(StunMsgHdr); + size = msg->msgHdr.msgLength; + + /*ortp_message("stun: bytes after header = %i\n", size); */ + + while ( size > 0 ) + { + /* !jf! should check that there are enough bytes left in the buffer */ + + StunAtrHdr* attr = (StunAtrHdr*)body; /*reinterpret_cast(body);*/ + + unsigned int attrLen = ntohs(attr->length); + int atrType = ntohs(attr->type); + + /*if (verbose) ortp_message("stun: Found attribute type=" << AttrNames[atrType] << " length=" << attrLen << endl;*/ + if ( attrLen+4 > size ) + { + ortp_error("stun: claims attribute is larger than size of message (attribute type=%i)\n", atrType); + return FALSE; + } + + body += 4; /* skip the length and type in attribute header */ + size -= 4; + + if (atrType == MappedAddress) + { + msg->hasMappedAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->mappedAddress )== FALSE ) + { + ortp_error("stun: problem parsing MappedAddress\n"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: MappedAddress = %s\n", ipaddr(&msg->mappedAddress.ipv4)); + } + + } + else if (atrType == ResponseAddress) + { + msg->hasResponseAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->responseAddress )== FALSE ) + { + ortp_error("stun: problem parsing ResponseAddress"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: ResponseAddress = %s\n", ipaddr(&msg->responseAddress.ipv4)); + } + } + else if (atrType == ChangeRequest) + { + msg->hasChangeRequest = TRUE; + if (stunParseAtrChangeRequest( body, attrLen, &msg->changeRequest) == FALSE) + { + ortp_error("stun: problem parsing ChangeRequest\n"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: ChangeRequest = %i\n", msg->changeRequest.value); + } + } + else if (atrType == SourceAddress) + { + msg->hasSourceAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->sourceAddress )== FALSE ) + { + ortp_error("stun: problem parsing SourceAddress\n"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: SourceAddress = %s\n", ipaddr(&msg->sourceAddress.ipv4) ); + } + } + else if (atrType == ChangedAddress) + { + msg->hasChangedAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->changedAddress )== FALSE ) + { + ortp_error("stun: problem parsing ChangedAddress\n"); + return FALSE; + } + else + { + if (verbose) ortp_message("stun: ChangedAddress = %s\n", ipaddr(&msg->changedAddress.ipv4)); + } + } + else if (atrType == Username) + { + msg->hasUsername = TRUE; + if (stunParseAtrString( body, attrLen, &msg->username) == FALSE) + { + ortp_error("stun: problem parsing Username"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: Username = %s\n", msg->username.value ); + } + } + else if (atrType == Password) + { + msg->hasPassword = TRUE; + if (stunParseAtrString( body, attrLen, &msg->password) == FALSE) + { + ortp_error("stun: problem parsing Password"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: Password = %s\n", msg->password.value ); + } + } + else if (atrType == MessageIntegrity) + { + msg->hasMessageIntegrity = TRUE; + if (stunParseAtrIntegrity( body, attrLen, &msg->messageIntegrity) == FALSE) + { + ortp_error("stun: problem parsing MessageIntegrity"); + return FALSE; + } + else + { + /*if (verbose) ortp_message("stun: MessageIntegrity = " << msg->messageIntegrity.hash ); */ + } + + /* read the current HMAC + look up the password given the user of given the transaction id + compute the HMAC on the buffer + decide if they match or not */ + } + else if (atrType == ErrorCode) + { + msg->hasErrorCode = TRUE; + if (stunParseAtrError(body, attrLen, &msg->errorCode) == FALSE) + { + ortp_error("stun: problem parsing ErrorCode"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: ErrorCode = %i %i %s\n", + msg->errorCode.errorClass , + msg->errorCode.number , + msg->errorCode.reason ); + } + + } + else if (atrType == UnknownAttribute) + { + msg->hasUnknownAttributes = TRUE; + if (stunParseAtrUnknown(body, attrLen, &msg->unknownAttributes) == FALSE) + { + ortp_error("stun: problem parsing UnknownAttribute"); + return FALSE; + } + } + else if (atrType == ReflectedFrom) + { + msg->hasReflectedFrom = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->reflectedFrom ) == FALSE ) + { + ortp_error("stun: problem parsing ReflectedFrom"); + return FALSE; + } + } + else if (atrType == XorMappedAddress) + { + msg->hasXorMappedAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->xorMappedAddress ) == FALSE ) + { + ortp_error("stun: problem parsing XorMappedAddress"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: XorMappedAddress = %s\n", ipaddr(&msg->mappedAddress.ipv4) ); + } + } + else if (atrType == XorOnly) + { + msg->xorOnly = TRUE; + } + else if (atrType == ServerName) + { + msg->hasServerName = TRUE; + if (stunParseAtrString( body, attrLen, &msg->serverName) == FALSE) + { + ortp_error("stun: problem parsing ServerName"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: ServerName = %s\n", msg->serverName.value ); + } + } + else if (atrType == SecondaryAddress) + { + msg->hasSecondaryAddress = TRUE; + if ( stunParseAtrAddress( body, attrLen, &msg->secondaryAddress ) == FALSE ) + { + ortp_error("stun: problem parsing secondaryAddress"); + return FALSE; + } + else + { + if (verbose) + ortp_message("stun: SecondaryAddress = %s\n", ipaddr(&msg->secondaryAddress.ipv4) ); + } + } + else + { + if (verbose) + ortp_message("stun: Unknown attribute: %i\n", atrType ); + if ( atrType <= 0x7FFF ) + { + return FALSE; + } + } + + body += attrLen; + size -= attrLen; + } + + return TRUE; +} + + +static char* +encode16(char* buf, UInt16 data) +{ + UInt16 ndata = htons(data); + /*memcpy(buf, reinterpret_cast(&ndata), sizeof(UInt16)); */ + memcpy(buf, &ndata, sizeof(UInt16)); + return buf + sizeof(UInt16); +} + +static char* +encode32(char* buf, UInt32 data) +{ + UInt32 ndata = htonl(data); + /*memcpy(buf, reinterpret_cast(&ndata), sizeof(UInt32));*/ + memcpy(buf, &ndata, sizeof(UInt32)); + return buf + sizeof(UInt32); +} + + +static char* +encode(char* buf, const char* data, unsigned int length) +{ + memcpy(buf, data, length); + return buf + length; +} + + +static char* +encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4 *atr) +{ + ptr = encode16(ptr, type); + ptr = encode16(ptr, 8); + *ptr++ = atr->pad; + *ptr++ = IPv4Family; + ptr = encode16(ptr, atr->ipv4.port); + ptr = encode32(ptr, atr->ipv4.addr); + + return ptr; +} + +static char* +encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest *atr) +{ + ptr = encode16(ptr, ChangeRequest); + ptr = encode16(ptr, 4); + ptr = encode32(ptr, atr->value); + return ptr; +} + +static char* +encodeAtrError(char* ptr, const StunAtrError *atr) +{ + ptr = encode16(ptr, ErrorCode); + ptr = encode16(ptr, 6 + atr->sizeReason); + ptr = encode16(ptr, atr->pad); + *ptr++ = atr->errorClass; + *ptr++ = atr->number; + ptr = encode(ptr, atr->reason, atr->sizeReason); + return ptr; +} + + +static char* +encodeAtrUnknown(char* ptr, const StunAtrUnknown *atr) +{ + int i; + ptr = encode16(ptr, UnknownAttribute); + ptr = encode16(ptr, 2+2*atr->numAttributes); + for (i=0; inumAttributes; i++) + { + ptr = encode16(ptr, atr->attrType[i]); + } + return ptr; +} + + +static char* +encodeXorOnly(char* ptr) +{ + ptr = encode16(ptr, XorOnly ); + return ptr; +} + + +static char* +encodeAtrString(char* ptr, UInt16 type, const StunAtrString *atr) +{ + /*assert(atr->sizeValue % 4 == 0);*/ + + ptr = encode16(ptr, type); + ptr = encode16(ptr, atr->sizeValue); + ptr = encode(ptr, atr->value, atr->sizeValue); + return ptr; +} + + +static char* +encodeAtrIntegrity(char* ptr, const StunAtrIntegrity *atr) +{ + ptr = encode16(ptr, MessageIntegrity); + ptr = encode16(ptr, 20); + ptr = encode(ptr, atr->hash, sizeof(atr->hash)); + return ptr; +} + + +unsigned int +stunEncodeMessage( const StunMessage *msg, + char* buf, + unsigned int bufLen, + const StunAtrString *password, + bool_t verbose) +{ + /*assert(bufLen >= sizeof(StunMsgHdr));*/ + char* ptr = buf; + char* lengthp; + ptr = encode16(ptr, msg->msgHdr.msgType); + lengthp = ptr; + ptr = encode16(ptr, 0); + /*ptr = encode(ptr, reinterpret_cast(msg->msgHdr.id.octet), sizeof(msg->msgHdr.id));*/ + ptr = encode(ptr, (const char*)msg->msgHdr.id.octet, sizeof(msg->msgHdr.id)); + + if (verbose) ortp_message("stun: Encoding stun message: "); + if (msg->hasMappedAddress) + { + if (verbose) ortp_message("stun: Encoding MappedAddress: %s\n", ipaddr(&msg->mappedAddress.ipv4) ); + ptr = encodeAtrAddress4 (ptr, MappedAddress, &msg->mappedAddress); + } + if (msg->hasResponseAddress) + { + if (verbose) ortp_message("stun: Encoding ResponseAddress: %s\n", ipaddr(&msg->responseAddress.ipv4) ); + ptr = encodeAtrAddress4(ptr, ResponseAddress, &msg->responseAddress); + } + if (msg->hasChangeRequest) + { + if (verbose) ortp_message("stun: Encoding ChangeRequest: %i\n", msg->changeRequest.value ); + ptr = encodeAtrChangeRequest(ptr, &msg->changeRequest); + } + if (msg->hasSourceAddress) + { + if (verbose) ortp_message("stun: Encoding SourceAddress: %s\n", ipaddr(&msg->sourceAddress.ipv4) ); + ptr = encodeAtrAddress4(ptr, SourceAddress, &msg->sourceAddress); + } + if (msg->hasChangedAddress) + { + if (verbose) ortp_message("stun: Encoding ChangedAddress: %s\n", ipaddr(&msg->changedAddress.ipv4) ); + ptr = encodeAtrAddress4(ptr, ChangedAddress, &msg->changedAddress); + } + if (msg->hasUsername) + { + if (verbose) ortp_message("stun: Encoding Username: %s\n", msg->username.value ); + ptr = encodeAtrString(ptr, Username, &msg->username); + } + if (msg->hasPassword) + { + if (verbose) ortp_message("stun: Encoding Password: %s\n", msg->password.value ); + ptr = encodeAtrString(ptr, Password, &msg->password); + } + if (msg->hasErrorCode) + { + if (verbose) ortp_message("stun: Encoding ErrorCode: class=%i number=%i reason=%s\n" + , msg->errorCode.errorClass + , msg->errorCode.number + , msg->errorCode.reason ); + + ptr = encodeAtrError(ptr, &msg->errorCode); + } + if (msg->hasUnknownAttributes) + { + if (verbose) ortp_message("stun: Encoding UnknownAttribute: ???"); + ptr = encodeAtrUnknown(ptr, &msg->unknownAttributes); + } + if (msg->hasReflectedFrom) + { + if (verbose) ortp_message("stun: Encoding ReflectedFrom: %s\n", ipaddr(&msg->reflectedFrom.ipv4) ); + ptr = encodeAtrAddress4(ptr, ReflectedFrom, &msg->reflectedFrom); + } + if (msg->hasXorMappedAddress) + { + if (verbose) ortp_message("stun: Encoding XorMappedAddress: %s\n", ipaddr(&msg->xorMappedAddress.ipv4) ); + ptr = encodeAtrAddress4 (ptr, XorMappedAddress, &msg->xorMappedAddress); + } + if (msg->xorOnly) + { + if (verbose) ortp_message("stun: Encoding xorOnly: "); + ptr = encodeXorOnly( ptr ); + } + if (msg->hasServerName) + { + if (verbose) ortp_message("stun: Encoding ServerName: %s\n", msg->serverName.value ); + ptr = encodeAtrString(ptr, ServerName, &msg->serverName); + } + if (msg->hasSecondaryAddress) + { + if (verbose) ortp_message("stun: Encoding SecondaryAddress: %s\n", ipaddr(&msg->secondaryAddress.ipv4) ); + ptr = encodeAtrAddress4 (ptr, SecondaryAddress, &msg->secondaryAddress); + } + + if (password->sizeValue > 0) + { + StunAtrIntegrity integrity; + if (verbose) ortp_message("stun: HMAC with password: %s\n", password->value ); + + computeHmac(integrity.hash, buf, (int)(ptr-buf) , password->value, password->sizeValue); + ptr = encodeAtrIntegrity(ptr, &integrity); + } + + encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr))); + return (int)(ptr - buf); +} + +int +stunRand(void) +{ + /* return 32 bits of random stuff */ + /* assert( sizeof(int) == 4 ); */ + static bool_t init=FALSE; + if ( !init ) + { + UInt64 tick; + int seed; + init = TRUE; + +#if defined(_WIN32_WCE) + tick = GetTickCount (); +#elif defined(_MSC_VER) + { + volatile unsigned int lowtick=0,hightick=0; + __asm + { + rdtsc + mov lowtick, eax + mov hightick, edx + } + tick = hightick; + tick <<= 32; + tick |= lowtick; + } +#elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) ) + asm("rdtsc" : "=A" (tick)); +#elif defined(__GNUC__) && defined(__amd64__) + asm("rdtsc" : "=A" (tick)); +#elif defined (__SUNPRO_CC) && defined( __sparc__ ) + tick = gethrtime(); +#elif defined(__MACH__) + { + int fd=open("/dev/random",O_RDONLY); + read(fd,&tick,sizeof(tick)); + closesocket(fd); + } +#elif defined(__linux) + { + fd_set fdSet; + int maxFd=0; + struct timeval tv; + int e; + + int fd=open("/dev/random",O_RDONLY); + + if (fd<0) + { + ortp_message("stun: Failed to open random device\n"); + return random(); + } + FD_ZERO(&fdSet); + FD_SET(fd,&fdSet); + maxFd=fd+1; + + tv.tv_sec = 0; + tv.tv_usec = 500; + + e = select( maxFd, &fdSet, NULL,NULL, &tv ); + if (e <= 0) + { + ortp_error("stun: Failed to get data from random device\n"); + closesocket(fd); + return random(); + } + read(fd,&tick,sizeof(tick)); + closesocket(fd); + } +#else +# error Need some way to seed the random number generator +#endif + seed = (int)(tick); +#if defined(_WIN32) || defined(_WIN32_WCE) + srand(seed); +#else + srandom(seed); +#endif + } + +#if defined(_WIN32) || defined(_WIN32_WCE) + /* assert( RAND_MAX == 0x7fff ); */ + { + int r1 = rand(); + int r2 = rand(); + int ret = (r1<<16) + r2; + + return ret; + } +#else + return random(); +#endif +} + + +/* return a random number to use as a port */ +static int +randomPort() +{ + int min=0x4000; + int max=0x7FFF; + + int ret = stunRand(); + ret = ret|min; + ret = ret&max; + + return ret; +} + + +#ifdef NOSSL +static void +computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + strncpy(hmac,"hmac-not-implemented",20); +} +#else +#include + +static void +computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) +{ + unsigned int resultSize=0; + HMAC(EVP_sha1(), + key, sizeKey, + (const unsigned char*) input, length, + (unsigned char*)hmac, &resultSize); + /* + HMAC(EVP_sha1(), + key, sizeKey, + reinterpret_cast(input), length, + reinterpret_cast(hmac), &resultSize); + //assert(resultSize == 20); + */ +} +#endif + + +static void +toHex(const char* buffer, int bufferSize, char* output) +{ + int i; + static char hexmap[] = "0123456789abcdef"; + + const char* p = buffer; + char* r = output; + for (i=0; i < bufferSize; i++) + { + unsigned char temp = *p++; + + int hi = (temp & 0xf0)>>4; + int low = (temp & 0xf); + + *r++ = hexmap[hi]; + *r++ = hexmap[low]; + } + *r = 0; +} + +void +stunCreateUserName(const StunAddress4* source, StunAtrString* username) +{ + UInt64 time = stunGetSystemTimeSecs(); + UInt64 lotime; + char buffer[1024]; + char hmac[20]; + char key[] = "Jason"; + char hmacHex[41]; + int l; + + time -= (time % 20*60); + /* UInt64 hitime = time >> 32; */ + lotime = time & 0xFFFFFFFF; + + sprintf(buffer, + "%08x:%08x:%08x:", + (UInt32)(source->addr), + (UInt32)(stunRand()), + (UInt32)(lotime)); + /*assert( strlen(buffer) < 1024 ); */ + + /*assert(strlen(buffer) + 41 < STUN_MAX_STRING); */ + + computeHmac(hmac, buffer, strlen(buffer), key, strlen(key) ); + toHex(hmac, 20, hmacHex ); + hmacHex[40] =0; + + strcat(buffer,hmacHex); + + l = strlen(buffer); + /* assert( l+1 < STUN_MAX_STRING );*/ + /* assert( l%4 == 0 ); */ + + username->sizeValue = l; + memcpy(username->value,buffer,l); + username->value[l]=0; + + /* if (verbose) ortp_message("stun: computed username=%s\n", username.value ); */ +} + +void +stunCreatePassword(const StunAtrString *username, StunAtrString* password) +{ + char hmac[20]; + char key[] = "Fluffy"; + /* char buffer[STUN_MAX_STRING]; */ + computeHmac(hmac, username->value, strlen(username->value), key, strlen(key)); + toHex(hmac, 20, password->value); + password->sizeValue = 40; + password->value[40]=0; + + /* ortp_message("stun: password=%s\n", password->value ); */ +} + + +UInt64 +stunGetSystemTimeSecs(void) +{ + UInt64 time=0; +#if defined(_WIN32) || defined(_WIN32_WCE) + SYSTEMTIME t; + /* CJ TODO - this probably has bug on wrap around every 24 hours */ + GetSystemTime( &t ); + time = (t.wHour*60+t.wMinute)*60+t.wSecond; +#else + struct timeval now; + gettimeofday( &now , NULL ); + /* assert( now ); */ + time = now.tv_sec; +#endif + return time; +} + + +/* returns TRUE if it scucceeded */ +bool_t +stunParseHostName( char* peerName, + UInt32* ip, + UInt16* portVal, + UInt16 defaultPort ) +{ + struct in_addr sin_addr; + + char host[512]; + char* port = NULL; + int portNum = defaultPort; + char* sep; + struct hostent* h; + + strncpy(host,peerName,512); + host[512-1]='\0'; + + /* pull out the port part if present. */ + sep = strchr(host,':'); + + if ( sep == NULL ) + { + portNum = defaultPort; + } + else + { + char* endPtr=NULL; + *sep = '\0'; + port = sep + 1; + /* set port part */ + + + portNum = strtol(port,&endPtr,10); + + if ( endPtr != NULL ) + { + if ( *endPtr != '\0' ) + { + portNum = defaultPort; + } + } + } + + if ( portNum < 1024 ) return FALSE; + if ( portNum >= 0xFFFF ) return FALSE; + + /* figure out the host part */ + +#if defined(_WIN32) || defined(_WIN32_WCE) + /* assert( strlen(host) >= 1 ); */ + if ( isdigit( host[0] ) ) + { + /* assume it is a ip address */ + unsigned long a = inet_addr(host); + /* cerr << "a=0x" << hex << a << dec ); */ + + *ip = ntohl( a ); + } + else + { + /* assume it is a host name */ + h = gethostbyname( host ); + + if ( h == NULL ) + { + /*int err = getErrno();*/ + + /* ortp_message("stun: error was %i\n", err); */ + /* std::cerr << "error was " << err << std::endl; */ + /* assert( err != WSANOTINITIALISED ); */ + + *ip = ntohl( 0x7F000001L ); + + return FALSE; + } + else + { + sin_addr = *(struct in_addr*)h->h_addr; + *ip = ntohl( sin_addr.s_addr ); + } + } + +#else + h = gethostbyname( host ); + if ( h == NULL ) + { + /* + int err = getErrno(); + ortp_message("stun: error was %i\n", err); + */ + *ip = ntohl( 0x7F000001L ); + return FALSE; + } + else + { + sin_addr = *(struct in_addr*)h->h_addr; + *ip = ntohl( sin_addr.s_addr ); + } +#endif + + *portVal = portNum; + + return TRUE; +} + + +bool_t +stunParseServerName( char* name, StunAddress4 *addr) +{ + /* assert(name); */ + + /* TODO - put in DNS SRV stuff. */ + + bool_t ret = stunParseHostName( name, &addr->addr, &addr->port, 3478); + if ( ret != TRUE ) + { + addr->port=0xFFFF; + } + return ret; +} + + +static void +stunCreateErrorResponse(StunMessage *response, int cl, int number, const char* msg) +{ + response->msgHdr.msgType = BindErrorResponseMsg; + response->hasErrorCode = TRUE; + response->errorCode.errorClass = cl; + response->errorCode.number = number; + strcpy(response->errorCode.reason, msg); +} + +#if 0 +static void +stunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg) +{ + response.msgHdr.msgType = SharedSecretErrorResponseMsg; + response.hasErrorCode = TRUE; + response.errorCode.errorClass = cl; + response.errorCode.number = number; + strcpy(response.errorCode.reason, msg); +} +#endif + +static void +stunCreateSharedSecretResponse(const StunMessage *request, const StunAddress4 *source, StunMessage *response) +{ + response->msgHdr.msgType = SharedSecretResponseMsg; + response->msgHdr.id = request->msgHdr.id; + + response->hasUsername = TRUE; + stunCreateUserName( source, &response->username); + + response->hasPassword = TRUE; + stunCreatePassword( &response->username, &response->password); +} + + +/* This funtion takes a single message sent to a stun server, parses + and constructs an apropriate repsonse - returns TRUE if message is + valid */ +bool_t +stunServerProcessMsg( char* buf, + unsigned int bufLen, + StunAddress4 *from, + StunAddress4 *secondary, + StunAddress4 *myAddr, + StunAddress4 *altAddr, + StunMessage *resp, + StunAddress4 *destination, + StunAtrString *hmacPassword, + bool_t* changePort, + bool_t* changeIp, + bool_t verbose) +{ + int i; + StunMessage req; + StunAddress4 mapped; + StunAddress4 respondTo; + UInt32 flags; + bool_t ok; + /* set up information for default response */ + + memset( &req, 0 , sizeof(req) ); + memset( resp, 0 , sizeof(*resp) ); + + *changeIp = FALSE; + *changePort = FALSE; + + ok = stunParseMessage( buf,bufLen, &req, verbose); + + if (!ok) /* Complete garbage, drop it on the floor */ + { + if (verbose) ortp_error("stun: Request did not parse"); + return FALSE; + } + if (verbose) ortp_message("stun: Request parsed ok"); + + mapped = req.mappedAddress.ipv4; + respondTo = req.responseAddress.ipv4; + flags = req.changeRequest.value; + + if (req.msgHdr.msgType==SharedSecretRequestMsg) + { + if(verbose) ortp_message("stun: Received SharedSecretRequestMsg on udp. send error 433."); + /* !cj! - should fix so you know if this came over TLS or UDP */ + stunCreateSharedSecretResponse(&req, from, resp); + /* stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS"); */ + return TRUE; + + } + else if (req.msgHdr.msgType==BindRequestMsg) + { + if (!req.hasMessageIntegrity) + { + if (verbose) ortp_message("stun: BindRequest does not contain MessageIntegrity"); + + if (0) /* !jf! mustAuthenticate */ + { + if(verbose) ortp_message("stun: Received BindRequest with no MessageIntegrity. Sending 401."); + stunCreateErrorResponse(resp, 4, 1, "Missing MessageIntegrity"); + return TRUE; + } + } + else + { + if (!req.hasUsername) + { + if (verbose) ortp_message("stun: No UserName. Send 432."); + stunCreateErrorResponse(resp, 4, 32, "No UserName and contains MessageIntegrity"); + return TRUE; + } + else + { + if (verbose) ortp_message("stun: Validating username: %s", req.username.value ); + /* !jf! could retrieve associated password from provisioning here */ + if (strcmp(req.username.value, "test") == 0) + { + if (0) + { + /* !jf! if the credentials are stale */ + stunCreateErrorResponse(resp, 4, 30, "Stale credentials on BindRequest"); + return TRUE; + } + else + { + unsigned char hmac[20]; + if (verbose) ortp_message("stun: Validating MessageIntegrity"); + /* need access to shared secret */ + +#ifndef NOSSL + { + unsigned int hmacSize=20; + + HMAC(EVP_sha1(), + "1234", 4, + (const unsigned char*) buf, bufLen-20-4, + hmac, &hmacSize); + /*HMAC(EVP_sha1(), + "1234", 4, + reinterpret_cast(buf), bufLen-20-4, + hmac, &hmacSize); + //assert(hmacSize == 20); + */ + } +#endif + + if (memcmp(buf, hmac, 20) != 0) + { + if (verbose) ortp_warning("stun: MessageIntegrity is bad. Sending "); + stunCreateErrorResponse(resp, 4, 3, "Unknown username. Try test with password 1234"); + return TRUE; + } + + /* need to compute this later after message is filled in */ + resp->hasMessageIntegrity = TRUE; + /* assert(req.hasUsername); */ + resp->hasUsername = TRUE; + resp->username = req.username; /* copy username in */ + } + } + else + { + if (verbose) ortp_message("stun: Invalid username: %s Send 430", req.username.value); + } + } + } + + /* TODO !jf! should check for unknown attributes here and send 420 listing the + unknown attributes. */ + + if ( respondTo.port == 0 ) + { + /* respondTo = from; */ + memcpy(&respondTo, from, sizeof(StunAddress4)); + } + if ( mapped.port == 0 ) + { + /* mapped = from; */ + memcpy(&mapped, from, sizeof(StunAddress4)); + } + + *changeIp = ( flags & ChangeIpFlag )?TRUE:FALSE; + *changePort = ( flags & ChangePortFlag )?TRUE:FALSE; + + if (verbose) + { + ortp_message("stun: Request is valid:\n"); + ortp_message("stun: \t flags= %i\n", flags ); + ortp_message("stun: \t changeIp= %i\n", *changeIp ); + ortp_message("stun: \t changePort=%i\n", *changePort ); + ortp_message("stun: \t from= %i\n", from->addr ); + ortp_message("stun: \t respond to= %i\n", respondTo.addr ); + ortp_message("stun: \t mapped= %i\n", mapped.addr ); + } + + /* form the outgoing message */ + resp->msgHdr.msgType = BindResponseMsg; + for (i=0; i<16; i++ ) + { + resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i]; + } + + if ( req.xorOnly == FALSE ) + { + resp->hasMappedAddress = TRUE; + resp->mappedAddress.ipv4.port = mapped.port; + resp->mappedAddress.ipv4.addr = mapped.addr; + } + + if (1) /* do xorMapped address or not */ + { + UInt16 id16; + UInt32 id32; + resp->hasXorMappedAddress = TRUE; + id16 = req.msgHdr.id.octet[7]<<8 + | req.msgHdr.id.octet[6]; + id32 = req.msgHdr.id.octet[7]<<24 + | req.msgHdr.id.octet[6]<<16 + | req.msgHdr.id.octet[5]<<8 + | req.msgHdr.id.octet[4]; + resp->xorMappedAddress.ipv4.port = mapped.port^id16; + resp->xorMappedAddress.ipv4.addr = mapped.addr^id32; + } + + resp->hasSourceAddress = TRUE; + resp->sourceAddress.ipv4.port = (*changePort) ? altAddr->port : myAddr->port; + resp->sourceAddress.ipv4.addr = (*changeIp) ? altAddr->addr : myAddr->addr; + + resp->hasChangedAddress = TRUE; + resp->changedAddress.ipv4.port = altAddr->port; + resp->changedAddress.ipv4.addr = altAddr->addr; + + if ( secondary->port != 0 ) + { + resp->hasSecondaryAddress = TRUE; + resp->secondaryAddress.ipv4.port = secondary->port; + resp->secondaryAddress.ipv4.addr = secondary->addr; + } + + if ( req.hasUsername && req.username.sizeValue > 0 ) + { + /* copy username in */ + resp->hasUsername = TRUE; + /* assert( req.username.sizeValue % 4 == 0 ); */ + /* assert( req.username.sizeValue < STUN_MAX_STRING ); */ + memcpy( resp->username.value, req.username.value, req.username.sizeValue ); + resp->username.sizeValue = req.username.sizeValue; + } + + if (1) /* add ServerName */ + { + const char serverName[] = "Vovida.org " STUN_VERSION; /* must pad to mult of 4 */ + resp->hasServerName = TRUE; + + /* assert( sizeof(serverName) < STUN_MAX_STRING ); */ + /* cerr << "sizeof serverName is " << sizeof(serverName) ); */ + /* assert( sizeof(serverName)%4 == 0 ); */ + memcpy( resp->serverName.value, serverName, sizeof(serverName)); + resp->serverName.sizeValue = sizeof(serverName); + } + + if ( req.hasMessageIntegrity & req.hasUsername ) + { + /* this creates the password that will be used in the HMAC when then */ + /* messages is sent */ + stunCreatePassword( &req.username, hmacPassword ); + } + + if (req.hasUsername && (req.username.sizeValue > 64 ) ) + { + UInt32 source; + /* assert( sizeof(int) == sizeof(UInt32) ); */ + + sscanf(req.username.value, "%x", &source); + resp->hasReflectedFrom = TRUE; + resp->reflectedFrom.ipv4.port = 0; + resp->reflectedFrom.ipv4.addr = source; + } + + destination->port = respondTo.port; + destination->addr = respondTo.addr; + + return TRUE; + } + else + { + if (verbose) ortp_error("stun: Unknown or unsupported request "); + return FALSE; + } + + /* assert(0); */ + return FALSE; +} + +bool_t +stunInitServer(StunServerInfo *info, const StunAddress4 *myAddr, const StunAddress4 *altAddr, int startMediaPort, bool_t verbose ) +{ + /* assert( myAddr.port != 0 ); */ + /* assert( altAddr.port!= 0 ); */ + /* assert( myAddr.addr != 0 ); */ + /* assert( altAddr.addr != 0 ); */ + + /* info->myAddr = myAddr; */ + info->myAddr.port = myAddr->port; + info->myAddr.addr = myAddr->addr; + + /* info->altAddr = altAddr; */ + info->altAddr.port = altAddr->port; + info->altAddr.addr = altAddr->addr; + + info->myFd = INVALID_SOCKET; + info->altPortFd = INVALID_SOCKET; + info->altIpFd = INVALID_SOCKET; + info->altIpPortFd = INVALID_SOCKET; + + memset(info->relays, 0, sizeof(info->relays)); + if (startMediaPort > 0) + { + int i; + info->relay = TRUE; + + for (i=0; irelays[i]; + relay->relayPort = startMediaPort+i; + relay->fd = 0; + relay->expireTime = 0; + } + } + else + { + info->relay = FALSE; + } + + if ((info->myFd = openPort(myAddr->port, myAddr->addr,verbose)) == INVALID_SOCKET) + { + ortp_error("stun: Can't open %i\n", myAddr->addr ); + stunStopServer(info); + + return FALSE; + } + /*if (verbose) ortp_message("stun: Opened " << myAddr->addr << ":" << myAddr->port << " --> " << info->myFd ); */ + + if ((info->altPortFd = openPort(altAddr->port,myAddr->addr,verbose)) == INVALID_SOCKET) + { + ortp_error("stun: Can't open %i\n", myAddr->addr ); + stunStopServer(info); + return FALSE; + } + /* if (verbose) ortp_message("stun: Opened " << myAddr->addr << ":" << altAddr->port << " --> " << info->altPortFd ); */ + + + info->altIpFd = INVALID_SOCKET; + if ( altAddr->addr != 0 ) + { + if ((info->altIpFd = openPort( myAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET) + { + ortp_error("stun: Can't open %i\n", altAddr->addr ); + stunStopServer(info); + return FALSE; + } + /* if (verbose) ortp_message("stun: Opened " << altAddr->addr << ":" << myAddr->port << " --> " << info->altIpFd ); */ + } + + info->altIpPortFd = INVALID_SOCKET; + if ( altAddr->addr != 0 ) + { if ((info->altIpPortFd = openPort(altAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET) + { + ortp_error("stun: Can't open %i\n", altAddr->addr ); + stunStopServer(info); + return FALSE; + } + /* if (verbose) ortp_message("stun: Opened " << altAddr->addr << ":" << altAddr->port << " --> " << info->altIpPortFd ); */ + } + + return TRUE; +} + +void +stunStopServer(StunServerInfo *info) +{ + if (info->myFd > 0) closesocket(info->myFd); + if (info->altPortFd > 0) closesocket(info->altPortFd); + if (info->altIpFd > 0) closesocket(info->altIpFd); + if (info->altIpPortFd > 0) closesocket(info->altIpPortFd); + + if (info->relay) + { + int i; + for (i=0; irelays[i]; + if (relay->fd) + { + closesocket(relay->fd); + relay->fd = 0; + } + } + } +} + +#if 0 /* no usefull here */ + +bool_t +stunServerProcess(StunServerInfo *info, bool_t verbose) +{ + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + bool_t ok = FALSE; + bool_t recvAltIp =FALSE; + bool_t recvAltPort = FALSE; + + fd_set fdSet; +#if defined(_WIN32) || defined(_WIN32_WCE) + unsigned int maxFd=0; +#else + int maxFd=0; +#endif + struct timeval tv; + int e; + + FD_ZERO(&fdSet); + FD_SET(info->myFd,&fdSet); + if ( info->myFd >= maxFd ) maxFd=info->myFd+1; + FD_SET(info->altPortFd,&fdSet); + if ( info->altPortFd >= maxFd ) maxFd=info->altPortFd+1; + + if ( info->altIpFd != INVALID_SOCKET ) + { + FD_SET(info->altIpFd,&fdSet); + if (info->altIpFd>=maxFd) maxFd=info->altIpFd+1; + } + if ( info->altIpPortFd != INVALID_SOCKET ) + { + FD_SET(info->altIpPortFd,&fdSet); + if (info->altIpPortFd>=maxFd) maxFd=info->altIpPortFd+1; + } + + if (info->relay) + { + int i; + for (i=0; irelays[i]; + if (relay->fd) + { + FD_SET(relay->fd, &fdSet); + if (relay->fd >= maxFd) maxFd=relay->fd+1; + } + } + } + + if ( info->altIpFd != INVALID_SOCKET ) + { + FD_SET(info->altIpFd,&fdSet); + if (info->altIpFd>=maxFd) maxFd=info->altIpFd+1; + } + if ( info->altIpPortFd != INVALID_SOCKET ) + { + FD_SET(info->altIpPortFd,&fdSet); + if (info->altIpPortFd>=maxFd) maxFd=info->altIpPortFd+1; + } + + tv.tv_sec = 0; + tv.tv_usec = 1000; + + e = select( maxFd, &fdSet, NULL,NULL, &tv ); + if (e < 0) + { + int err = getErrno(); +#if !defined(_WIN32_WCE) + ortp_error("stun: Error on select: %s\n", strerror(err) ); +#else + ortp_error("stun: Error on select: %i\n", err ); +#endif + } + else if (e >= 0) + { + StunAddress4 from; + int relayPort = 0; + + bool_t changePort = FALSE; + bool_t changeIp = FALSE; + + StunMessage resp; + StunAddress4 dest; + StunAtrString hmacPassword; + + StunAddress4 secondary; + + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = sizeof(buf); + + hmacPassword.sizeValue = 0; + secondary.port = 0; + secondary.addr = 0; + + /* do the media relaying */ + if (info->relay) + { + time_t now; + int i; +#if !defined(_WIN32_WCE) + now = time(0); +#else + DWORD timemillis = GetTickCount(); + now = timemillis/1000; +#endif + for (i=0; irelays[i]; + if (relay->fd) + { + if (FD_ISSET(relay->fd, &fdSet)) + { + char msg[MAX_RTP_MSG_SIZE]; + int msgLen = sizeof(msg); + + StunAddress4 rtpFrom; + ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose); + if (ok) + { + sendMessage(info->myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose); + relay->expireTime = now + MEDIA_RELAY_TIMEOUT; + if ( verbose ) ortp_message("stun: Relay packet on %i from %i -> %i", + relay->fd, + rtpFrom.addr, + relay->destination.addr + ); + } + } + else if (now > relay->expireTime) + { + closesocket(relay->fd); + relay->fd = 0; + } + } + } + } + + + if (FD_ISSET(info->myFd,&fdSet)) + { + if (verbose) ortp_message("stun: received on A1:P1"); + recvAltIp = FALSE; + recvAltPort = FALSE; + ok = getMessage( info->myFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else if (FD_ISSET(info->altPortFd, &fdSet)) + { + if (verbose) ortp_message("stun: received on A1:P2"); + recvAltIp = FALSE; + recvAltPort = TRUE; + ok = getMessage( info->altPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else if ( (info->altIpFd!=INVALID_SOCKET) && FD_ISSET(info->altIpFd,&fdSet)) + { + if (verbose) ortp_message("stun: received on A2:P1"); + recvAltIp = TRUE; + recvAltPort = FALSE; + ok = getMessage( info->altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose); + } + else if ( (info->altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info->altIpPortFd, &fdSet)) + { + if (verbose) ortp_message("stun: received on A2:P2"); + recvAltIp = TRUE; + recvAltPort = TRUE; + ok = getMessage( info->altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); + } + else + { + return TRUE; + } + + if (info->relay) + { + int i; + for (i=0; irelays[i]; + if (relay->destination.addr == from.addr && + relay->destination.port == from.port) + { + relayPort = relay->relayPort; + relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; + break; + } + } + + if (relayPort == 0) + { + int i; + for (i=0; irelays[i]; + if (relay->fd == 0) + { + if ( verbose ) ortp_message("stun: Open relay port %i\n", relay->relayPort ); + relay->fd = openPort(relay->relayPort, info->myAddr.addr, verbose); + relay->destination.addr = from.addr; + relay->destination.port = from.port; + relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; + relayPort = relay->relayPort; + break; + } + } + } + } + + if ( !ok ) + { + if ( verbose ) ortp_message("stun: Get message did not return a valid message\n"); + return TRUE; + } + + if ( verbose ) ortp_message("stun: Got a request (len=%i) from %i", msgLen, from.addr); + + if ( msgLen <= 0 ) + { + return TRUE; + } + + if (info->relay && relayPort) + { + secondary = from; + + from.addr = info->myAddr.addr; + from.port = relayPort; + } + + ok = stunServerProcessMsg( msg, msgLen, &from, &secondary, + recvAltIp ? &info->altAddr : &info->myAddr, + recvAltIp ? &info->myAddr : &info->altAddr, + &resp, + &dest, + &hmacPassword, + &changePort, + &changeIp, + verbose ); + + if ( !ok ) + { + if ( verbose ) ortp_error("stun: Failed to parse message"); + return TRUE; + } + + len = stunEncodeMessage( &resp, buf, len, &hmacPassword,verbose ); + + if ( dest.addr == 0 ) ok=FALSE; + if ( dest.port == 0 ) ok=FALSE; + + if ( ok ) + { + /* assert( dest.addr != 0 ); */ + /* assert( dest.port != 0 ); */ + + Socket sendFd; + + bool_t sendAltIp = recvAltIp; /* send on the received IP address */ + bool_t sendAltPort = recvAltPort; /* send on the received port */ + + if ( changeIp ) sendAltIp = !sendAltIp; /* if need to change IP, then flip logic */ + if ( changePort ) sendAltPort = !sendAltPort; /* if need to change port, then flip logic */ + + if ( !sendAltPort ) + { + if ( !sendAltIp ) + { + sendFd = info->myFd; + } + else + { + sendFd = info->altIpFd; + } + } + else + { + if ( !sendAltIp ) + { + sendFd = info->altPortFd; + } + else + { + sendFd = info->altIpPortFd; + } + } + + if ( sendFd != INVALID_SOCKET ) + { + sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose ); + } + } + } + + return TRUE; +} +#endif + +int +stunFindLocalInterfaces(UInt32* addresses,int maxRet) +{ +#if defined(WIN32) || defined(_WIN32_WCE) || defined(__sparc__) + return 0; +#else + struct ifconf ifc; + int e; + + int s = socket( AF_INET, SOCK_DGRAM, 0 ); + int len = 100 * sizeof(struct ifreq); + + char buf[ 100 * sizeof(struct ifreq) ]; + char *ptr; + int tl; + int count=0; + + ifc.ifc_len = len; + ifc.ifc_buf = buf; + + e = ioctl(s,SIOCGIFCONF,&ifc); + ptr = buf; + tl = ifc.ifc_len; + + while ( (tl > 0) && ( count < maxRet) ) + { + struct ifreq* ifr = (struct ifreq *)ptr; + struct ifreq ifr2; + struct sockaddr a; + struct sockaddr_in* addr; + + UInt32 ai; + int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr); + tl -= si; + ptr += si; + /* char* name = ifr->ifr_ifrn.ifrn_name; */ + /* cerr << "name = " << name ); */ + + ifr2 = *ifr; + + e = ioctl(s,SIOCGIFADDR,&ifr2); + if ( e == -1 ) + { + break; + } + + /* cerr << "ioctl addr e = " << e ; */ + + a = ifr2.ifr_addr; + addr = (struct sockaddr_in*) &a; + + ai = ntohl( addr->sin_addr.s_addr ); + if ((int)((ai>>24)&0xFF) != 127) + { + addresses[count++] = ai; + } + + } + + closesocket(s); + + return count; +#endif +} + + +void +stunBuildReqSimple( StunMessage* msg, + const StunAtrString *username, + bool_t changePort, bool_t changeIp, unsigned int id ) +{ + int i; + /* assert( msg ); */ + memset( msg , 0 , sizeof(*msg) ); + + msg->msgHdr.msgType = BindRequestMsg; + + for ( i=0; i<16; i=i+4 ) + { + /* assert(i+3<16); */ + int r = stunRand(); + msg->msgHdr.id.octet[i+0]= r>>0; + msg->msgHdr.id.octet[i+1]= r>>8; + msg->msgHdr.id.octet[i+2]= r>>16; + msg->msgHdr.id.octet[i+3]= r>>24; + } + + if ( id != 0 ) + { + msg->msgHdr.id.octet[0] = id; + } + + msg->hasChangeRequest = TRUE; + msg->changeRequest.value =(changeIp?ChangeIpFlag:0) | + (changePort?ChangePortFlag:0); + + if ( username->sizeValue > 0 ) + { + msg->hasUsername = TRUE; + /* msg->username = username; */ + memcpy(&msg->username, username, sizeof(StunAtrString)); + } +} + + +static void +stunSendTest( Socket myFd, StunAddress4 *dest, + const StunAtrString *username, const StunAtrString *password, + int testNum, bool_t verbose ) +{ + /* assert( dest.addr != 0 ); */ + /* assert( dest.port != 0 ); */ + + bool_t changePort=FALSE; + bool_t changeIP=FALSE; + bool_t discard=FALSE; + + StunMessage req; + char buf[STUN_MAX_MESSAGE_SIZE]; + int len = STUN_MAX_MESSAGE_SIZE; + + switch (testNum) + { + case 1: + case 10: + case 11: + break; + case 2: + /* changePort=TRUE; */ + changeIP=TRUE; + break; + case 3: + changePort=TRUE; + break; + case 4: + changeIP=TRUE; + break; + case 5: + discard=TRUE; + break; + default: + ortp_error("stun: Test %i is unkown\n", testNum); + return ; /* error */ + } + + memset(&req, 0, sizeof(StunMessage)); + + stunBuildReqSimple( &req, username, + changePort , changeIP , + testNum ); + + len = stunEncodeMessage( &req, buf, len, password,verbose ); + + if ( verbose ) + { + ortp_message("stun: About to send msg of len %i to %s\n", len, ipaddr(dest) ); + } + + sendMessage( myFd, buf, len, dest->addr, dest->port, verbose ); + + /* add some delay so the packets don't get sent too quickly */ +#if defined(_WIN32_WCE) + Sleep (10); +#elif defined(WIN32)/* !cj! TODO - should fix this up in windows */ + { + clock_t now = clock(); + /* assert( CLOCKS_PER_SEC == 1000 ); */ + while ( clock() <= now+10 ) { }; + } +#else + usleep(10*1000); +#endif + +} + + +void +stunGetUserNameAndPassword( const StunAddress4 *dest, + StunAtrString* username, + StunAtrString* password) +{ + /* !cj! This is totally bogus - need to make TLS connection to dest and get a */ + /* username and password to use */ + stunCreateUserName(dest, username); + stunCreatePassword(username, password); +} + + +int +stunTest( StunAddress4 *dest, int testNum, bool_t verbose, StunAddress4* sAddr , StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr) +{ + /* assert( dest.addr != 0 ); */ + /* assert( dest.port != 0 ); */ + + int port = randomPort(); + UInt32 interfaceIp=0; + Socket myFd; + StunAtrString username; + StunAtrString password; + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = STUN_MAX_MESSAGE_SIZE; + StunAddress4 from; + StunMessage resp; + bool_t ok; + + if (sAddr) + { + interfaceIp = sAddr->addr; + if ( sAddr->port != 0 ) + { + port = sAddr->port; + } + } + myFd = openPort(port,interfaceIp,verbose); + if ( myFd == INVALID_SOCKET) + return -1; + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, &username, &password ); +#endif + + stunSendTest( myFd, dest, &username, &password, testNum, verbose ); + + ok = getMessage( myFd, + msg, + &msgLen, + &from.addr, + &from.port,verbose ); + closesocket(myFd); + if (!ok) + return -1; + + memset(&resp, 0, sizeof(StunMessage)); + + if ( verbose ) ortp_message("stun: Got a response"); + ok = stunParseMessage( msg,msgLen, &resp,verbose ); + + if ( verbose ) + { + ortp_message("stun: \t ok=%i\n", ok ); +#if defined(WIN32) || defined(_WIN32_WCE) + ortp_message("stun: \t id=%u\n", *(unsigned int*)&resp.msgHdr.id ); +#endif + ortp_message("stun: \t mappedAddr=%i\n", resp.mappedAddress.ipv4.addr ); + ortp_message("stun: \t changedAddr=%i\n", resp.changedAddress.ipv4.addr ); + } + + if (sAddr) + { + sAddr->port = port; + } + + if (sMappedAddr) + { + sMappedAddr->port = resp.mappedAddress.ipv4.port; + sMappedAddr->addr = resp.mappedAddress.ipv4.addr; + } + + if (sChangedAddr) + { + sChangedAddr->port = resp.changedAddress.ipv4.port; + sChangedAddr->addr = resp.changedAddress.ipv4.addr; + } + + if (ok) + return 0; + else + return -1; +} + + +NatType +stunNatType( StunAddress4 *dest, + bool_t verbose, + bool_t* preservePort, /* if set, is return for if NAT preservers ports or not */ + bool_t* hairpin, /* if set, is the return for if NAT will hairpin packets */ + int port, /* port to use for the test, 0 to choose random port */ + StunAddress4* sAddr /* NIC to use */ + ) +{ + /* assert( dest.addr != 0 ); */ + /* assert( dest.port != 0 ); */ + UInt32 interfaceIp=0; + Socket myFd1; + Socket myFd2; + + bool_t respTestI=FALSE; + bool_t isNat=TRUE; + StunAddress4 testIchangedAddr; + StunAddress4 testImappedAddr; + bool_t respTestI2=FALSE; + bool_t mappedIpSame = TRUE; + StunAddress4 testI2mappedAddr; + /* StunAddress4 testI2dest=dest; */ + StunAddress4 testI2dest; + bool_t respTestII=FALSE; + bool_t respTestIII=FALSE; + bool_t respTestHairpin=FALSE; + StunAtrString username; + StunAtrString password; + int count=0; + UInt64 second_started; + UInt64 second_elapsed; + Socket s; + + if ( hairpin ) + { + *hairpin = FALSE; + } + + if ( port == 0 ) + { + port = randomPort(); + } + + if (sAddr) + { + interfaceIp = sAddr->addr; + } + myFd1 = openPort(port,interfaceIp,verbose); + myFd2 = openPort(port+1,interfaceIp,verbose); + + if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) ) + { + ortp_error("stun: Some problem opening port/interface to send on\n"); + return StunTypeFailure; + } + + /* assert( myFd1 != INVALID_SOCKET ); */ + /* assert( myFd2 != INVALID_SOCKET ); */ + + memcpy(&testI2dest, dest, sizeof(StunAddress4)); + + memset(&testImappedAddr,0,sizeof(testImappedAddr)); + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + /* stunSendTest( myFd1, dest, username, password, 1, verbose ); */ + + + second_started = stunGetSystemTimeSecs(); + second_elapsed = 1; + + while ( count < 7 && second_elapsed < 5) + { + struct timeval tv; + fd_set fdSet; + int err; + int e; + +#if defined(WIN32) || defined(_WIN32_WCE) + unsigned int fdSetSize; +#else + int fdSetSize; +#endif + + second_elapsed = stunGetSystemTimeSecs() - second_started ; + + FD_ZERO(&fdSet); fdSetSize=0; + FD_SET(myFd1,&fdSet); fdSetSize = (myFd1+1>fdSetSize) ? myFd1+1 : fdSetSize; + FD_SET(myFd2,&fdSet); fdSetSize = (myFd2+1>fdSetSize) ? myFd2+1 : fdSetSize; + tv.tv_sec=0; + tv.tv_usec=500*1000; /* 150 ms */ + if ( count == 0 ) tv.tv_usec=0; + + err = select(fdSetSize, &fdSet, NULL, NULL, &tv); + e = getErrno(); + if ( err == SOCKET_ERROR ) + { + /* error occured */ +#if !defined(_WIN32_WCE) + ortp_error("stun: Error %i %s in select\n", e, strerror(e)); +#else + ortp_error("stun: Error %i in select\n", e); +#endif + closesocket(myFd1); /* AMD */ + closesocket(myFd2); /* AMD */ + return StunTypeFailure; + } + else if ( err == 0 ) + { + /* timeout occured */ + count++; + + if ( !respTestI ) + { + stunSendTest( myFd1, dest, &username, &password, 1 ,verbose ); + } + + if ( (!respTestI2) && respTestI ) + { + /* check the address to send to if valid */ + if ( ( testI2dest.addr != 0 ) && + ( testI2dest.port != 0 ) ) + { + stunSendTest( myFd1, &testI2dest, &username, &password, 10 ,verbose); + } + } + + if ( !respTestII ) + { + stunSendTest( myFd2, dest, &username, &password, 2 ,verbose ); + } + + if ( !respTestIII ) + { + stunSendTest( myFd2, dest, &username, &password, 3 ,verbose ); + } + + if ( respTestI && (!respTestHairpin) ) + { + if ( ( testImappedAddr.addr != 0 ) && + ( testImappedAddr.port != 0 ) ) + { + stunSendTest( myFd1, &testImappedAddr, &username, &password, 11 ,verbose ); + } + } + } + else + { + int i; + /* if (verbose) ortp_message("stun: -----------------------------------------"); */ + /* assert( err>0 ); */ + /* data is avialbe on some fd */ + + for ( i=0; i<2; i++) + { + Socket myFd; + if ( i==0 ) + { + myFd=myFd1; + } + else + { + myFd=myFd2; + } + + if ( myFd!=INVALID_SOCKET ) + { + if ( FD_ISSET(myFd,&fdSet) ) + { + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + StunAddress4 from; + StunMessage resp; + + getMessage( myFd, + msg, + &msgLen, + &from.addr, + &from.port,verbose ); + + memset(&resp, 0, sizeof(StunMessage)); + + stunParseMessage( msg,msgLen, &resp,verbose ); + + if ( verbose ) + { + ortp_message("stun: Received message of type %i id=%i\n", + resp.msgHdr.msgType, + (int)(resp.msgHdr.id.octet[0]) ); + } + + switch( resp.msgHdr.id.octet[0] ) + { + case 1: + { + if ( !respTestI ) + { + + testIchangedAddr.addr = resp.changedAddress.ipv4.addr; + testIchangedAddr.port = resp.changedAddress.ipv4.port; + testImappedAddr.addr = resp.mappedAddress.ipv4.addr; + testImappedAddr.port = resp.mappedAddress.ipv4.port; + + if ( preservePort ) + { + *preservePort = ( testImappedAddr.port == port ); + } + + testI2dest.addr = resp.changedAddress.ipv4.addr; + + if (sAddr) + { + sAddr->port = testImappedAddr.port; + sAddr->addr = testImappedAddr.addr; + } + + count = 0; + } + respTestI=TRUE; + } + break; + case 2: + { + respTestII=TRUE; + } + break; + case 3: + { + respTestIII=TRUE; + } + break; + case 10: + { + if ( !respTestI2 ) + { + testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr; + testI2mappedAddr.port = resp.mappedAddress.ipv4.port; + + mappedIpSame = FALSE; + if ( (testI2mappedAddr.addr == testImappedAddr.addr ) && + (testI2mappedAddr.port == testImappedAddr.port )) + { + mappedIpSame = TRUE; + } + + + } + respTestI2=TRUE; + } + break; + case 11: + { + + if ( hairpin ) + { + *hairpin = TRUE; + } + respTestHairpin = TRUE; + } + break; + } + } + } + } + } + } + + closesocket(myFd1); /* AMD */ + closesocket(myFd2); /* AMD */ + + /* see if we can bind to this address */ + /* cerr << "try binding to " << testImappedAddr ); */ + s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, FALSE ); + if ( s != INVALID_SOCKET ) + { + isNat = FALSE; + /* cerr << "binding worked"); */ + } + else + { + isNat = TRUE; + /* cerr << "binding failed"); */ + } + + closesocket(s); /* AMD */ + + if (verbose) + { + ortp_message("stun: test I = %i\n", respTestI ); + ortp_message("stun: test II = %i\n", respTestII ); + ortp_message("stun: test III = %i\n", respTestIII ); + ortp_message("stun: test I(2) = %i\n", respTestI2 ); + ortp_message("stun: is nat = %i\n", isNat); + ortp_message("stun: mapped IP same = %i\n", mappedIpSame ); + } + + /* implement logic flow chart from draft RFC */ + if ( respTestI ) + { + if ( isNat ) + { + if (respTestII) + { + return StunTypeConeNat; + } + else + { + if ( mappedIpSame ) + { + if ( respTestIII ) + { + return StunTypeRestrictedNat; + } + else + { + return StunTypePortRestrictedNat; + } + } + else + { + return StunTypeSymNat; + } + } + } + else + { + if (respTestII) + { + return StunTypeOpen; + } + else + { + return StunTypeSymFirewall; + } + } + } + else + { + return StunTypeBlocked; + } + + return StunTypeUnknown; +} + +int +stunOpenSocket( StunAddress4 *dest, StunAddress4* mapAddr, + int port, StunAddress4* srcAddr, + bool_t verbose ) +{ + /* assert( dest.addr != 0 ); */ + /* assert( dest.port != 0 ); */ + /* assert( mapAddr );*/ + unsigned int interfaceIp = 0; + Socket myFd; + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen = sizeof(msg); + + StunAtrString username; + StunAtrString password; + + StunAddress4 from; + StunMessage resp; + bool_t ok; + StunAddress4 mappedAddr; + + if ( port == 0 ) + { + port = randomPort(); + } + + if ( srcAddr ) + { + interfaceIp = srcAddr->addr; + } + + myFd = openPort(port,interfaceIp,verbose); + if (myFd == INVALID_SOCKET) + { + return myFd; + } + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + stunSendTest(myFd, dest, &username, &password, 1, 0/*FALSE*/ ); + + getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); + + memset(&resp, 0, sizeof(StunMessage)); + + ok = stunParseMessage( msg, msgLen, &resp,verbose ); + if (!ok) + { + closesocket(myFd); + return -1; + } + + mappedAddr = resp.mappedAddress.ipv4; + + /* + ortp_message("stun: --- stunOpenSocket --- "); + ortp_message("stun: \treq id=" << req.id ); + ortp_message("stun: \tresp id=" << id ); + ortp_message("stun: \tmappedAddr=" << mappedAddr ); + */ + + *mapAddr = mappedAddr; + + return myFd; +} + + +bool_t +stunOpenSocketPair(StunAddress4 *dest, + StunAddress4* mapAddr_rtp, + StunAddress4* mapAddr_rtcp, + int* fd1, int* fd2, + int port, StunAddress4* srcAddr, + bool_t verbose ) +{ + /* assert( dest.addr!= 0 ); */ + /* assert( dest.port != 0 ); */ + /* assert( mapAddr ); */ + + const int NUM=2; + char msg[STUN_MAX_MESSAGE_SIZE]; + int msgLen =sizeof(msg); + + StunAddress4 from; + int fd[2/*NUM*/]; + int i; + + unsigned int interfaceIp = 0; + + StunAtrString username; + StunAtrString password; + + StunAddress4 mappedAddr[2/*NUM*/]; + + if ( port == 0 ) + { + port = randomPort(); + } + + *fd1=-1; + *fd2=-1; + + if ( srcAddr ) + { + interfaceIp = srcAddr->addr; + } + + for( i=0; i 0) + { + closesocket(fd[--i]); + } + return FALSE; + } + } + + username.sizeValue = 0; + password.sizeValue = 0; + +#ifdef USE_TLS + stunGetUserNameAndPassword( dest, username, password ); +#endif + + for( i=0; i. + * + */ + +#include +#include +#include +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +#include + +#if defined(WIN32) || defined(_WIN32_WCE) + +#include +#include +/* #include */ + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include + +#include "ortp/stun_udp.h" +#include "ortp/ortp.h" + +#if !defined(WIN32) && !defined(_WIN32_WCE) +int getErrno() { return errno; } +#else +int getErrno() { return WSAGetLastError(); } +#endif + +Socket +openPort( unsigned short port, unsigned int interfaceIp, bool_t verbose ) +{ + struct sockaddr_in addr; + Socket fd; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if ( fd == INVALID_SOCKET ) + { + ortp_error("stun_udp: Could not create a UDP socket"); + return INVALID_SOCKET; + } + + memset((char*) &(addr),0, sizeof((addr))); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + if ( (interfaceIp != 0) && + ( interfaceIp != 0x100007f ) ) + { + addr.sin_addr.s_addr = htonl(interfaceIp); + if (verbose ) + { + ortp_message("Binding to interface 0x%lu\n",(unsigned long) htonl(interfaceIp)); + } + } + + if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) + { + int e = getErrno(); + + switch (e) + { + case 0: + { + ortp_error("stun_udp: Could not bind socket");; + return INVALID_SOCKET; + } + case EADDRINUSE: + { + ortp_error("stun_udp: Port %i for receiving UDP is in use", port); + return INVALID_SOCKET; + } + break; + case EADDRNOTAVAIL: + { + if ( verbose ) + { + ortp_error("stun_udp: Cannot assign requested address"); + } + return INVALID_SOCKET; + } + break; + default: + { +#if !defined(_WIN32_WCE) + ortp_error("stun_udp: Could not bind UDP receive port Error=%i %s", + e, strerror(e)); +#else + ortp_error("stun_udp: Could not bind UDP receive port Error=%i", + e); +#endif + return INVALID_SOCKET; + } + break; + } + } + if ( verbose ) + { + ortp_message("stun: opened port %i with fd %i\n", port, fd); + } + + /* assert( fd != INVALID_SOCKET ); */ + + return fd; +} + + +bool_t +getMessage( Socket fd, char* buf, int* len, + unsigned int* srcIp, unsigned short* srcPort, + bool_t verbose) +{ + /* assert( fd != INVALID_SOCKET ); */ + + int originalSize = *len; + struct sockaddr_in from; + int fromLen = sizeof(from); + + + int err; + struct timeval tv; + fd_set fdSet; +#if defined(WIN32) || defined(_WIN32_WCE) + unsigned int fdSetSize; +#else + int fdSetSize; +#endif + + if (originalSize <= 0) + { + return FALSE; + } + + tv.tv_sec=1; + tv.tv_usec=0; /* 150 ms */ + FD_ZERO(&fdSet); fdSetSize=0; + FD_SET(fd,&fdSet); fdSetSize = fd+1; + + err = select(fdSetSize, &fdSet, NULL, NULL, &tv); + if ( err == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case ENOTSOCK: + ortp_error("stun_udp: Error fd not a socket"); + break; + case ECONNRESET: + ortp_error("stun_udp: Error connection reset - host not reachable"); + break; + + default: + ortp_error("stun_udp: Socket Error=%i", e); + } + return FALSE; + } + + if (err==0) + { + ortp_error("stun_udp: Connection timeout with stun server!"); + *len = 0; + return FALSE; + } + + if (FD_ISSET (fd, &fdSet)) + { + *len = recvfrom(fd, + buf, + originalSize, + 0, + (struct sockaddr *)&from, + (socklen_t*)&fromLen); + + if ( *len == SOCKET_ERROR ) + { + int e = getErrno(); + + switch (e) + { + case ENOTSOCK: + ortp_error("stun_udp: Error fd not a socket"); + break; + case ECONNRESET: + ortp_error("stun_udp: Error connection reset - host not reachable"); + break; + + default: + ortp_error("stun_udp: Socket Error=%i", e); + } + + return FALSE; + } + + if ( *len < 0 ) + { + ortp_error("stun_udp: socket closed? negative len"); + return FALSE; + } + + if ( *len == 0 ) + { + ortp_error("stun_udp: socket closed? zero len"); + return FALSE; + } + + *srcPort = ntohs(from.sin_port); + *srcIp = ntohl(from.sin_addr.s_addr); + + if ( (*len)+1 >= originalSize ) + { + if (verbose) + { + ortp_error("stun_udp: Received a message that was too large"); + } + return FALSE; + } + buf[*len]=0; + + return TRUE; + } + return FALSE; +} + + +bool_t +sendMessage( Socket fd, char* buf, int l, + unsigned int dstIp, unsigned short dstPort, + bool_t verbose) +{ + int s; + + if (fd == INVALID_SOCKET) + return FALSE; + + if ( dstPort == 0 ) + { + /* sending on a connected port */ + s = send(fd,buf,l,0); + } + else + { + struct sockaddr_in to; + int toLen = sizeof(to); + if (dstIp == 0) + { + ortp_error("stun_udp: invalid IP provided (dstIP==0)"); + return FALSE; + } + + memset(&to,0,toLen); + + to.sin_family = AF_INET; + to.sin_port = htons(dstPort); + to.sin_addr.s_addr = htonl(dstIp); + + s = sendto(fd, buf, l, 0,(struct sockaddr*)&to, toLen); + } + + if ( s == SOCKET_ERROR ) + { + int e = getErrno(); + switch (e) + { + case ECONNREFUSED: + case EHOSTDOWN: + case EHOSTUNREACH: + { + /* quietly ignore this */ + } + break; + case EAFNOSUPPORT: + { + ortp_error("stun_udp: err EAFNOSUPPORT in send"); + } + break; + default: + { +#if !defined(_WIN32_WCE) + ortp_error("stun_udp: err %i %s in send", e, strerror(e)); +#else + ortp_error("stun_udp: err %i in send", e); +#endif + } + } + return FALSE; + } + + if ( s == 0 ) + { + ortp_error("stun_udp: no data sent in send"); + return FALSE; + } + + if ( s != l ) + { + if (verbose) + { + ortp_error("stun_udp: only %i out of %i bytes sent", s, l); + } + return FALSE; + } + + return TRUE; +} + + +void +initNetwork() +{ +#if defined(WIN32) || defined(_WIN32_WCE) + WORD wVersionRequested = MAKEWORD( 2, 2 ); + WSADATA wsaData; + int err; + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) + { + /* could not find a usable WinSock DLL */ + ortp_error("stun_udp: Could not load winsock"); + } + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + WSACleanup( ); + ortp_error("stun_udp: Wrong winsock (!= 2.2) version"); + } +#endif +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ + +/* Local Variables: + mode:c + c-file-style:"ellemtel" + c-file-offsets:((case-label . +)) + indent-tabs-mode:nil + End: +*/ diff --git a/linphone/oRTP/src/system b/linphone/oRTP/src/system new file mode 100644 index 000000000..50dcc4375 --- /dev/null +++ b/linphone/oRTP/src/system @@ -0,0 +1,15 @@ +*############################################################ +*# +*# $Header: /sources/linphone/linphone/oRTP/src/system,v 1.1 2002/02/25 08:41:53 smorlat Exp $ +*# +*# $Source: /sources/linphone/linphone/oRTP/src/system,v $ +*# $Revision: 1.1 $ +*# $Locker: $ +*# +*############################################################ +$VERSION 1 +$CONFIGURE Y +$LOADABLE Y +$TUNABLE +$$$ + diff --git a/linphone/oRTP/src/telephonyevents.c b/linphone/oRTP/src/telephonyevents.c new file mode 100644 index 000000000..538bdba4e --- /dev/null +++ b/linphone/oRTP/src/telephonyevents.c @@ -0,0 +1,421 @@ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "utils.h" +#include "rtpsession_priv.h" +#include + +PayloadType payload_type_telephone_event={ + PAYLOAD_AUDIO_PACKETIZED, /*type */ + 8000, /*clock rate */ + 0, /* bytes per sample N/A */ + NULL, /* zero pattern N/A*/ + 0, /*pattern_length N/A */ + 0, /* normal_bitrate */ + "telephone-event", /* MIME subtype */ + 0, /* Audio Channels N/A */ + 0 /*flags */ +}; + +/** + * Tells whether telephony events payload type is supported within the + * context of the rtp session. + * @param session a rtp session + * + * @return the payload type number used for telephony events if found, -1 if not found. +**/ +int rtp_session_telephone_events_supported(RtpSession *session) +{ + /* search for a telephony event payload in the current profile */ + session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event"); + session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event"); + /*printf("Telephone event pt is %i\n",session->telephone_events_pt);*/ + return session->snd.telephone_events_pt; +} + + +/** + * Tells whether telephone event payload type is supported for send within the + * context of the rtp session. + * @param session a rtp session + * + * @return the payload type number used for telephony events if found, -1 if not found. +**/ +int rtp_session_send_telephone_events_supported(RtpSession *session) +{ + /* search for a telephony event payload in the current profile */ + session->snd.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->snd.profile,"telephone-event"); + /*printf("Telephone event pt is %i\n",session->telephone_events_pt);*/ + return session->snd.telephone_events_pt; +} + +/** + * Tells whether telephone event payload type is supported for receiving within the + * context of the rtp session. + * @param session a rtp session + * + * @return the payload type number used for telephony events if found, -1 if not found. +**/int rtp_session_recv_telephone_events_supported(RtpSession *session) +{ + /* search for a telephony event payload in the current profile */ + session->rcv.telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->rcv.profile,"telephone-event"); + /*printf("Telephone event pt is %i\n",session->telephone_events_pt);*/ + return session->snd.telephone_events_pt; +} + + +/** + * Allocates a new rtp packet to be used to add named telephony events. The application can use + * then rtp_session_add_telephone_event() to add named events to the packet. + * Finally the packet has to be sent with rtp_session_sendm_with_ts(). + * + * @param session a rtp session. + * @param start boolean to indicate if the marker bit should be set. + * + * @return a message block containing the rtp packet if successfull, NULL if the rtp session + *cannot support telephony event (because the rtp profile it is bound to does not include + *a telephony event payload type). +**/ +mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start) +{ + mblk_t *mp; + rtp_header_t *rtp; + + return_val_if_fail(session->snd.telephone_events_pt!=-1,NULL); + + mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED); + if (mp==NULL) return NULL; + rtp=(rtp_header_t*)mp->b_rptr; + rtp->version = 2; + rtp->markbit=start; + rtp->padbit = 0; + rtp->extbit = 0; + rtp->cc = 0; + rtp->ssrc = session->snd.ssrc; + /* timestamp set later, when packet is sended */ + /*seq number set later, when packet is sended */ + + /*set the payload type */ + rtp->paytype=session->snd.telephone_events_pt; + + /*copy the payload */ + mp->b_wptr+=RTP_FIXED_HEADER_SIZE; + return mp; +} + + +/** + *@param session a rtp session. + *@param packet a rtp packet as a mblk_t + *@param event the event type as described in rfc2833, ie one of the TEV_* macros. + *@param end a boolean to indicate if the end bit should be set. (end of tone) + *@param volume the volume of the telephony tone, as described in rfc2833 + *@param duration the duration of the telephony tone, in timestamp unit. + * + * Adds a named telephony event to a rtp packet previously allocated using + * rtp_session_create_telephone_event_packet(). + * + *@return 0 on success. +**/ +int rtp_session_add_telephone_event(RtpSession *session, + mblk_t *packet, uint8_t event, int end, uint8_t volume, uint16_t duration) +{ + mblk_t *mp=packet; + telephone_event_t *event_hdr; + + + /* find the place where to add the new telephony event to the packet */ + while(mp->b_cont!=NULL) mp=mp->b_cont; + /* see if we need to allocate a new mblk_t */ + if ( ( mp->b_wptr) >= (mp->b_datap->db_lim)){ + mblk_t *newm=allocb(TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED); + mp->b_cont=newm; + mp=mp->b_cont; + } + if (mp==NULL) return -1; + event_hdr=(telephone_event_t*)mp->b_wptr; + event_hdr->event=event; + event_hdr->R=0; + event_hdr->E=end; + event_hdr->volume=volume; + event_hdr->duration=htons(duration); + mp->b_wptr+=sizeof(telephone_event_t); + return 0; +} +/** + * This functions creates telephony events packets for dtmf and sends them. + * It uses rtp_session_create_telephone_event_packet() and + * rtp_session_add_telephone_event() to create them and finally + * rtp_session_sendm_with_ts() to send them. + * + * @param session a rtp session + * @param dtmf a character meaning the dtmf (ex: '1', '#' , '9' ...) + * @param userts the timestamp + * @return 0 if successfull, -1 if the session cannot support telephony events or if the dtmf given as argument is not valid. +**/ +int rtp_session_send_dtmf(RtpSession *session, char dtmf, uint32_t userts) +{ + return rtp_session_send_dtmf2(session, dtmf, userts, 480); +} + +/** + * A variation of rtp_session_send_dtmf() with duration specified. + * + * @param session a rtp session + * @param dtmf a character meaning the dtmf (ex: '1', '#' , '9' ...) + * @param userts the timestamp + * @param duration duration of the dtmf in timestamp units + * @return 0 if successfull, -1 if the session cannot support telephony events or if the dtmf given as argument is not valid. +**/ +int rtp_session_send_dtmf2(RtpSession *session, char dtmf, uint32_t userts, int duration) +{ + mblk_t *m1,*m2,*m3; + int tev_type; + int durationtier = duration/3; + + /* create the first telephony event packet */ + switch (dtmf){ + case '1': + tev_type=TEV_DTMF_1; + break; + case '2': + tev_type=TEV_DTMF_2; + break; + case '3': + tev_type=TEV_DTMF_3; + break; + case '4': + tev_type=TEV_DTMF_4; + break; + case '5': + tev_type=TEV_DTMF_5; + break; + case '6': + tev_type=TEV_DTMF_6; + break; + case '7': + tev_type=TEV_DTMF_7; + break; + case '8': + tev_type=TEV_DTMF_8; + break; + case '9': + tev_type=TEV_DTMF_9; + break; + case '*': + tev_type=TEV_DTMF_STAR; + break; + case '0': + tev_type=TEV_DTMF_0; + break; + case '#': + tev_type=TEV_DTMF_POUND; + break; + + case 'A': + case 'a': + tev_type=TEV_DTMF_A; + break; + + + case 'B': + case 'b': + tev_type=TEV_DTMF_B; + break; + + case 'C': + case 'c': + tev_type=TEV_DTMF_C; + break; + + case 'D': + case 'd': + tev_type=TEV_DTMF_D; + break; + + case '!': + tev_type=TEV_FLASH; + break; + + + default: + ortp_warning("Bad dtmf: %c.",dtmf); + return -1; + } + + m1=rtp_session_create_telephone_event_packet(session,1); + if (m1==NULL) return -1; + rtp_session_add_telephone_event(session,m1,tev_type,0,10,durationtier); + /* create a second packet */ + m2=rtp_session_create_telephone_event_packet(session,0); + if (m2==NULL) return -1; + rtp_session_add_telephone_event(session,m2,tev_type,0,10, durationtier+durationtier); + + /* create a third and final packet */ + m3=rtp_session_create_telephone_event_packet(session,0); + if (m3==NULL) return -1; + rtp_session_add_telephone_event(session,m3,tev_type,1,10,duration); + + /* and now sends them */ + rtp_session_sendm_with_ts(session,m1,userts); + rtp_session_sendm_with_ts(session,m2,userts); + /* the last packet is sent three times in order to improve reliability*/ + m1=copymsg(m3); + m2=copymsg(m3); + /* NOTE: */ + /* we need to copymsg() instead of dupmsg() because the buffers are modified when + the packet is sended because of the host-to-network conversion of timestamp,ssrc, csrc, and + seq number. + */ + rtp_session_sendm_with_ts(session,m3,userts); + session->rtp.snd_seq--; + rtp_session_sendm_with_ts(session,m1,userts); + session->rtp.snd_seq--; + rtp_session_sendm_with_ts(session,m2,userts); + return 0; +} + + +/** + * Reads telephony events from a rtp packet. *@tab points to the beginning of the event buffer. + * + * @param session a rtp session from which telephony events are received. + * @param packet a rtp packet as a mblk_t. + * @param tab the address of a pointer. + * @return the number of events in the packet if successfull, 0 if the packet did not contain telephony events. +**/ +int rtp_session_read_telephone_event(RtpSession *session, + mblk_t *packet,telephone_event_t **tab) +{ + int datasize; + int num; + int i; + telephone_event_t *tev; + rtp_header_t *hdr=(rtp_header_t*)packet->b_rptr; + unsigned char *payload; + if (hdr->paytype!=session->rcv.telephone_events_pt) return 0; /* this is not tel ev.*/ + datasize=rtp_get_payload(packet,&payload); + tev=*tab=(telephone_event_t*)payload; + /* convert from network to host order what should be */ + num=datasize/sizeof(telephone_event_t); + for (i=0;ion_telephone_event,(long)(long)event[0].event); + if (session->eventqs!=NULL){ + ev=ortp_event_new(ORTP_EVENT_TELEPHONE_EVENT); + evd=ortp_event_get_data(ev); + evd->packet=dupmsg(session->current_tev); + evd->info.telephone_event=event[0].event; + rtp_session_dispatch_event(session,ev); + } +} + +static void notify_events_ended(RtpSession *session, telephone_event_t *events, int num){ + int i; + for (i=0;ib_rptr; + + datasize=rtp_get_payload(m0,&payload); + + num=datasize/sizeof(telephone_event_t); + events=(telephone_event_t*)payload; + + + if (hdr->markbit==1) + { + /* this is a start of new events. Store the event buffer for later use*/ + if (session->current_tev!=NULL) { + freemsg(session->current_tev); + session->current_tev=NULL; + } + session->current_tev=copymsg(m0); + /* handle the case where the events are short enough to end within the packet that has the marker bit*/ + notify_events_ended(session,events,num); + } + /* whatever there is a markbit set or not, we parse the packet and compare it to previously received one */ + cur_tev=session->current_tev; + if (cur_tev!=NULL) + { + /* first compare timestamp, they must be identical */ + if (((rtp_header_t*)cur_tev->b_rptr)->timestamp== + ((rtp_header_t*)m0->b_rptr)->timestamp) + { + datasize=rtp_get_payload(cur_tev,&payload); + num2=datasize/sizeof(telephone_event_t); + evbuf=(telephone_event_t*)payload; + for (i=0;icurrent_tev!=NULL) { + freemsg(session->current_tev); + session->current_tev=NULL; + } + session->current_tev=copymsg(m0); + notify_events_ended(session,events,num); + } + } + else + { + /* there is no pending events, but we did not received marked bit packet + either the sending implementation is not compliant, either it has been lost, + we must deal with it anyway.*/ + session->current_tev=copymsg(m0); + /* inform the application if there are tone ends */ + notify_events_ended(session,events,num); + } +} diff --git a/linphone/oRTP/src/tests/.cvsignore b/linphone/oRTP/src/tests/.cvsignore new file mode 100644 index 000000000..cfffd5f7d --- /dev/null +++ b/linphone/oRTP/src/tests/.cvsignore @@ -0,0 +1,15 @@ +Makefile +Makefile.in +.deps +.libs +*.lo +*.la +mrtprecv +mrtpsend +rtpmemtest +rtprecv +rtpsend +test_timer +tevmrtprecv +tevrtprecv +tevrtpsend diff --git a/linphone/oRTP/src/tests/Makefile.am b/linphone/oRTP/src/tests/Makefile.am new file mode 100644 index 000000000..a0ca2e3e0 --- /dev/null +++ b/linphone/oRTP/src/tests/Makefile.am @@ -0,0 +1,28 @@ +SUBDIRS=win_receiver win_sender + +noinst_PROGRAMS= rtpsend rtprecv mrtpsend mrtprecv test_timer rtpmemtest tevrtpsend tevrtprecv tevmrtprecv rtpsend_stupid + +rtpsend_SOURCES= rtpsend.c + +rtprecv_SOURCES= rtprecv.c + +mrtpsend_SOURCES= mrtpsend.c + +mrtprecv_SOURCES= mrtprecv.c + +rtpmemtest_SOURCES= rtpmemtest.c + +test_timer_SOURCES= test_timer.c + +tevrtpsend_SOURCES= tevrtpsend.c + +tevrtprecv_SOURCES= tevrtprecv.c + +tevmrtprecv_SOURCES= tevmrtprecv.c + +rtpsend_stupid_SOURCES=rtpsend_stupid.c + +AM_CFLAGS= -D_ORTP_SOURCE $(PTHREAD_CFLAGS) +AM_LDFLAGS= $(PTHREAD_LDFLAGS) +LDADD=$(top_builddir)/src/libortp.la $(SRTP_LIBS) +INCLUDES=-I$(top_srcdir)/include/ diff --git a/linphone/oRTP/src/tests/mrtprecv.c b/linphone/oRTP/src/tests/mrtprecv.c new file mode 100644 index 000000000..a5b9de280 --- /dev/null +++ b/linphone/oRTP/src/tests/mrtprecv.c @@ -0,0 +1,159 @@ +/* + The oRTP LinPhone RTP library intends to provide basics for a RTP stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* this program shows how to receive streams in paralel using the SessionSet api + and two threads only. */ + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include + +#include +#include +#include +#endif + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: mrtprecv file_prefix local_port number_of_streams \n" + "Receives multiples rtp streams on local_port+2*k, k={0..number_of_streams}\n"; + +#define STREAMS_COUNT 1000 + +/* malloc'd in order to detect buffer overflows with efence */ +static uint8_t* recvbuf=0; + +int rtp2disk(RtpSession *session,uint32_t ts, int fd) +{ + int err,havemore=1; + while (havemore){ + err=rtp_session_recv_with_ts(session,recvbuf,160,ts,&havemore); + if (havemore) printf("warning: havemore=%i!\n",havemore); + if (err>0){ + rtp_session_set_data(session,(void*)1); + /* to indicate that (for the application) the stream has started, so we can start + recording on disk */ + } + if (session->user_data != NULL) { + size_t ret = write(fd,recvbuf,err); + assert( ret == err ); + } + } + return 0; +} + + +int main(int argc, char *argv[]) +{ + RtpSession *session[STREAMS_COUNT]; + int i; + int filefd[STREAMS_COUNT]; + int port; + uint32_t user_ts=0; + int channels; + SessionSet *set; + char *filename; + + if (argc<4){ + printf(help); + return -1; + } + + channels=atoi(argv[3]); + if (channels==0){ + printf(help); + return -1; + } + + ortp_init(); + ortp_scheduler_init(); + + port=atoi(argv[2]); + recvbuf=ortp_malloc(160); + + for (i=0;i +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#endif + + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: mrtpsend filename ip port nstreams [--packet-size size] [--ts-inc value]\n"; + +#define STREAMS_COUNT 1000 + + + +int main(int argc, char *argv[]) +{ + RtpSession *session[STREAMS_COUNT]; + unsigned char *buffer; + int packet_size=160; + int ts_inc=160; + int i; + FILE *infile; + char *ssrc; + int port; + uint32_t user_ts=0; + int channels; + SessionSet *set; + + if (argc<5){ + printf(help); + return -1; + } + + channels=atoi(argv[4]); + if (channels==0){ + printf(help); + return -1; + } + + /* look at command line options */ + for (i=5;i0) && (runcond) ) + { + int k; + //ortp_message("Sending packet."); + for (k=0;k +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#else +//#include +#endif + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: mrtprecv file_prefix local_port number_of_streams \n" + "Receives multiples rtp streams on local_port+2*k, k={0..number_of_streams}\n"; + +#define STREAMS_COUNT 1000 + +int rtp2disk(RtpSession *session,uint32_t ts, int fd) +{ + unsigned char buffer[160]; + int err,havemore=1; + while (havemore){ + err=rtp_session_recv_with_ts(session,buffer,160,ts,&havemore); + if (err>0){ + rtp_session_set_data(session,(void*)1); + /* to indicate that (for the application) the stream has started, so we can start + recording on disk */ + } + if (session->user_data != NULL) { + size_t ret = write(fd,buffer,err); + assert( ret == err ); + } + } + return 0; +} + + +int main(int argc, char *argv[]) +{ + RtpSession *session[STREAMS_COUNT]; + int i; + int filefd[STREAMS_COUNT]; + int port; + uint32_t user_ts=0; + int channels; + SessionSet *set; + char *filename; + + argc=4; + argv[1]="/tmp/output"; + argv[2]="8000"; + argv[3]="100"; + + if (argc<4){ + printf(help); + return -1; + } + + channels=atoi(argv[3]); + if (channels==0){ + printf(help); + return -1; + } + + ortp_init(); + ortp_scheduler_init(); + + port=atoi(argv[2]); + for (i=0;isetflags=%i\n",session[k]->setflags); + } + /* and then suspend the process by selecting() */ + session_set_select(set,NULL,NULL); + for (k=0;k +#include +#include +#ifndef _WIN32 +#include +#include +#include +#endif + +int cond=1; + +void stop_handler(int signum) +{ + cond=0; +} + +void ssrc_cb(RtpSession *session) +{ + printf("hey, the ssrc has changed !\n"); +} + +static char *help="usage: rtprecv filename loc_port [--format format] [--soundcard] [--noadapt] [--with-jitter ]\n"; + +#define MULAW 0 +#define ALAW 1 + +#if defined(__hpux) && HAVE_SYS_AUDIO_H + +#include + +int sound_init(int format) +{ + int fd; + fd=open("/dev/audio",O_WRONLY); + if (fd<0){ + perror("Can't open /dev/audio"); + return -1; + } + ioctl(fd,AUDIO_RESET,0); + ioctl(fd,AUDIO_SET_SAMPLE_RATE,8000); + ioctl(fd,AUDIO_SET_CHANNELS,1); + if (format==MULAW) + ioctl(fd,AUDIO_SET_DATA_FORMAT,AUDIO_FORMAT_ULAW); + else ioctl(fd,AUDIO_SET_DATA_FORMAT,AUDIO_FORMAT_ALAW); + return fd; +} +#else +int sound_init(int format) +{ + return -1; +} +#endif + +int main(int argc, char*argv[]) +{ + RtpSession *session; + unsigned char buffer[160]; + int err; + uint32_t ts=0; + int stream_received=0; + FILE *outfile; + int local_port; + int have_more; + int i; + int format=0; + int soundcard=0; + int sound_fd=0; + int jittcomp=40; + bool_t adapt=TRUE; + + /* init the lib */ + if (argc<3){ + printf(help); + return -1; + } + local_port=atoi(argv[2]); + if (local_port<=0) { + printf(help); + return -1; + } + for (i=3;i0) stream_received=1; + /* this is to avoid to write to disk some silence before the first RTP packet is returned*/ + if ((stream_received) && (err>0)) { + size_t ret = fwrite(buffer,1,err,outfile); + if (sound_fd>0) + ret = write(sound_fd,buffer,err); + } + } + ts+=160; + //ortp_message("Receiving packet."); + } + + rtp_session_destroy(session); + ortp_exit(); + + ortp_global_stats_display(); + + return 0; +} diff --git a/linphone/oRTP/src/tests/rtpsend.c b/linphone/oRTP/src/tests/rtpsend.c new file mode 100644 index 000000000..19935bd01 --- /dev/null +++ b/linphone/oRTP/src/tests/rtpsend.c @@ -0,0 +1,128 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#endif + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: rtpsend filename dest_ip4addr dest_port [ --with-clockslide ] [ --with-jitter ]\n"; + +int main(int argc, char *argv[]) +{ + RtpSession *session; + unsigned char buffer[160]; + int i; + FILE *infile; + char *ssrc; + uint32_t user_ts=0; + int clockslide=0; + int jitter=0; + if (argc<4){ + printf(help); + return -1; + } + for(i=4;i=argc) { + printf(help); + return -1; + } + clockslide=atoi(argv[i]); + ortp_message("Using clockslide of %i milisecond every 50 packets.",clockslide); + }else if (strcmp(argv[i],"--with-jitter")==0){ + ortp_message("Jitter will be added to outgoing stream."); + i++; + if (i>=argc) { + printf(help); + return -1; + } + jitter=atoi(argv[i]); + } + } + + ortp_init(); + ortp_scheduler_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR); + session=rtp_session_new(RTP_SESSION_SENDONLY); + + rtp_session_set_scheduling_mode(session,1); + rtp_session_set_blocking_mode(session,1); + rtp_session_set_connected_mode(session,TRUE); + rtp_session_set_remote_addr(session,argv[2],atoi(argv[3])); + rtp_session_set_payload_type(session,0); + + ssrc=getenv("SSRC"); + if (ssrc!=NULL) { + printf("using SSRC=%i.\n",atoi(ssrc)); + rtp_session_set_ssrc(session,atoi(ssrc)); + } + + #ifndef _WIN32 + infile=fopen(argv[1],"r"); + #else + infile=fopen(argv[1],"rb"); + #endif + + if (infile==NULL) { + perror("Cannot open file"); + return -1; + } + + signal(SIGINT,stophandler); + while( ((i=fread(buffer,1,160,infile))>0) && (runcond) ) + { + rtp_session_send_with_ts(session,buffer,i,user_ts); + user_ts+=160; + if (clockslide!=0 && user_ts%(160*50)==0){ + ortp_message("Clock sliding of %i miliseconds now",clockslide); + rtp_session_make_time_distorsion(session,clockslide); + } + /*this will simulate a burst of late packets */ + if (jitter && (user_ts%(8000)==0)) { + struct timespec pausetime, remtime; + ortp_message("Simulating late packets now (%i milliseconds)",jitter); + pausetime.tv_sec=jitter/1000; + pausetime.tv_nsec=(jitter%1000)*1000000; + while(nanosleep(&pausetime,&remtime)==-1 && errno==EINTR){ + pausetime=remtime; + } + } + } + + fclose(infile); + rtp_session_destroy(session); + ortp_exit(); + ortp_global_stats_display(); + + return 0; +} diff --git a/linphone/oRTP/src/tests/rtpsend_stupid.c b/linphone/oRTP/src/tests/rtpsend_stupid.c new file mode 100644 index 000000000..0758ceaee --- /dev/null +++ b/linphone/oRTP/src/tests/rtpsend_stupid.c @@ -0,0 +1,126 @@ + /* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#endif +/*defined in library, but not declared in public headers (this method is only useful for tests)*/ +extern int __rtp_session_sendm_with_ts(RtpSession *session, mblk_t *packet, uint32_t packet_ts, uint32_t send_ts); + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: rtpsend filename dest_ip4addr dest_port [ --with-clockslide ] [ --with-ptime ]\n"; + +int main(int argc, char *argv[]) +{ + RtpSession *session; + unsigned char buffer[160]; + int i; + FILE *infile; + char *ssrc; + uint32_t packet_ts=0,send_ts=0; + uint32_t send_ts_inc=160; + int clockslide=0; + int jitter=0; + if (argc<4){ + printf(help); + return -1; + } + for(i=4;i=argc) { + printf(help); + return -1; + } + clockslide=atoi(argv[i]); + ortp_message("Using clockslide of %i milisecond every 50 packets.",clockslide); + }else if (strcmp(argv[i],"--with-ptime")==0){ + ortp_message("Ptime related jitter will be added to outgoing stream."); + i++; + if (i>=argc) { + printf(help); + return -1; + } + jitter=atoi(argv[i]); + send_ts_inc=jitter*8; + } + } + + ortp_init(); + ortp_scheduler_init(); + ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR); + session=rtp_session_new(RTP_SESSION_SENDONLY); + + rtp_session_set_scheduling_mode(session,1); + rtp_session_set_blocking_mode(session,1); + rtp_session_set_connected_mode(session,TRUE); + rtp_session_set_remote_addr(session,argv[2],atoi(argv[3])); + rtp_session_set_payload_type(session,0); + + ssrc=getenv("SSRC"); + if (ssrc!=NULL) { + printf("using SSRC=%i.\n",atoi(ssrc)); + rtp_session_set_ssrc(session,atoi(ssrc)); + } + + #ifndef _WIN32 + infile=fopen(argv[1],"r"); + #else + infile=fopen(argv[1],"rb"); + #endif + + if (infile==NULL) { + perror("Cannot open file"); + return -1; + } + + signal(SIGINT,stophandler); + while( ((i=fread(buffer,1,160,infile))>0) && (runcond) ) + { + mblk_t *m=rtp_session_create_packet(session,RTP_FIXED_HEADER_SIZE,buffer,i); + __rtp_session_sendm_with_ts(session,m,packet_ts,send_ts); + packet_ts+=160; + if ((send_ts+send_ts_inc)<=packet_ts){ + send_ts+=send_ts_inc; + } + if (clockslide!=0 && send_ts%(160*50)==0){ + ortp_message("Clock sliding of %i miliseconds now",clockslide); + rtp_session_make_time_distorsion(session,clockslide); + } + } + + fclose(infile); + rtp_session_destroy(session); + ortp_exit(); + ortp_global_stats_display(); + + return 0; +} diff --git a/linphone/oRTP/src/tests/test_timer.c b/linphone/oRTP/src/tests/test_timer.c new file mode 100644 index 000000000..48f4d0da2 --- /dev/null +++ b/linphone/oRTP/src/tests/test_timer.c @@ -0,0 +1,43 @@ + /* + The oRTP LinPhone RTP library intends to provide basics for a RTP stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "../rtptimer.h" +#include + +int main(int argc, char *argv[]) +{ + RtpTimer *timer=&posix_timer; + int i; + struct timeval interval; + + interval.tv_sec=0; + interval.tv_usec=500000; + + rtp_timer_set_interval(timer,&interval); + + timer->timer_init(); + for (i=0;i<10;i++) + { + printf("doing something...\n"); + timer->timer_do(); + } + timer->timer_uninit(); + return 0; +} diff --git a/linphone/oRTP/src/tests/tevmrtprecv.c b/linphone/oRTP/src/tests/tevmrtprecv.c new file mode 100644 index 000000000..b306d2057 --- /dev/null +++ b/linphone/oRTP/src/tests/tevmrtprecv.c @@ -0,0 +1,175 @@ + /* + The oRTP LinPhone RTP library intends to provide basics for a RTP stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* this program shows how to receive streams in paralel using the SessionSet api + and two threads only. */ + +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include + +#else +//#include +#endif + +#include + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; + +static int *p_channel_id; + +int dtmf_count=0; + +static char *help="usage: tevmrtprecv file_prefix local_port number_of_streams \n" + "Receives multiples rtp streams with telephone events on local_port+2*k, k={0..number_of_streams}\n"; + +#define STREAMS_COUNT 1000 + + +void recv_tev_cb(RtpSession *session,int type,long user_data) +{ + //printf("Receiving telephony event:%i\n",type); + if (type<16) printf("This is dtmf %c on channel %d\n",dtmf_tab[type],*(int *)user_data); + dtmf_count++; +} + +int rtp2disk(RtpSession *session,uint32_t ts, int fd) +{ + unsigned char buffer[160]; + int err,havemore=1; + while (havemore){ + err=rtp_session_recv_with_ts(session,buffer,160,ts,&havemore); + if (err>0){ + rtp_session_set_data(session,(void*)1); + /* to indicate that (for the application) the stream has started, so we can start + recording on disk */ + } + if (session->user_data != NULL) { + size_t ret = write(fd,buffer,err); + assert( ret == err ); + } + } + return 0; +} + + +int main(int argc, char *argv[]) +{ + RtpSession *session[STREAMS_COUNT]; + int i; + int filefd[STREAMS_COUNT]; + int port; + uint32_t user_ts=0; + int channels; + SessionSet *set; + char *filename; + + if (argc<4){ + printf(help); + return -1; + } + + channels=atoi(argv[3]); + if (channels==0){ + printf(help); + return -1; + } + + ortp_init(); + ortp_scheduler_init(); + + /* set the telephony event payload type to 96 in the av profile.*/ + rtp_profile_set_payload(&av_profile,96,&payload_type_telephone_event); + + port=atoi(argv[2]); + p_channel_id = (int *)ortp_malloc(channels*sizeof(int)); + for (i=0;i +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#else +#include +#endif +#include + +int runcond=1; + +static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: test_tevrecv filename loc_port\n"; + +int dtmf_count=0; + +void recv_tev_cb(RtpSession *session,int type,long user_data) +{ + printf("Receiving telephony event:%i\n",type); + if (type<16) printf("This is dtmf %c\n",dtmf_tab[type]); + dtmf_count++; +} + +int main(int argc, char *argv[]) +{ + RtpSession *session; + unsigned char buffer[160]; + int err; + FILE *outfile; + uint32_t ts=0; + int have_more; + + if (argc<3){ + printf(help); + return -1; + } + + ortp_init(); + ortp_scheduler_init(); + + /* set the telephony event payload type to 96 in the av profile.*/ + rtp_profile_set_payload(&av_profile,96,&payload_type_telephone_event); + + session=rtp_session_new(RTP_SESSION_RECVONLY); + + rtp_session_set_scheduling_mode(session,1); + rtp_session_set_blocking_mode(session,1); + rtp_session_set_local_addr(session,"0.0.0.0",atoi(argv[2])); + rtp_session_set_payload_type(session,0); + + /* register for telephony events */ + rtp_session_signal_connect(session,"telephone-event",(RtpCallback)recv_tev_cb,0); + + outfile=fopen(argv[1],"wb"); + if (outfile==NULL) { + perror("Cannot open file"); + return -1; + } + signal(SIGINT,stophandler); + while(runcond) + { + have_more=1; + while (have_more){ + err=rtp_session_recv_with_ts(session,buffer,160,ts,&have_more); + if (err>0) { + size_t ret = fwrite(buffer,1,err,outfile); + assert( ret == err ); + } + } + ts+=160; + //ortp_message("Receiving packet."); + } + fclose(outfile); + rtp_session_destroy(session); + ortp_exit(); + ortp_global_stats_display(); + printf("Total dtmf events received: %i\n",dtmf_count); + return 0; +} diff --git a/linphone/oRTP/src/tests/tevrtpsend.c b/linphone/oRTP/src/tests/tevrtpsend.c new file mode 100644 index 000000000..c064f6c64 --- /dev/null +++ b/linphone/oRTP/src/tests/tevrtpsend.c @@ -0,0 +1,99 @@ +/* + The oRTP LinPhone RTP library intends to provide basics for a RTP stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#else +#include +#endif +#include + +int runcond=1; + +void stophandler(int signum) +{ + runcond=0; +} + +static char *help="usage: test_tevsend filename dest_ip4addr dest_port\n"; + +int main(int argc, char *argv[]) +{ + RtpSession *session; + unsigned char buffer[160]; + int i; + FILE *infile; + char *ssrc; + uint32_t user_ts=0; + int tel=0; + + if (argc<4){ + printf(help); + return -1; + } + + ortp_init(); + ortp_scheduler_init(); + + /* set the telephony event payload type to 96 in the av profile.*/ + rtp_profile_set_payload(&av_profile,96,&payload_type_telephone_event); + + session=rtp_session_new(RTP_SESSION_SENDONLY); + + rtp_session_set_scheduling_mode(session,1); + rtp_session_set_blocking_mode(session,1); + rtp_session_set_remote_addr(session,argv[2],atoi(argv[3])); + rtp_session_set_send_payload_type(session,0); + + ssrc=getenv("SSRC"); + if (ssrc!=NULL) { + printf("using SSRC=%i.\n",atoi(ssrc)); + rtp_session_set_ssrc(session,atoi(ssrc)); + } + + infile=fopen(argv[1],"rb"); + if (infile==NULL) { + perror("Cannot open file"); + return -1; + } + signal(SIGINT,stophandler); + while( ((i=fread(buffer,1,160,infile))>0) && (runcond) ) + { + //ortp_message("Sending packet."); + rtp_session_send_with_ts(session,buffer,i,user_ts); + user_ts+=160; + tel++; + if (tel==50){ + tel=0; + ortp_message("Sending telephony event packet."); + rtp_session_send_dtmf(session,'*',user_ts); + user_ts+=160+160+160; /* the duration of the dtmf */ + } + } + fclose(infile); + rtp_session_destroy(session); + ortp_exit(); + ortp_global_stats_display(); + return 0; +} diff --git a/linphone/oRTP/src/tests/win_receiver/.cvsignore b/linphone/oRTP/src/tests/win_receiver/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/oRTP/src/tests/win_receiver/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/oRTP/src/tests/win_receiver/Makefile.am b/linphone/oRTP/src/tests/win_receiver/Makefile.am new file mode 100644 index 000000000..e7e00556f --- /dev/null +++ b/linphone/oRTP/src/tests/win_receiver/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=RTPReceiver.cpp RTPReceiver.vcproj + diff --git a/linphone/oRTP/src/tests/win_receiver/RTPReceiver.cpp b/linphone/oRTP/src/tests/win_receiver/RTPReceiver.cpp new file mode 100644 index 000000000..8701508f8 --- /dev/null +++ b/linphone/oRTP/src/tests/win_receiver/RTPReceiver.cpp @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include + +#define STREAMS_COUNT 1000 + +BOOL m_bExit = FALSE; + +static char *help="usage: mrtprecv file_prefix local_port number_of_streams \n" + "Receives multiples rtp streams on local_port+2*k, k={0..number_of_streams}\n"; + + +void ProductVersion() +{ + char strBuffer[255]; + + printf("====================================\n"); + printf("Author : Simon Morlat =\n"); + printf("Porting : Yann STEPHAN =\n"); + printf("====================================\n"); + + memset(&strBuffer, 0x0, sizeof(strBuffer)); + + sprintf((char *) &strBuffer, "= RTPReceiver V1.0 - Date : %s - %s\n", __DATE__, __TIME__); + printf(strBuffer); + + printf("====================================\n"); +} + +BOOL ctrlHandlerFunction(DWORD fdwCtrlType) +{ + switch (fdwCtrlType) + { + // Handle the CTRL+C signal. + // CTRL+CLOSE: confirm that the user wants to exit. + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + m_bExit = TRUE; + return TRUE; + + default: + return FALSE; + } +} + +int rtp2disk(RtpSession *session,uint32_t ts, FILE * fd) +{ + char buffer[160]; + int err,havemore=1; + + while (havemore) + { + err=rtp_session_recv_with_ts(session,buffer,160,ts,&havemore); + + if (havemore) + printf("==> Warning: havemore=1!\n"); + + if (err>0) + { + rtp_session_set_data(session,(void*)1); + /* to indicate that (for the application) the stream has started, so we can start + recording on disk */ + } + + if (session->user_data != NULL) + { + fwrite(&buffer,1,160, fd); + } + } + return 0; +} + +int GetSystemInformation() +{ + SYSTEM_INFO SystemInfo; + + GetSystemInfo(&SystemInfo); + + return SystemInfo.dwNumberOfProcessors; +} + +int __cdecl main(int argc, char *argv[]) +{ + RtpSession * session[STREAMS_COUNT]; + FILE * filefd[STREAMS_COUNT]; + SessionSet * set; + + uint32_t user_ts = 0; + + int port = 0; + int channels = 0; + int i = 0; + int nCPUCount = 0; + int nSchedulerCPU = 2; + + char strFilename[MAX_PATH]; + + ProductVersion(); + + if (argc<4) + { + printf(help); + return -1; + } + + channels=atoi(argv[3]); + if (channels==0){ + printf(help); + return -1; + } + + // Now it's time to use the power of multiple CPUs + nCPUCount = GetSystemInformation(); + + printf("==> # of CPU detected : %d\n", nCPUCount); + + ortp_init(); + ortp_scheduler_init(); + + if (nCPUCount > 1) + { + if (nCPUCount > 2) + { + nSchedulerCPU = 3; + } + +/* if (ortp_bind_scheduler_to_cpu(nSchedulerCPU) != -1) + { + printf("==> Scheduler has been binded to CPU %d\n", nSchedulerCPU); + } + else + { + printf("==> Scheduler still binded to CPU 1\n"); + } +*/ + } + + port=atoi(argv[2]); + + for (i=0;i Cannot handle the CTRL-C...\n"); + } + + /* create a set */ + set=session_set_new(); + printf("==> RTP Receiver started\n"); + + while(m_bExit == FALSE) + { + int k; + + for (k=0;k Warning: session_set_select() is returning 0...\n"); + } + + for (k=0;k Session_set_is_set %d\n", k); + } + else + { + //printf("warning: session %i is not set !\n",k); + } + } + user_ts+=160; + } + + printf("==> Exiting\n"); + + for (i=0;i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/oRTP/src/tests/win_receiver/ortpreceiver.dev b/linphone/oRTP/src/tests/win_receiver/ortpreceiver.dev new file mode 100755 index 000000000..aa13ec819 --- /dev/null +++ b/linphone/oRTP/src/tests/win_receiver/ortpreceiver.dev @@ -0,0 +1,59 @@ +[Project] +FileName=ortpreceiver.dev +Name=ortpreceiver +UnitCount=1 +Type=1 +Ver=1 +ObjFiles= +Includes=../../../include +Libs=../../../build/win32native/ +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DORTP_INET6_@@_ +CppCompiler= +Linker=-lortp_@@_ +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=ortpreceiver.exe +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 + +[Unit1] +FileName=RTPReceiver.cpp +CompileCpp=0 +Folder=ortpreceiver +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + diff --git a/linphone/oRTP/src/tests/win_sender/.cvsignore b/linphone/oRTP/src/tests/win_sender/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/oRTP/src/tests/win_sender/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/oRTP/src/tests/win_sender/Makefile.am b/linphone/oRTP/src/tests/win_sender/Makefile.am new file mode 100644 index 000000000..3af05d969 --- /dev/null +++ b/linphone/oRTP/src/tests/win_sender/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=RTPSender.cpp RTPSender.vcproj + diff --git a/linphone/oRTP/src/tests/win_sender/RTPSender.cpp b/linphone/oRTP/src/tests/win_sender/RTPSender.cpp new file mode 100644 index 000000000..95630b079 --- /dev/null +++ b/linphone/oRTP/src/tests/win_sender/RTPSender.cpp @@ -0,0 +1,265 @@ +#include +#include + +#define STREAMS_COUNT 1000 + +enum +{ + EVENT_STOP, + EVENT_RTP, + EVENT_COUNT // Always last +}; + + +RtpSession * m_Session[STREAMS_COUNT]; + +int m_nPacket_Size = 160; +int m_nTimestamp_Inc = 160; + +char * m_pBuffer = NULL; +char * m_SSRC = NULL; + +int m_nChannels = 0; +int m_nPort = 0; + +HANDLE m_hEvents[EVENT_COUNT]; + +BOOL m_bExit = FALSE; + +static char *help="usage: mrtpsend filename ip port nstreams [--packet-size size] [--ts-inc value]\n"; + +BOOL ctrlHandlerFunction(DWORD fdwCtrlType) +{ + switch (fdwCtrlType) + { + // Handle the CTRL+C signal. + // CTRL+CLOSE: confirm that the user wants to exit. + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + m_bExit = TRUE; + SetEvent(m_hEvents[EVENT_STOP]); + return TRUE; + + default: + return FALSE; + } +} + +int GetCommandArguments(int argc, char *argv[]) +{ + int nCounter; + + // Check the number of arguments + if (argc<5) + { + printf(help); + return -1; + } + + m_nChannels = atoi(argv[4]); + + // Get the number of channels + if (m_nChannels == 0) + { + printf(help); + return -1; + } + + /* look at command line options */ + for (nCounter=5; nCounter Sorry dude...\n"); + Sleep(1000); + return -1; + } + + printf("==> Starting the RTP Sender test\n"); + + + // =============== INSTALL THE CONTROL HANDLER =============== + if (SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlHandlerFunction, TRUE) == 0) + { + printf("==> Cannot handle the CTRL-C...\n"); + } + + + printf("==> Timestamp increment will be %i\n" , m_nTimestamp_Inc); + printf("==> Packet size will be %i\n" , m_nPacket_Size); + + m_pBuffer = (char *) ortp_malloc(m_nPacket_Size); + + ortp_init(); + ortp_scheduler_init(); + printf("==> Scheduler initialized\n"); + + m_SSRC = getenv("SSRC"); + m_nPort = atoi(argv[3]); + + for (nCounter=0; nCounter < m_nChannels; nCounter++) + { + //printf("==> Channel [#%d]\n", nCounter); + + m_Session[nCounter] = rtp_session_new(RTP_SESSION_SENDONLY); + + rtp_session_set_scheduling_mode(m_Session[nCounter],1); + rtp_session_set_blocking_mode(m_Session[nCounter],0); + rtp_session_set_remote_addr(m_Session[nCounter],argv[2], m_nPort); + rtp_session_set_send_payload_type(m_Session[nCounter],0); + + if (m_SSRC != NULL) + { + rtp_session_set_ssrc(m_Session[nCounter],atoi(m_SSRC)); + } + + m_nPort+=2; + } + + infile=fopen(argv[1],"rb"); + + if (infile==NULL) + { + printf("==> Cannot open file !!!!"); + Sleep(1000); + return -1; + } + +// printf("==> Open file\n"); + + /* Create a set */ + pSessionSet = session_set_new(); +// printf("==> Session set\n"); + + while( ((nCounter= (int) fread(m_pBuffer,1,m_nPacket_Size,infile))>0) && (m_bExit == FALSE) ) + { + int k; + //g_message("Sending packet."); + for (k=0;k Session set set %d\n", k); + } + /* and then suspend the process by selecting() */ + session_set_select(NULL,pSessionSet,NULL); + //printf("==> Session set select\n"); + + for (k=0;k Session set is set %d\n", k); + rtp_session_send_with_ts(m_Session[k],m_pBuffer,nCounter,m_nUser_Timestamp); + //g_message("packet sended !"); + } + } + m_nUser_Timestamp+=m_nTimestamp_Inc; + } + + fclose(infile); + printf("==> Close file\n"); + + + + for(nCounter=0;nCounter Remove the CTRL-C handler...\n"); + SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlHandlerFunction, FALSE); + + // Wait for an input key + printf("Waiting for exit : "); + + for (nCounter = 0; nCounter < 4*5; nCounter++) + { + printf("."); + Sleep(250); + } + + return 0; +} + diff --git a/linphone/oRTP/src/tests/win_sender/RTPSender.vcproj b/linphone/oRTP/src/tests/win_sender/RTPSender.vcproj new file mode 100644 index 000000000..32b054186 --- /dev/null +++ b/linphone/oRTP/src/tests/win_sender/RTPSender.vcproj @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linphone/oRTP/src/tests/win_sender/ortpsender.dev b/linphone/oRTP/src/tests/win_sender/ortpsender.dev new file mode 100755 index 000000000..a7310659a --- /dev/null +++ b/linphone/oRTP/src/tests/win_sender/ortpsender.dev @@ -0,0 +1,59 @@ +[Project] +FileName=ortpsender.dev +Name=ortpsender +UnitCount=1 +Type=1 +Ver=1 +ObjFiles= +Includes=../../../include +Libs=../../../build/win32native +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-DORTP_INET6_@@_ +CppCompiler= +Linker=-lortp_@@_ +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=ortpsender.exe +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000 + +[Unit1] +FileName=RTPSender.cpp +CompileCpp=0 +Folder=ortpsender +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + diff --git a/linphone/oRTP/src/utils.c b/linphone/oRTP/src/utils.c new file mode 100644 index 000000000..436e2a2c2 --- /dev/null +++ b/linphone/oRTP/src/utils.c @@ -0,0 +1,86 @@ +/*************************************************************************** + * utils.c + * + * Wed Feb 23 14:15:36 2005 + * Copyright 2005 Simon Morlat + * Email simon.morlat@linphone.org + ****************************************************************************/ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ortp/port.h" +#include "utils.h" + +OList *o_list_new(void *data){ + OList *new_elem=(OList*)ortp_new0(OList,1); + new_elem->data=data; + return new_elem; +} + +OList * o_list_append(OList *elem, void * data){ + OList *new_elem=o_list_new(data); + OList *it=elem; + if (elem==NULL) return new_elem; + while (it->next!=NULL) it=o_list_next(it); + it->next=new_elem; + new_elem->prev=it; + return elem; +} + +OList * o_list_free(OList *list){ + OList *elem = list; + OList *tmp; + return_val_if_fail(list, list); + while(elem->next!=NULL) { + tmp = elem; + elem = elem->next; + ortp_free(tmp); + } + ortp_free(elem); + return NULL; +} + +OList *o_list_remove_link(OList *list, OList *elem){ + OList *ret; + if (elem==list){ + ret=elem->next; + elem->prev=NULL; + elem->next=NULL; + if (ret!=NULL) ret->prev=NULL; + ortp_free(elem); + return ret; + } + elem->prev->next=elem->next; + if (elem->next!=NULL) elem->next->prev=elem->prev; + elem->next=NULL; + elem->prev=NULL; + ortp_free(elem); + return list; +} + +OList * o_list_remove(OList *list, void *data){ + OList *it; + for(it=list;it!=NULL;it=it->next){ + if (it->data==data){ + return o_list_remove_link(list,it); + } + } + return list; +} + diff --git a/linphone/oRTP/src/utils.h b/linphone/oRTP/src/utils.h new file mode 100644 index 000000000..0a50fcf0f --- /dev/null +++ b/linphone/oRTP/src/utils.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * utils.h + * + * Wed Feb 23 14:15:36 2005 + * Copyright 2005 Simon Morlat + * Email simon.morlat@linphone.org + ****************************************************************************/ +/* + The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef UTILS_H +#define UTILS_H + +#include "ortp/event.h" + +struct _OList { + struct _OList *next; + struct _OList *prev; + void *data; +}; + +typedef struct _OList OList; + + +#define o_list_next(elem) ((elem)->next) + +OList * o_list_append(OList *elem, void * data); +OList * o_list_remove(OList *list, void *data); +OList * o_list_free(OList *elem); + +#ifndef MIN +#define MIN(a,b) (((a)>(b)) ? (b) : (a)) +#endif +#ifndef MAX +#define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif + +#define return_if_fail(expr) if (!(expr)) {printf("%s:%i- assertion"#expr "failed\n",__FILE__,__LINE__); return;} +#define return_val_if_fail(expr,ret) if (!(expr)) {printf("%s:%i- assertion" #expr "failed\n",__FILE__,__LINE__); return (ret);} + + +#define INT_TO_POINTER(truc) ((long)(long)(truc)) +#define POINTER_TO_INT(truc) ((int)(long)(truc)) + +typedef struct _dwsplit_t{ +#ifdef ORTP_BIGENDIAN + uint16_t hi; + uint16_t lo; +#else + uint16_t lo; + uint16_t hi; +#endif +} dwsplit_t; + +typedef union{ + dwsplit_t split; + uint32_t one; +} poly32_t; + +#ifdef ORTP_BIGENDIAN +#define hton24(x) (x) +#else +#define hton24(x) ((( (x) & 0x00ff0000) >>16) | (( (x) & 0x000000ff) <<16) | ( (x) & 0x0000ff00) ) +#endif +#define ntoh24(x) hton24(x) + +#if defined(WIN32) || defined(_WIN32_WCE) +#define is_would_block_error(errnum) (errnum==WSAEWOULDBLOCK) +#else +#define is_would_block_error(errnum) (errnum==EWOULDBLOCK || errnum==EAGAIN) +#endif + +void ortp_ev_queue_put(OrtpEvQueue *q, OrtpEvent *ev); + +#endif diff --git a/linphone/pixmaps/.cvsignore b/linphone/pixmaps/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/linphone/pixmaps/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/linphone/pixmaps/Makefile.am b/linphone/pixmaps/Makefile.am new file mode 100644 index 000000000..6968c4ee9 --- /dev/null +++ b/linphone/pixmaps/Makefile.am @@ -0,0 +1,11 @@ + + +pixmapdir=$(datadir)/pixmaps/linphone + +pixmap_DATA= linphone2.png linphone2.xpm linphone.png \ +sip-away.png sip-bifm.png \ +sip-busy.png sip-closed.png \ +sip-online.png sip-otl.png \ +sip-otp.png sip-wfa.png + +EXTRA_DIST=$(pixmap_DATA) diff --git a/linphone/pixmaps/linphone.png b/linphone/pixmaps/linphone.png new file mode 100644 index 0000000000000000000000000000000000000000..06cf18315e755813a393d246ba1d27d51c0aaaeb GIT binary patch literal 11971 zcmV;!EU5Fe!S?mTjCUS(yk6Mr zI}gix9(HFx9`^dajF-!0uJ>i<1Fm;G4_?a;-jN1orezp!x4=eiuuuuyPz`Fx0u^L} z5+Xneb00GDv$CqIs=M`3U4Mk=%8EE~GAd4-6DLl@`Nkjr_($fLV~&Hse|gjl%rVF8 zU@lH`%yD3_DxZ~N{e8ARDLq_yiOYX68Qt4kY<*03t3+h&dq_DQpAQ>PI{$M#5>&-$ z>o@$%9j;y~J^b%CICUQH=?Um=eat%+odTT~@8JA~3olR2>O;ko&i@>b1mhZeDn3*; z=9ps^P}NQeMB%Yc1xdlAmQF@TKbg|_r1L+=L&o0PDHp8=sA-!?h-ifZ^E)~ID7o2n9)Zkdlx6Wc{w z{odByOhdL%mKPP=S-$7uQIJF7`!B2Zl zgNVl!z#zi^ns7INA|#wHmkHRqR`}UqJpweu$C))Yz+uR?+zQ+*to-vP2i@~{=m{FoN93XWmcbuw68Q^ z8RM!%DWdZ!Th|G?C6<8p8CEXQS_X2tQZZp{WQjhT*C*~Y?9}G8(3zh${WT@2@W*sM zp>w0e7|^Y>GNdX82!4x{9CR*OZZ&rVd&C@tsb}EC-hnSZee{=u#OUWxcLhgzgRhN}ZIA>8Y#DuXK`U2JYgZyB7;!ZpN9H+iR5JS2E17p02RHANv zIFvEK?$Q37)$6Q0kGPo9N9wfe<`PA%IJtuEzUlgR2we1HzK-wp%pam$CM=AM?uV>@ zz(>Dh^IPaLYuds;OE)I?9V!}#(padW#vN||mVdc}|E;P|MO$>w;HT8q{w#MG3^USP z!PO60f41C20inxg6X!p$Pa5@-Nt6O<0j&RmjW256F5^nOTzA>(vG%W={~GVLl8GfO zsdp#qwC)+Y5PV7)bKyG#5Ne~HRBX5s78}1};|s2TyWam~-p-}d!~c+#`*@eYLd8m0 zGDO*_jymGld*5lF$Vj;&|Cr5TtwwbOeDpguFM_E5ZG^?G+iF^%htDGuaT!0x!NT7 zj2FRs4b1eP&;DYPP6N|vEgSa|!pb-0g@tXg^`T)*)Df>?>{HgDbqTaou>v$o9CghE zL&fPJ+-|J~ewmK0+p?*&)jNxLY7fer7xAvuh*PCSeS)o}z20Sk-dQ$3E{IdQqNq@F zn{-Z&F#&sYK4xVX$A!d`R*@IY`JCP3v^zf_5WzK5w4NUxoS!7dLg#)wb95o>x&1ZHF7{pY zQ}|1CSE#^WqW3w@ODPcx{|24U=)PR-5N``7#J&p<9;bVn;8>|Z=OXRvxMz}zQkK1f z2`1{aU>BN@%2If%%2@J(-X`7)w3bj2?HhEO)z|Evr+Xdmdq_(v)Lbzos28V-{HW2} ze#23rqg6il*Om!aa0KEm?ayeR!Fz__9-AN2xri=1^a30IOWeik{#B7$@*5}A&Oe7- zLPhn|!WA~IrQ%fJaFCj}$tz2odI@_OBDSuv{xMtMDZh3DKcroF(78_MVzoEiOPrTWtQe%9wMPHBI|};kfuc>?WsP z=Jv;2*`jwoFV=gS&ad!ZfClnW?;<`vs1YYIuoj?EE9^Ws}Z7P4^FY zFEK}k`j|aomHthQK_Y_@H;C!fwT~U zmFIE4Disb-;(v*-P}J{(A3+?hXKx%jr7{|48}Dz>aUmc8ypxD6O7>H_ZBp@TmvmrA ztBG@#Af+Y*O4B-t^CiJEWj>bZ-lF~T9@J4b|vFyQXvGzt5(T$Dwx2N8A?VWC}QzxuN{qUsdgXQv4Z zEP^iL>YGbDIFrqdGtWVl_!m~_E~f#3#7%|k#e z65M6Tw)RoPSaRb&ifP9Ti#=Vidxa57%LF9^JytFntzz4ws*Hvt9j|*G(?~Gr(f~vn z=F@WXxb@!degm|}?KBQ75?n{#0`1c(FQ5E~)?!w2 z5B{scQ+2#4kjbK=g`=Th6k(f_U;?ErNvu+dlDZF#YXAEYauEvmN$sc863t_~i2K!s zberzy*cZ)7Tb+7wgr%eD-ScNe=dWhA4-$2@rQ_E#_wy4gj(7H@42;Z{a*!_{v3T2obiCC6NZv`Cr3{DkZUv zc)@5+VU4oZ#^+5#>uK~3VyVzj6Tinm5F#LjMfXE|i%yLA0wVKj;(3_6$Wsh4_UgLF zxR1wPGYC;nXZ$ji>8@DP7I|cJ=8dRQTOzRN{Kf?1W!lyM8t+VX70w;Rv!w_7;w||r zRtnjE2LD&sm&#(WO!qpg-yzV6kSif1A)BAl{+rV96gy}EP4k*Mu5lqu##o%F9c3@e zu!~qOmWE}zALG3YkQ}~{mb3->2L3j!9~KJt@ZZO~q|6{%mV0Ls>Xl7|RvW{=vB9IzQpmSNZkJ69*ZM zUD7TtpDgr3O_`+J`5&_JJ{#9)x%fS3(Eh9Hdv~t0`W!u>NH%9J6IDAMZwX_vVH^eu z)qY8Cd|2+r2JJWLz0c47nwAUD*`|FFw;WNbw{iN2HcZ#t&sYo=t1qjoKa%u}t0QCV!fWW42zCJ0zE`t0>b%d|pCB4#@86NfkZs&) z#mNyR?^BUZEzNPt)Neyt_e-emnJti6dnWSC|Mcj^2B_blE^#^aLmCil-66c;?QeGwR!F&)x< zA6!=c3>_zCr;^A6xeZ|kFhrd8N%euDGDxQqv^u)XD6R@2u%hs=Qn7uGjUTi6XSf62 z=iWBmPY{c=zn2J)Ok~N)Lh=Tv1u?@e&m82f&V_BmXet>5B*j`uwFQVpH3 zNB0`xF721G&m=D>&CU;U7-LM*X~Z(wGS0qgpTmaE^}QJT1D($}{~X@;R3b|NND(6z zN>Nuw7FBUt`8L7(T>1W#ynztlU7R>+7 zG8dNdf5X=MC`~Jk;0Ea7_W)L(W90`Xmd`K-P7=~^K%FMDX(+i(+M;!i);T&i>KKa% zcTt+v=UDkaAkeWi_x>e4X3b^E;2VRfrjuJyO^nHi>*0$(UR-)EvPDRNNVY?2TL{bS zU#SPFQ(<_SL9TRcR%p^PC0XFgKj6JkGWT!)3g;N!w*i7(db?z|B->BpED;pgcCvG( z#k-Imm=;x>#{rGcTZLe9c37t;{M0UCAD!N5C_L;Y(nXcMEcJ{ja}{QCC+no0R%I+L zmIOvs7^8*V#5rLue;vlyT$~tY>=mO?@|&OHp(0fLR%TSwn|sR_FPc9}H--)=GssoZ zp(hKQDl)B@+cp-Y!;To~;x*x{X_`2fB~cz>rECD{E69}L@p;Rqm4TsVJn1gd%`ckH zu97T<8cJa-&k|z~(lEaPkKdGxr5O*B!?yK|=>lVx>53v_b5Ji%3y241X|4-nE{oJ0 z{6CkaqG}@lRu@Kp%}JplWd^xQ3hOKs$O3C@$40UXl)X`G4gzN9YKs<&Os00rn1WOA zmUTjjW)eD3i03G>WEe{dXMT}#cgdos=aDkT+{PO~&FC{fSSlpKGB&_yWD+HcW4f}E zq54Cb-`g5lrjDzuWbqeG0t>4sj|pj|Pek@#K3l8o3|wl3CN`3j6&{bbTr*q7l**XV zh5r>*&75_DN~?<)G(C*16>82OABe%-i?N_^Zr_-E4D?l*pHfz?!iq5)2}u$S9nbSS z(kT(o{!Zq_k!5PR%27FwFj&n>=iS2Vl*(rW2O7<& z39ImN4Bo;5<;uy9s?BU6V~RIHWCLBK1#;mmM7t*|mN7f6Bs>KMvg$hJByX;6YpYm3 znQP|xor)N$bmW5hjRmQ(z9(vzqzeOMrP9zCWd^w#TCymsi61Z9s7Vdc`i=bIJ12<| zRavL)!CRcuuS!(*Fq@+*Z4!K-Gg%rK znw4=}t5h>*gDx3_N~h-lCm6wT!5ke}6b%+0{gp0eh)Q2`o{ffCiVtbO#KwpG@^AAe z-V1n1j9l?8)1^_4y0cPw)J1H@$)tlO@pfkJ?E3wN!oaPjLn!E?bT1((_NtFxe zxO%hSuwbal5T7ESQWjj7Iag}RM1&C}PR>1VdMZ$u=Xc65JK|J9RhBG(UJrj4(V!c# za%Qr(KiCvTVTj)^jXw?S;GKB{%mBR}x{vLGMn~un;qHC<^YHk2LNPnylsSb-_x=-z z%mWeQ_h>I896DbS>UtfOd;iK)_`%M;K_71kCu1N6xOoR1j-eS2nwjJp+V&Y^5Q+wV zkFZybF@I?MJh_-1aY~Rom&u*u=1lu;ev#eYD9h4;tO|-dusXtN;P(jnxyM3?dRY?X z1e*uGMA3cPrwKxOJ1C1*gVrM59`<-rGG8)fsL!DBgd*8^5n05L$j@AKcR=I1ba%)5 z?em@JLmVnPLPrSD5kd?-k#(pDBXcW8*h5+92tT583&);ooQW}O+9}y%5oKpx*dq*C zIYW0Rzjbv4YIlkz#(=q)AyYNBiF(h7%;jVc722r8AZB$LASdnvzg!v)~NoN@-fm+S+Ll z-Xh&yI(O1*u^OyC&CRcXhqO?sti&WH%b4RL8gzRojkkmpbo;apEt6k55u$*AY68~X)m*K)|Bb&AjI6WH!)^koQiN9{66cOxJ_*5Q6@-s zm(YFuh^-sgKm(_Ndzg;$VcH3>8{l$t+gvECHKK`oV%)Seb7VML;sl&JiT5y%yVbeN zll@%L#B1U`EYJApyTt4!cGIloY_Z>);f^e3vD^02IdX*cRy4_CHNDYQJSAQUuoz>? z7sbOJ0~Dr%PA^WWXCOI^l3h7gIImSAa&Y|2BxXyT525(nUSIl`C~aeA=Fzr}E`V`3eIaW!2J%#U46gqaYhy=18#d*017 z9W$ox9(r=393}fn!eE-q+ntNYA)@9M*e4Fjf$b2L{(ZpPHUg21K^r;d&2opw(iF@* zhWyMbX2%tgIS=YC#6KANQ&c%5mZl^3xbZW4mY&o>gW1PP`I$+~#c3$AY}48tC6p5_<6E$gv80eiyu}mfzS~vXOMENHN!q<-%8WHK6Zol3F90~^3(V|yrp4v z4Ugu=ynU+zX_XXIl6_F5cP#g|5zV1@mDS$La>P{=M@pQ!JyuSabrIbB3azUTYjLov z0;N$A?IpT91Q9^kz+1w~Dw4x%C`^x=YyhW5E4DpVeuO7CoV&OFCZlhxy zfw%ZjrKlEJ%En%gFfuvRgk9ss&y|%mzeTKsqa{v25CAw1z22iqo@t;7B2Jwq=(BNy z&Nf=pUNY%w;9=Vhc9Y&NTGL*}7T8&4(Rp&3NpR%E$?xOX<_~vR_Lm8xT_-}Kg#6I> z$GbbUPb1*wmjKcte7GYxyQ0jt+4>T{Z}Q1^?>tmCW&=k~oWd~QEv>AY9;Ur#7Eu;0 zm(DHxR8^`dW$)ob0EC+E4xu*2XBf^GP7~k=xgx;$7^Fn0N9?U~T*4jvUA!f;(WGO# z6<5UYWYvd(ut)n0L7!e9G~OA4&?I%AV@w<^aS9@A0i=67BXIcsJMVaUcNqEVk%X;iM71Bbv{ z!gC2?Y;YFMukomyWphw=Zq7EV-$KbiW zQdEIua{eV46_&bhW^^GQx3)!l5!*#;03iyaV}3wzJj|jv4Kvb)564NfKaGp*97LQq zqLCvw87KSGbjTfsW#SdhqENXRT*Jm(5skuZiPLncG!6-IrUyzai9@)jc1(zorsdG4C0|~(-?T%_?bP-jyN$-@iYb=H-2UeGbK)Q%<*V3Q?7_P=6JN2 zi_;u)92jP5-|3K$WOoT+Hr7@r*QUpW8WnTd zo086qVXmDH3)!MyGX3Qf`QB)ZP6zRn$imx;Q|NxC(^Qt`$2T&}wbLFjx+O*}z(mfg z2dIVVon1BV>^R*mil@x)WP~$KqOl)-R7@D>vNX@{lwdASdq6%w#fq3o^E&}NK(S{U zfjSI~bsZDzFZ+wh3S}W;^Y=LIR*LPQDsCBdQq09<7Xx@7pLJcnLPKE->I_VACWX|bb7+dl4 zQ(0g{?LqepL3$sUjz(V$Cilh9%waB06JUxIMtj~pq%}bZ;MnECxYw;G5kugG;g}DLgwwzg=m=5?n3TiAIA?+k3 z?bBv)5(MZ7ELzT^W~+clyJ^#M>Fv_p1x%u+FkrLH0D6la_QZ{@8c~JMktUEU7WJzQR!H z0_-N89okE*oCDCBn|EjpnpK76QvaKXgg3ywHBUDyqboM9qrz>=s8S_w&T0T~@KOIP3g?oh_w&AIfWo*gh zC;1;0W<{Jr^^I$LcolwplDE%dBx-P2B*`Np-u;3fel3CDKf_u>BBmTbA~{o3Xh?vJ zNceod#rip=?W$%t^z2XN7uT^AmeLP18>eD@n{R%ebwZsu1(jdni8(|yE8;XMCds@a z({l*>yYe4x$*RF-C25y3W)!KP&4`(mTvn`#T5CkQno+3JX~IfctdXeH-Di$qB>W7^ zSR+wK{G?NYSrI2&{`h46>7BbKcjfn6w9_@osy+Sdrh`aMG-whLO8&0ZIRdnmOR0|Y zm0Ec;O95CVQ*hGZD-z0u9vEg=CNhR4O%+p764y$dk+*|A?BrNH-vY3os1f=^F*_XU z7;l|RC+~=>k-Y8$yuQf!WkoWY1ziabup^u(*BU{CFpZ6HEsBOkAXJ!svK1m!G7G3n zR$`fZ@IEA`7#h%k5E&{!mg!exFe2rIIUCw3DK80jfD@?#t13(v5&|g#B_j!`1sj4+ z*Bc3M1+Ki7)ahma_I)WLrG@evuz*Gj(?cR}S}75dy|1!W*pzx9-}i0>2o0bcO58_= zDW8>|nF0=PoaK$AX&Yp@dmRX%U$^?oiV1Qa9wa@JQWNEmPn9bUTg#1y84)J{M3x0H*x6Z0wDlHkS zANXuVRaTKw1nPq?j^>f_p@%9eaeVOp~?rG&L%I*$t+yQv8!P{ry7$C)cwSJ5D zcIAr=-Z-axrs=?->dgby2RvtU6+JIJK##*y1LnuZ|`v3r`Y=R<1*l9Uyu-g zcZt>0rS5&>4DWuy-xs>~)e{(ZMOtjN!MkVkhi`wu&B$~Vf;T>;OGu0?`N9Nh=)mxa-n`Zg{g!m^zr(8np2~~SDwx-r zn~|Z0Ry5`7i+uBQfVW}Y1;INz^19C}Emqxqxjkk!$Vgab`5|H@kOC<~UcDtd8e#FH zHot#{e}9IR2EyWldwlSvbnYXQWk6aNOFH-2+?N02YlOv0gP*qf{WJXdq$%*Hoz&_` zYyJEl-IyPr%!>(&x4Y<`Q31)5t$_7_AD`qupW*v0^YFd9$PgPTLz%Jq{gz?%m6l=k z@4iHarPq9Chx5ny_h`ftm-0S<4!L>{VX@{yLuQF&1PE{o z@7uQX_q7GUH@E2Zq%)Dbc@K~A3l=|Kjkpq+?tLZex82lK8%{ZYE?HYNbvN(v zvpcMB^IjKQ@YBp@-&`1R9VSO%dkG}-!t?8bCs&`6~=QdZwM&bw!!p@`+Hi>%#XE8x8@ zf4!(2H)l0S%oy9a@80eLbR&RQ7c&NUHAKc-=}Td;;^5gTSdgONUlAZf_1>-_`|B0F zMUwYz+x+QQ03Yr0whLCJb%iYxg^;(d>t}kAcEX5g{^GA-YFPkVL7{t_>eQz6HCsWl zXp{`0>`<1mChsoOQTUqo?i%9%_B2jY?$e(#BjQBCoek0!w36S!LLw7iL?<*4y#^aQ zdA%2pbH%5p%t=1T>w*j-)l;%1SUW~1l5Cr5ZQB&IdEKU`0JcK8=H}GiT7(8X1uADOfoHSk z&{1p#1d(!t>}Xno*X>+26%j;q6fMDv$MEcQU`j5B%4{2vMrrjb!q1BVr?}snx@n>B+~{25BO5keq5LTc-Oq!-^Fc zrp)T8hBC4Q2v%(D5WtV2z^Z5E)3`|MisVUy?=SMsF2F`8FI#FOl(yu>MQ9An#fnb) zzAK4~GJ}w74jU1E^1hAnTCYP^#u+~PD!&5b^jo1=h4NrAj`7Blx~iqG0p4;M6)`h5 zW=fng2n$D;KL#Iuf5-{kR->kF_Hjk9Qg>Rx5yoyDY%woTcwSp9Yo+$%u=g7Mn&zRy z1zS0N32a6cJO zk(JV|>5eTrL0TDu^rh)|^E%WhwlgmrxX0nP7^i8pnnel)iHc#5Z zgh4iS+QP6J#5fPqai3@{0okA_vr78PcKU4sry*ZyvL4Ze4UH{$zFF2hg}N=F zY>}$dVjzW9T1cDRY8tck+E!{ip@>1^d-vP0Vkze(gnSfAotEsv%^s_bk?XlJFq`7! zq}F*ZGz~mKD+ai&r_YM9PWJ`P$Vxp8md*|b7{EiKog^f!+1V^eHJD3BFa6VyDk zSqbUHhP{?xRSb!$SirGpHwa_4;Pt+uA(LHHKQ@b{^9^HBjobPFWTg}8E|VIhvvVaLSJn(q>kB$ad$b@SHx_@vJ19g#lmSCFIMdYZ&wVSr&ty0YP#eQ7A;E+ zJ%`+sFKVu8fRD6X+fj~1SIdp!i`bHA?AGg$lnE?0!raGg*n`!@8sdBRTcMZ_-4IW! zu9hFgxQ%kCamadvEm#wHF0a742H1$@g?syQNX)1>2}H73FTS5EU)kkq4Dd@$Ht`9I zmc?Z&9VLa834p_ep6Uwe$8?~h^IE`*$;e*FpEwqN%ttXqx!-opA~P>b#0MBQXv){) zgh{T(T#d$KH7!$dF$380g63unaKU0=VP1g4YJ?xr(RATwS*VDGsJ!p^t(Q^U8rm2L z%=Ii*>t1cFezWD8HZ-%JpcUf@HnKAJxEbPGv@I^!aEuFm)e$m?*@$WPl_RE)=a^A( zvg&MLhf^_5pY?J&mNs0l6pQ&Nsd}6iqD~+)@02|hX@?)7%3;Jpc=~%2Kvl8ISwO!UNfDPp3efT84@y9>@amuQXE$)|t zK`XjDfQTSc8VR(LJ}ri9)*f6-!YD(P7~%ruG$h59>(?ro$X$!e4bY}!3q`X)zxL$Z zFoy3#I614e4;8_Vx)MtPuM5S=y;cYhAcFqz_noNq3PzvxOnOF_>5SiR3L=8O(n!O0 zg&HH-9&w^^49uc9je`fN+iKF4XEF?|0WWh!oQ@w{g3GB{O^^(fnDtn86aD5+vOE~} zzK=Qf*=f^aHjTZ#u`uoU82{%vs2_4_Rsn_I=W5}QQaiJ7#>B%Njt7SQblN^Jvmvl^ z4B|YwBVmriz)>~!4jcz$d>=eI%BQf3dvdNZc@i-frz3!aTE)$=7v|zL#~cTS{|}Yy V7sWprRrO3P?wqO6LN1et%fjmaN&|?tY)=KKHrr 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 literal 0 HcmV?d00001 diff --git a/linphone/pixmaps/linphone2.xpm b/linphone/pixmaps/linphone2.xpm new file mode 100644 index 000000000..717f8c42f --- /dev/null +++ b/linphone/pixmaps/linphone2.xpm @@ -0,0 +1,883 @@ +/* XPM */ +static char * linphone2_xpm[] = { +"50 45 835 2", +" c None", +". c #211F1D", +"+ c #53514E", +"@ c #5F5D59", +"# c #7D7C78", +"$ c #605F5C", +"% c #94928C", +"& c #95938D", +"* c #7B7A77", +"= c #605E5C", +"- c #353432", +"; c #585754", +"> c #84827D", +", c #B9B6B0", +"' c #D9D5CE", +") c #DFDBD3", +"! c #EAE6DE", +"~ c #EFEBE2", +"{ c #EEEAE1", +"] c #EFEBE3", +"^ c #EEEAE2", +"/ c #75726D", +"( c #5E5C58", +"_ c #7D7B77", +": c #BAB6AF", +"< c #E5E1D8", +"[ c #DAD7CF", +"} c #C8C4BD", +"| c #898782", +"1 c #949089", +"2 c #938F88", +"3 c #5B5854", +"4 c #45433F", +"5 c #4D4943", +"6 c #5F5C56", +"7 c #A5A199", +"8 c #DCD5C5", +"9 c #6F6B63", +"0 c #42413F", +"a c #A19E97", +"b c #DAD6CE", +"c c #EDE9E1", +"d c #D4D0C9", +"e c #96928C", +"f c #63605B", +"g c #827C73", +"h c #6F6961", +"i c #90877A", +"j c #8E8578", +"k c #B4A999", +"l c #B9AD9D", +"m c #C0B5A3", +"n c #BCB1A0", +"o c #858075", +"p c #C3BCAE", +"q c #EAE5DB", +"r c #E0D9C9", +"s c #C5BDAE", +"t c #20201E", +"u c #8D8B86", +"v c #CAC7C1", +"w c #D2CEC6", +"x c #918F89", +"y c #5D5A56", +"z c #A0998F", +"A c #827B6F", +"B c #C0B4A2", +"C c #C2B7A5", +"D c #C1B6A4", +"E c #8A8174", +"F c #94918B", +"G c #C7C3BB", +"H c #AFAAA1", +"I c #938B7E", +"J c #646058", +"K c #D8D1C3", +"L c #ECE7DE", +"M c #EBE7DD", +"N c #E4DED0", +"O c #DED6C5", +"P c #57544D", +"Q c #202020", +"R c #7E7C77", +"S c #DFDCD4", +"T c #F0ECE4", +"U c #EDE9E0", +"V c #ECE8E1", +"W c #B6B2AB", +"X c #77736E", +"Y c #767067", +"Z c #A3998B", +"` c #BCB09F", +" . c #C3B7A6", +".. c #BFB3A1", +"+. c #C3B8A7", +"@. c #BFB4A2", +"#. c #BDB2A1", +"$. c #3E3B35", +"%. c #BBB4A6", +"&. c #A7A39C", +"*. c #ECE9E1", +"=. c #77736A", +"-. c #E7E1D5", +";. c #E3DDCE", +">. c #8F897F", +",. c #22201E", +"'. c #91908C", +"). c #EFECE3", +"!. c #EBE7DE", +"~. c #878581", +"{. c #5B574F", +"]. c #7F786C", +"^. c #8D867A", +"/. c #9C9994", +"(. c #98958F", +"_. c #837B6E", +":. c #C4B9A7", +"<. c #958B7E", +"[. c #736D62", +"}. c #4E4942", +"|. c #4C4842", +"1. c #383632", +"2. c #99968F", +"3. c #ECE8DE", +"4. c #7C7972", +"5. c #CCC6BB", +"6. c #E9E4D9", +"7. c #EDE8DF", +"8. c #E1D9C9", +"9. c #BFB8A9", +"0. c #1A1A1A", +"a. c #C3BFB8", +"b. c #CFCCC4", +"c. c #85827C", +"d. c #56514A", +"e. c #A69C8D", +"f. c #BFB3A2", +"g. c #C2B7A6", +"h. c #B4AA9A", +"i. c #757168", +"j. c #706D68", +"k. c #918E88", +"l. c #464441", +"m. c #97948E", +"n. c #C9C6BF", +"o. c #8C8A85", +"p. c #8E897F", +"q. c #999488", +"r. c #817E77", +"s. c #C1BEB7", +"t. c #807D75", +"u. c #8A8377", +"v. c #6E6A63", +"w. c #A8A49C", +"x. c #EAE4D9", +"y. c #E4DDCF", +"z. c #D8D0C0", +"A. c #AFA99C", +"B. c #848076", +"C. c #BFBBB4", +"D. c #B1AEA8", +"E. c #47443F", +"F. c #5C5851", +"G. c #686259", +"H. c #B0A595", +"I. c #B7AC9B", +"J. c #817A6F", +"K. c #7E7A70", +"L. c #AEA99D", +"M. c #9A9791", +"N. c #EEE9E1", +"O. c #E6E2DA", +"P. c #CCC8BF", +"Q. c #E3DCCE", +"R. c #86827A", +"S. c #C6C3BC", +"T. c #7C7974", +"U. c #4A4642", +"V. c #6E685F", +"W. c #89837A", +"X. c #7B7873", +"Y. c #9A9892", +"Z. c #827D73", +"`. c #56534C", +" + c #6A675E", +".+ c #E2DBCC", +"++ c #EDE9DF", +"@+ c #DED8CC", +"#+ c #DDD5C4", +"$+ c #C4BDAE", +"%+ c #6F6B62", +"&+ c #312F2B", +"*+ c #6D6960", +"=+ c #A19B8F", +"-+ c #E5E1DA", +";+ c #7F7D79", +">+ c #CFCBC3", +",+ c #ACA9A2", +"'+ c #B6B1A8", +")+ c #B4B0AA", +"!+ c #827F7A", +"~+ c #444340", +"{+ c #262524", +"]+ c #C1BEB8", +"^+ c #9A968D", +"/+ c #242322", +"(+ c #CEC7B7", +"_+ c #DFD8C7", +":+ c #E6E0D3", +"<+ c #747067", +"[+ c #D3CCBC", +"}+ c #857F74", +"|+ c #595856", +"1+ c #CCC8C2", +"2+ c #D4D1C9", +"3+ c #ECE8DF", +"4+ c #CFCBC4", +"5+ c #93918C", +"6+ c #2F2E2C", +"7+ c #312F2C", +"8+ c #969185", +"9+ c #BAB3A5", +"0+ c #B1AB9D", +"a+ c #363532", +"b+ c #E2DED5", +"c+ c #676360", +"d+ c #4C4B4A", +"e+ c #767471", +"f+ c #75736D", +"g+ c #5B5956", +"h+ c #928D81", +"i+ c #E5DFD2", +"j+ c #EEE9E0", +"k+ c #EBE6DB", +"l+ c #C0B9AB", +"m+ c #A7A195", +"n+ c #8D887E", +"o+ c #C4BCAD", +"p+ c #BCB8B1", +"q+ c #D5D1C9", +"r+ c #7A746D", +"s+ c #AEABA4", +"t+ c #B2AFA8", +"u+ c #98948D", +"v+ c #7D7A76", +"w+ c #69655D", +"x+ c #9B9589", +"y+ c #A9A396", +"z+ c #A7A49F", +"A+ c #D8D2C9", +"B+ c #948F83", +"C+ c #454340", +"D+ c #D7D3CC", +"E+ c #63615E", +"F+ c #141414", +"G+ c #000000", +"H+ c #53504A", +"I+ c #EBE7DC", +"J+ c #E4DDD0", +"K+ c #898479", +"L+ c #ADA79A", +"M+ c #CBC3B4", +"N+ c #89847A", +"O+ c #CDC6B6", +"P+ c #AAA59C", +"Q+ c #9F9D98", +"R+ c #E6E2D9", +"S+ c #AFACA7", +"T+ c #615F5C", +"U+ c #201F1D", +"V+ c #66625B", +"W+ c #AEA89A", +"X+ c #AEA89B", +"Y+ c #B7B0A2", +"Z+ c #070707", +"`+ c #E0DED9", +" @ c #CFC7B8", +".@ c #6B6863", +"+@ c #63625E", +"@@ c #DBD3C3", +"#@ c #534D46", +"$@ c #807E7B", +"%@ c #DDD9D1", +"&@ c #36322E", +"*@ c #4B4A49", +"=@ c #6E6C67", +"-@ c #E5DED1", +";@ c #E9E4D8", +">@ c #EFEAE2", +",@ c #E2DCD0", +"'@ c #8F8A7F", +")@ c #999387", +"!@ c #4E4B45", +"~@ c #6B665E", +"{@ c #47433D", +"]@ c #D4CDC0", +"^@ c #E8E3DA", +"/@ c #1F1E1E", +"(@ c #65615A", +"_@ c #ADA699", +":@ c #949494", +"<@ c #BEBEBC", +"[@ c #DAD2C2", +"}@ c #7F7B74", +"|@ c #4D4D4D", +"1@ c #959084", +"2@ c #DAD5C9", +"3@ c #B9B1A2", +"4@ c #3C3934", +"5@ c #989693", +"6@ c #B1ADA5", +"7@ c #76746F", +"8@ c #4C4A44", +"9@ c #DCD4C3", +"0@ c #E9E3D8", +"a@ c #DCD8CE", +"b@ c #A6A49E", +"c@ c #9C9890", +"d@ c #7B776D", +"e@ c #55534E", +"f@ c #B5B3AD", +"g@ c #474440", +"h@ c #D0C9B9", +"i@ c #E7E2D7", +"j@ c #65635D", +"k@ c #4F4E4C", +"l@ c #B7B1A3", +"m@ c #B7B3A9", +"n@ c #96948E", +"o@ c #BCBBBB", +"p@ c #BCB6A9", +"q@ c #ABA6A1", +"r@ c #8E8C87", +"s@ c #161514", +"t@ c #545350", +"u@ c #B9B1A1", +"v@ c #958F84", +"w@ c #8C867B", +"x@ c #81796E", +"y@ c #BFB4A3", +"z@ c #C6BBAA", +"A@ c #5E5B53", +"B@ c #96938D", +"C@ c #696762", +"D@ c #DFD7C7", +"E@ c #C6C2B9", +"F@ c #817C72", +"G@ c #B3AC9F", +"H@ c #B5AFA4", +"I@ c #6C6964", +"J@ c #DFD8C9", +"K@ c #9C9C9B", +"L@ c #716E6A", +"M@ c #B8B1A3", +"N@ c #2A2926", +"O@ c #625F58", +"P@ c #E0D8C9", +"Q@ c #C1BAAB", +"R@ c #252321", +"S@ c #E1DDD5", +"T@ c #7B7977", +"U@ c #625E57", +"V@ c #322F2A", +"W@ c #C4B9A8", +"X@ c #D1C7B6", +"Y@ c #C1B5A4", +"Z@ c #C8BEAC", +"`@ c #9A9387", +" # c #2D2C28", +".# c #595752", +"+# c #A29D94", +"@# c #D5CEBD", +"## c #CBC4B4", +"$# c #DBD3C2", +"%# c #A09C94", +"&# c #C1C1C1", +"*# c #95938E", +"=# c #7F7A70", +"-# c #8B867C", +";# c #D6D0C4", +"># c #C9C2B3", +",# c #7C7B78", +"'# c #BEBBB5", +")# c #D1CABA", +"!# c #44423F", +"~# c #D6D2CA", +"{# c #3A3835", +"]# c #262421", +"^# c #33302C", +"/# c #69645B", +"(# c #8B8478", +"_# c #5F5951", +":# c #605C53", +"<# c #67635B", +"[# c #BFB8AA", +"}# c #928D82", +"|# c #B8B2A4", +"1# c #938F85", +"2# c #989287", +"3# c #89857C", +"4# c #706E6A", +"5# c #DED7C6", +"6# c #928F88", +"7# c #979797", +"8# c #B4AEA2", +"9# c #918C81", +"0# c #68645C", +"a# c #979286", +"b# c #4A4741", +"c# c #5E5D5A", +"d# c #B2AFAA", +"e# c #47453F", +"f# c #C2BBAC", +"g# c #B5AEA0", +"h# c #D4CDBC", +"i# c #CAC7C0", +"j# c #B5AEA1", +"k# c #CCC4B5", +"l# c #ACABA7", +"m# c #797979", +"n# c #757169", +"o# c #BDB6A7", +"p# c #68655D", +"q# c #A09B92", +"r# c #D1CABB", +"s# c #8D887D", +"t# c #80807F", +"u# c #C5BEAF", +"v# c #1E1D1B", +"w# c #A3A099", +"x# c #888681", +"y# c #6A6864", +"z# c #B3AEA3", +"A# c #4D4A44", +"B# c #D6CFBE", +"C# c #A29E95", +"D# c #C1BAAC", +"E# c #918C82", +"F# c #6D6961", +"G# c #B9B3A5", +"H# c #979084", +"I# c #3A3836", +"J# c #BDBBB7", +"K# c #C7C0B1", +"L# c #6C6860", +"M# c #D2CBBB", +"N# c #393836", +"O# c #66635D", +"P# c #A19D94", +"Q# c #656461", +"R# c #32302C", +"S# c #CCC5B5", +"T# c #DEDAD1", +"U# c #B1ACA3", +"V# c #7C7C7C", +"W# c #B5B4B1", +"X# c #5A5853", +"Y# c #4F4C46", +"Z# c #A09A8E", +"`# c #76726A", +" $ c #88857F", +".$ c #4B4843", +"+$ c #DAD2C1", +"@$ c #B4ADA0", +"#$ c #B7B4AF", +"$$ c #CCC9C2", +"%$ c #282623", +"&$ c #888378", +"*$ c #262522", +"=$ c #A8A194", +"-$ c #9A9388", +";$ c #BEB7A8", +">$ c #E3DCCD", +",$ c #D1CEC6", +"'$ c #ACA699", +")$ c #AFA99B", +"!$ c #B2ADA2", +"~$ c #A09D97", +"{$ c #C0BCB5", +"]$ c #B0A99C", +"^$ c #7A776F", +"/$ c #99958E", +"($ c #8A8681", +"_$ c #777068", +":$ c #B3AB9D", +"<$ c #131211", +"[$ c #5D5A53", +"}$ c #090908", +"|$ c #8C877C", +"1$ c #C7C1B4", +"2$ c #D3CEC5", +"3$ c #EAE5DA", +"4$ c #83817D", +"5$ c #C7C0B0", +"6$ c #484743", +"7$ c #C3BFB7", +"8$ c #C7C1B3", +"9$ c #9E998F", +"0$ c #CCC9C1", +"a$ c #C3C0B8", +"b$ c #817E78", +"c$ c #7F786E", +"d$ c #AFA494", +"e$ c #ABA396", +"f$ c #474645", +"g$ c #BCB9B3", +"h$ c #9B9893", +"i$ c #2B2926", +"j$ c #070706", +"k$ c #74716D", +"l$ c #B7B4AD", +"m$ c #484641", +"n$ c #504D47", +"o$ c #DBD6CC", +"p$ c #65615B", +"q$ c #DCD5C6", +"r$ c #B3ADA1", +"s$ c #A8A296", +"t$ c #949086", +"u$ c #999690", +"v$ c #AAA6A0", +"w$ c #6D675F", +"x$ c #A09789", +"y$ c #C2B6A5", +"z$ c #6C6259", +"A$ c #66645F", +"B$ c #2D2D2D", +"C$ c #64615B", +"D$ c #2F2D2A", +"E$ c #8B8781", +"F$ c #64625D", +"G$ c #0A0908", +"H$ c #393733", +"I$ c #C2BAAB", +"J$ c #D9D5CD", +"K$ c #9C978C", +"L$ c #CFC8B8", +"M$ c #9C968A", +"N$ c #928D83", +"O$ c #98958E", +"P$ c #CBC8C0", +"Q$ c #B1ADA7", +"R$ c #8D8A84", +"S$ c #878177", +"T$ c #B4AA9B", +"U$ c #B3A898", +"V$ c #7A7368", +"W$ c #706E6B", +"X$ c #292826", +"Y$ c #A9A499", +"Z$ c #3F3E3C", +"`$ c #1B1A18", +" % c #9F9C96", +".% c #2D2A27", +"+% c #C8C1B1", +"@% c #E6DFD2", +"#% c #C0BDB7", +"$% c #8C8982", +"%% c #C7C3BC", +"&% c #8E8B84", +"*% c #958E86", +"=% c #837B6F", +"-% c #AFA595", +";% c #80796E", +">% c #31302D", +",% c #8F8C87", +"'% c #74726E", +")% c #5E5C57", +"!% c #393430", +"~% c #413F3B", +"{% c #413C37", +"]% c #605E5A", +"^% c #22201D", +"/% c #0C0B0A", +"(% c #E9E4DA", +"_% c #D6CFC2", +":% c #7E766A", +"<% c #C0B4A3", +"[% c #C1B6A5", +"}% c #605B52", +"|% c #97938B", +"1% c #181817", +"2% c #0A0A0A", +"3% c #8D8981", +"4% c #787369", +"5% c #D4CFC6", +"6% c #DCD6C9", +"7% c #CAC6BC", +"8% c #A5A096", +"9% c #78756E", +"0% c #726E65", +"a% c #4A4742", +"b% c #605E59", +"c% c #363433", +"d% c #0B0A0A", +"e% c #BFB5A5", +"f% c #C3B8A6", +"g% c #6C6359", +"h% c #7C786E", +"i% c #46433D", +"j% c #55534F", +"k% c #BAB5AB", +"l% c #E1DACA", +"m% c #B1AA9C", +"n% c #928B80", +"o% c #ACA598", +"p% c #CCC5B8", +"q% c #E1DACB", +"r% c #CFC9BE", +"s% c #44413C", +"t% c #23221F", +"u% c #AFA89B", +"v% c #D5CCBB", +"w% c #BEB2A1", +"x% c #A59A8B", +"y% c #5C564D", +"z% c #0F0F0E", +"A% c #65625C", +"B% c #B8B4AE", +"C% c #AAA498", +"D% c #55514B", +"E% c #332F2A", +"F% c #47443E", +"G% c #252320", +"H% c #3A3833", +"I% c #6B665C", +"J% c #857D71", +"K% c #90887B", +"L% c #CBC1B0", +"M% c #CBC1AF", +"N% c #DED7CA", +"O% c #9B968A", +"P% c #59554E", +"Q% c #B5AB9C", +"R% c #7B7469", +"S% c #57524A", +"T% c #040303", +"U% c #2F2D29", +"V% c #BEBBB4", +"W% c #D2CEC3", +"X% c #1D1C1A", +"Y% c #292827", +"Z% c #1C1A18", +"`% c #090807", +" & c #181613", +".& c #807A6E", +"+& c #DCD5C7", +"@& c #B8B2A5", +"#& c #191815", +"$& c #B8B0A2", +"%& c #C9C1B2", +"&& c #6A6259", +"*& c #AEA393", +"=& c #625D54", +"-& c #010100", +";& c #353431", +">& c #76736C", +",& c #C8C5BD", +"'& c #979287", +")& c #3A3733", +"!& c #413E39", +"~& c #8A8680", +"{& c #BFB8AB", +"]& c #3A3631", +"^& c #494440", +"/& c #3C3731", +"(& c #28231F", +"_& c #181715", +":& c #040404", +"<& c #3D3933", +"[& c #B9B1A3", +"}& c #85827B", +"|& c #080807", +"1& c #645F57", +"2& c #8F897E", +"3& c #71675D", +"4& c #B5AB9A", +"5& c #766E63", +"6& c #38342F", +"7& c #0D0C0B", +"8& c #0D0B0A", +"9& c #33312D", +"0& c #D5CFC4", +"a& c #DBD4C5", +"b& c #534E48", +"c& c #030303", +"d& c #5E5D5E", +"e& c #535153", +"f& c #666460", +"g& c #3D3B39", +"h& c #79756B", +"i& c #43413B", +"j& c #B9B4A9", +"k& c #D5D0C6", +"l& c #CEC8BC", +"m& c #BDB6A9", +"n& c #97948F", +"o& c #D5CEC0", +"p& c #B2AC9E", +"q& c #ADA293", +"r& c #797166", +"s& c #151412", +"t& c #76736D", +"u& c #DBD4C8", +"v& c #D9D2C1", +"w& c #2E2B28", +"x& c #171615", +"y& c #454243", +"z& c #2C2B2A", +"A& c #68655E", +"B& c #807C75", +"C& c #BAB5AA", +"D& c #D0CABD", +"E& c #D9D1C0", +"F& c #E1DACD", +"G& c #DCD3C3", +"H& c #D0C7B7", +"I& c #D6CEBE", +"J& c #A8A299", +"K& c #54524D", +"L& c #0B0A09", +"M& c #5E5A53", +"N& c #9C9486", +"O& c #948C7E", +"P& c #544F47", +"Q& c #0D0C0A", +"R& c #DDD7CC", +"S& c #E4DFD3", +"T& c #AFAA9F", +"U& c #847F76", +"V& c #BFB7AB", +"W& c #E5DFD1", +"X& c #E8E3D7", +"Y& c #C6BBA9", +"Z& c #C8BDAC", +"`& c #B8AE9F", +" * c #756F65", +".* c #46413B", +"+* c #6A665D", +"@* c #B0AA9C", +"#* c #D7CFBF", +"$* c #E0D8C8", +"%* c #B8B2A7", +"&* c #5B5851", +"** c #272623", +"=* c #191513", +"-* c #413F3A", +";* c #4B4842", +">* c #87837B", +",* c #B7B2A9", +"'* c #A6A199", +")* c #E7E1D4", +"!* c #D7CEBD", +"~* c #D9D1C2", +"{* c #CDC4B3", +"]* c #B1A89A", +"^* c #837D73", +"/* c #534F48", +"(* c #373531", +"_* c #22211F", +":* c #C7BFB0", +"<* c #3F3D38", +"[* c #A8A295", +"}* c #BAB5A9", +"|* c #3B3935", +"1* c #706C63", +"2* c #91887C", +"3* c #C1B7A7", +"4* c #B7AD9D", +"5* c #69645C", +"6* c #74716B", +"7* c #A19D95", +"8* c #918B82", +"9* c #484640", +"0* c #636058", +"a* c #68635B", +"b* c #38332F", +"c* c #0E0C0B", +"d* c #837E73", +"e* c #34322E", +"f* c #050505", +"g* c #060606", +"h* c #060505", +"i* c #12100E", +"j* c #78746C", +"k* c #C5C0B5", +"l* c #AFABA1", +"m* c #44433F", +"n* c #100E0C", +"o* c #21201D", +"p* c #6C6963", +"q* c #D0CBBF", +"r* c #53504B", +"s* c #4E4B44", +"t* c #CCC5B6", +"u* c #72716C", +"v* c #6E6C66", +"w* c #43403B", +"x* c #B0AA9F", +"y* c #85817A", +"z* c #D5CFC3", +"A* c #8C887E", +"B* c #2D2C2A", +"C* c #2A2723", +"D* c #65635E", +"E* c #BCB7AC", +"F* c #66625A", +"G* c #7F796F", +"H* c #96928A", +"I* c #CCC7BE", +"J* c #B5B1A9", +"K* c #938F86", +"L* c #CCC8BE", +"M* c #1E1C1A", +"N* c #817D73", +"O* c #191715", +"P* c #726D64", +"Q* c #747069", +"R* c #E8E2D6", +"S* c #99958B", +"T* c #E5E0D3", +"U* c #7F7C73", +"V* c #666159", +"W* c #1A1917", +"X* c #131110", +"Y* c #726E66", +"Z* c #45433E", +"`* c #D9D1C1", +" = c #1E1B19", +".= c #CDC5B5", +"+= c #A7A194", +"@= c #242220", +"#= c #42403B", +"$= c #060605", +"%= c #484540", +" ", +" . + @ # $ % & % * = ", +" - ; > , ' ) ! ~ { ] { ] { ~ ^ / ", +" ( _ : < ~ ^ ~ ^ [ } | 1 2 3 4 5 6 7 8 9 ", +" 0 a b ^ ^ ~ c d e f g h i j k l m n o p q r s ", +" t u v { ] { w x y z A B C m D E F G H I J K L M N O P ", +" Q R S T U V W X Y Z ` ...+.@.C #.$.%.&.*.=.O -.{ ;.O O >. ", +" ,.'.^ { ).!.~.{.].#.^./.(._.:.<.[.}.|.1.O 2.3.4.5.6.] 7.-.8.9. ", +" 0.a.{ ^ b.c.d.e.f.g.h.i.j.c k.l.m.n.o.p.q.O r.s.t.u.v.w.x.y.O z. ", +" A.B.C.D.9 E.F.G.H.I.J.K.L.] M.).N.] { O.P.Q.R.S.T.U.V.W.X.Y.R.Z.`. ", +" +O .+++@+O O #+$+%+&+*+=+p.-+;+{ ] ^ ~ ^ ^ ^ U >+,+'+)+!+~+{+]+^+ ", +" /+(+_+U N.:+O O O O <+[+O }+|+1+^ ~ [ 2+^ ^ 3+4+5+@ 6+7+8+9+0+a+b+c+ ", +" d+e+f+g+h+i+j+k+j+:+O O l+m+n+O o+p+q+M.r+s+t+u+v+y w+x+y+8+z+A+O O B+C+D+E+ ", +" d+u F+G+H+#+;.I+^ ] J+O K+L+M+N+O O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@O O @@#@$@%@&@ ", +" *@=@G+ B+-@;@] >@{ ,@'@)@O M+!@~@{@]@^@/@(@_@O y.:@<@[@}@|@[@Y+1@2@O O 3@4@5@6@ ", +" 7@ 8@9@0@a@b@c@d@O O O e@f@g@h@O i@j@O O O h@_ k@l@O m@n@Q.H o@p@O O O &+q@r@ ", +" s@t@ G+u@v@w@x@y@z@O O A@B@C@(+O O D@E@F@O O O G@H@I@r J@K@L@M@N@O@P@O O Q@R@S@T@ ", +" U@<+ V@W@X@Y@Z@:.`@ #.#+#@#O O O O Q.1 ##O O $#%#&#*#$+=#-#;#>#,#'#)#O O K+!#~#{# ", +" w+i.]# ^#/#(#_#:#<#[#}#|#O O O O O O q 1#O O O $#2#3#4#5#6#7#8#9#0#a#O O O b#c#d# ", +" e#f# e#>#g#h#O O O O O O O O O O y.i#j#O O O k#l#m#n#o#p#q#r#s#t#5.O O u#v#w#x# ", +" y#z# A#B#O O O O O O O O O O O O O y.C#O+O O O D#E#F#G#H#I#J#K#T+L#M#O O Y+N#4+O# ", +" P#Q# R#S#O O O O O O O O O O O O O T#/ #+O O O U#V#W#9+X#Y#Z#`# $.$+$#+@$.@#$$$ ", +" %$&$ *$=$O O -$8+;$O O O O O O O >$,$'$O O O O 8@i.)$!$~${$L i+]$^$/$: ($_$:$G+", +" <$[$U@ }$|$1$s+2$=.O O O O O O O O 3$4$Q@O O O 5$6$7${ 3$8$9$u+0$a$b$c$d$@.e$G+", +" f$g$h$i$ j$k$l$m$n$9#O O O O O O O O 5#o$p$)#O O O q$r$s$t$u$b+v$w$x$n Y@Y@y$z$A$", +" B$C$D$ E$F$G$H$I$9#O O O O O O O O O N J$K$L$M$N$O$P$Q$R$S$T$U$m D Y@D D Y@V$W$", +" X$Y$Z$ `$ % .%+%w+O O O O O O O O O O @%#%$%%%0$&%*%=%-%D Y@D Y@D Y@D D Y@;%4#", +" >%,%'%)% !%~%{% R@]% ^%/%S$[@O O O O O O O O D@(%_%&$:%d$Y@D D m y$<%C m D Y@Y@[%}%F$", +" |%1% 2%`$3%4%5%;@N 6%7%8%9%0%a%b%c%d%H+K#O O O O O O O O e% .f. .<%y$D m C @.f%@.C m D D U$g% ", +" [$h%i%j%k%l%O m%k#n%o%p%-@++q%0@:+r%h%s%t%u%O O O O O O O v%..:.f.g.m D y$B f%w%+.@.C x%y%z% ", +" A%B%C%l%$+D%E%F%G%H%H%I%J%K%L%M%N%;.y.O%<$P%5$O O O O +$Q%+.w%f%B y$D m g.f.:...R%S%T%G+ ", +" U%V%W%z.s#X%Y%Z%G+G+G+G+G+G+j$`% &.&+&3$N @&#&v#$&O O O %&&&@.f%@.C m D y$<%*&=&}$-& ", +" ;&>&,&'&)&!&Q ~&{&]&G+ ^&/&(&_&:&<&[&:+D@}&G+|&1&z.O 2&3&C <%y$m D 4&5&6&7&8& ", +" 9&0&a&b&c&d&e&f&g&h&Z%i&a+j&k&l&>+m&n&>%P%L%O o&G+ G+^#p&h%{.Y@D q&r&6&s&G+ ", +" t&u&v&w&x&y&z&A&B&C&D&E&8 F&G&H&I&y.-.3$J&b#O K&G+ L&M&N&O&P&Q&G+ ", +"n$R&S&T&U&u#V&]@W&X&;.+$Y&Z&`& *.*+*@*#*$*%*&*=#**G+ =*G+G+ ", +"-*;*>*,*'*)*!*-@~*{*]*^*/*(*_*H%M$:*<*U@[*#+}***G+ ", +" |*1*=$2*3*4*5*.$G+6*7*8*8&v#9*0*a*H+b*c*M@+$d*e* ", +" f*g*h*i* U+-#E#N j*G+G+ k*l*m*n* ", +" o*u%p*q*r*G+ s*t*u*v*G+ ", +" w*x*y*z*A*B*C* D*E*[*}$G+ ", +" L#F*G*H*I*J*p@K*L*M#M*N*O* ", +" b#P*(+Q*R*S*T*U*l+1.V*W* ", +" X*Y*Z*`* =.=X%+=@=G+ ", +" #=$=%=G+ "}; diff --git a/linphone/pixmaps/sip-away.png b/linphone/pixmaps/sip-away.png new file mode 100644 index 0000000000000000000000000000000000000000..ba7580faa3bf0f4761b7835e77cd089653bc64a7 GIT binary patch literal 1069 zcmV+|1k(G7P)P000>X0ssI2ON$aT00004XF*Lt007q5 z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#zez+vRCwBA zeE04h2M5RBzkk1e{rdCgPX-bJJ3Bi!H#ajg^N$}t00M{w$O4-3^5x49A3gy2q?!eE zhk$^9xVSjb9Do2~`St4;&>(ATYbPfspu7J6{|{Hk$jC^HyY}tdcl78{85tRX0Ac|; z3g{ve6B9>A$8X=h0bR=i27mti0a}A>G*-aH#q|LU1O){F0*D3Z7NFOFCVmAP#KiRF z%a{B2?*0Dr2WTNLFE3Cj8yg#bC-21F)?7IT)K1#D01oIMPMkXsjCAW4-7bB;sGFl5Pk&e0S1tLIwzfd`96fgI(W6I1rZs>7LYT$R&kqcs%a<=pOG^VI zPDNF9>-Ozy)~o>v-nw;*iHV7zaR32?;zvNIw z00yOkf&wtx0^|QbIQTG)1_&S)G`@(42rzR&)B!{4%9ShEuU`k6c;?KR$B&=r>S_Z+ zfQ6Ii|KGo$4EGNu(E$Vyx>^6g04m4AqNSw;Ob`zrKK%aU2R9Gb_cyODo;=3E#=*|U z%quF&Dx(0*(r~>10mOpG|3DwHva*_*ngWCG>-X=XEKJXL?=fIzm1SiGmH|H>KKk(X z45?0cwlk?y5jt$%h#@51DXId2OxkLfytNndI%T-jKGWuHW%nq nU~z<84*>)aBNgjMfB*vkqF&UoLs0sw00000NkvXXu0mjfm{{Xu literal 0 HcmV?d00001 diff --git a/linphone/pixmaps/sip-bifm.png b/linphone/pixmaps/sip-bifm.png new file mode 100644 index 0000000000000000000000000000000000000000..898a18a7ebebafddcf9d96cfe2269d0facaf63f5 GIT binary patch literal 1166 zcmV;91abR`P)P000>X1^@s6#OZ}&00004XF*Lt007q5 z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$AW1|)RCwBA z{Qv*|Jq88_fj@u#Fnsy)h2iJVpA3`&c6N3K9v&VB78Vu|_X9uxF#;|5^8WpM?w2oL zGJN>(f#JuG9~4`{!NI{GARxdXE-ua>C@A<9Ab?naKKKQ+fZN*In!(A*32X@?BO@5Y z0MH>M`()p~eGEsB9%bO=<^2T^KrEmj0{Oti#Du}Y!GYoL-@gp3tgH<0-o9n{2Q?hz zZ4gGb7$4x`;sToq!XWbj0*D0^2O!sf{rZ&w6fYq9=8YR*%Rp8L@bfb;F*AcT1HI0` z3}q7n-@bhVn+q}@Ab^;VC776)7_MKx&hYy6YX%NZPKKbsK(OnDfQE~Ui7~td`VJIy z_%OC01_&UyB_P9q2>=v^46JNy4D;vD2M62KY10@UK6=DpVrmNZm zz<@zmSeRk%ym<_Y3JMH5Iywx$e*FT=6B{SU03d)c;soT)m#PK3|K4$2p|@G z=;@)D1rR_i#6}({=s?AazP>)gZ(vZq0a_+|=@LVbuP=iPuyB2H>lQfPuHC-Pa1E#q zInV$Ch>4V>2=);$|8M}4I{$+Q48D?*3^KqtVFCJ@8<;?3fod#)!Sx3icgP_D5I`)X zrg=~V{{qH~3eX|}U?TYiENZxcMUHT3DFY+W0$yOkU^;Y&;UAJ7fB+)h5@4?X4-770 zU~$e2wB!dcc-~H&$iN89TWmmIeg)!hz!ZsGx&Z_b6Ujvc&?n!4F8%^6rMZBKffY#q z1eV^hPtsa!`*xL;CcW8hy|33L3sc~gK9Kl04U#ZTUs*g1sb#qSf+6R^UV)XW&{Qk z$O0)~k_KgJn7IG}!~!cKKP000>X1^@s6#OZ}&00004XF*Lt007q5 z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$JxN4CRCwBA z{Qv*|Jq88_fj@u#Fnsy)h2iJVpA3`&c6N3K9v&VB78Vu|_X9uxF#;|5^8WpM?w2oL zGJN>(f#JuG9~4`{!NI{GARxdXE-ua>C@A<9Ab?naKKKQ+fLmKzn?XZEgW=b&Ukr?l zj1*bI%F4=cfw@bdEh0tg@$P!NH9AT2G;kd>9i@b~Xuu%dTw-!lCB{~xRg zSeu8QFMWEyk ziW_19Kmegw0&*oNr{1`E6KpUDfRf?eyLZ9q9aLPLKYt!vWPsFxEW(wdkO4pdp;!Xa z0J2Cnerpdbci+`qs?!GOh5 zfB<5_SN^~N$mJmZ(W6HhK7ING4#GdcL?8-G9N$2B2j~!xL4ScXBQU5z2?QAc1Q1S3 zkb?mfETG`Av9SRMmo6}F++3UcXlgQ;K6t>83iO4js3?P^q$Gn2FlD9#eRvsIUOfg{hHMEy05Or06hS^> z2NpM1fv%opWyRnDw8-M=QwA}huabd5xmHVy;RUexxdJTvkO4pdv5=bPe*+^I6i4rY z@i7Zn+J*uRX9ot`8ldlX$;dEp0#hTX6bAVLR{Q`25DPhV1xPbHFcmTZlQbu=B;Wwz zpTKerR4RbvVQOHO00a=pmaqZq6;KLO0mf0{u3Zc(fIhegjE_!WzWM-6T}Oct|NZ-S z2IL|XAb_yO3CtDPFcT0P1A`-R-#&)@zzE+eBEoPVm{+C%^G(W~I}F0lo-r5$OKjv6 z3J^dnpj-^f1E87@6qbYlNaG(vLxyIc!8d?)4>PcO0O{QhEax@@t8h?KR{>fK%ETaZ zLFNMl5F;?fyt{Mfjv%Ox2bH{_q)H5cS5z?HBc~>yrSIOoW4LnV3WKVu>U)3yBCE9m z%F&>D1>_)5$qg&L!BsZUVo->H94sXz1#YbX1P~)V+Fbwv1^|HP=7K_~Y_tFX002ov JPDHLkV1kl^?-~FA literal 0 HcmV?d00001 diff --git a/linphone/pixmaps/sip-closed.png b/linphone/pixmaps/sip-closed.png new file mode 100644 index 0000000000000000000000000000000000000000..6bbe08352bf3f7df7d08ccc131784d3bb40960b9 GIT binary patch literal 1234 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 literal 0 HcmV?d00001 diff --git a/linphone/pixmaps/sip-wfa.png b/linphone/pixmaps/sip-wfa.png new file mode 100644 index 0000000000000000000000000000000000000000..d6fe73b4f3b01d4bef078abf1a699fb1d66dfbb3 GIT binary patch literal 1259 zcmVP000>X1^@s6#OZ}&00004XF*Lt007q5 z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$eMv+?RCwBA z{Qv*|Jq88_fj@u#Fnsy)h2iJVpA3`&c6N3K9v&VB78Vu|_X9uxF#;|5^8WpM?w2oL zGJN>(f#JuG9~4`{!NI{GARxdXE-ua>C@A<9Ab?naKKKQ+fLmKzn?XZEgW=b&Ukr?l zj1*bI%F4=cfw@bdEh0tg@$P!NH9AT2G;kd>9i@b~Xuu%dTw-!lCB{~xRg z?&~R}vF^0E5-vQ$g1sk3{%WzXwm4OFnS;*?u4C27JMF#)@gklLW0f54g zft8JoVgCI2;9#3NZ5qSFM~@gxOijVQ{QdhkO0XSpa9~&&9?o#e+#Jl;06G#K00a;V zGUwa3Z(vs|$jdWGN=Se$Nl!~-P*+!H-~}d0P!NKGlnv+zjCcU*1%c0ed>C>70fb`7 zzkmN2IDv*48W=DL3kx&Moi~p`Q9*%0M@I)7#vpn0H~|46UB;aH7>_K#-2D$&Dlh?kiw*z+2&X0gkz51{7Etim*w`>!00z%jU~)A8 zmUR~{U1HDy`uM((5I9&rfBwv%2aGQcJv|h&00M}G*g_8!bf98IUtgc$D=>cE0$mOY zGA3X=r~*?ZD0tt$d&h9&=~D)#$B$9;0t65XDWxmON9@4j=D~vp403XE3}V3G;sHfA zFt|W++`xhn1TI{;!hjqz00G28YBBx`Xc(xJ1?3@rAkNCkVfZX6%CHJp>Vh&WD9Awa z$d&*E5ED6d1vtK-1tfAt24PTY1ZQd_JpchjvQOB6DF~FpKuH;t;wA%&c}`%Ye+Bvg z?tsuFOvWO002ovPDHLkV1h)80V4na literal 0 HcmV?d00001 diff --git a/linphone/po/.cvsignore b/linphone/po/.cvsignore new file mode 100644 index 000000000..56888d9d5 --- /dev/null +++ b/linphone/po/.cvsignore @@ -0,0 +1,6 @@ +.intltool-merge-cache +Makefile +Makefile.in +POTFILES +*.gmo +stamp-* diff --git a/linphone/po/ChangeLog b/linphone/po/ChangeLog new file mode 100644 index 000000000..63269d9a1 --- /dev/null +++ b/linphone/po/ChangeLog @@ -0,0 +1,97 @@ +2007-01-17 gettextize + + * Makefile.in.in: Upgrade to gettext-0.16.1. + * cat-id-tbl.c: Remove file. + +2006-07-20 gettextize + + * Makefile.in.in: Upgrade to gettext-0.14.6. + * boldquot.sed: New file, from gettext-0.14.6. + * en@boldquot.header: New file, from gettext-0.14.6. + * en@quot.header: New file, from gettext-0.14.6. + * insert-header.sin: New file, from gettext-0.14.6. + * quot.sed: New file, from gettext-0.14.6. + * remove-potcdate.sin: New file, from gettext-0.14.6. + * Rules-quot: New file, from gettext-0.14.6. + * cat-id-tbl.c: Remove file. + +2002-10-15 gettextize + + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-10-08 gettextize + + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-10-08 gettextize + + * boldquot.sed: New file, from gettext-0.11.5. + * en@boldquot.header: New file, from gettext-0.11.5. + * en@quot.header: New file, from gettext-0.11.5. + * insert-header.sin: New file, from gettext-0.11.5. + * quot.sed: New file, from gettext-0.11.5. + * remove-potcdate.sin: New file, from gettext-0.11.5. + * Rules-quot: New file, from gettext-0.11.5. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-10-04 gettextize + + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-10-04 gettextize + + * Makefile.in.in: Upgrade to gettext-0.11.5. + +2002-10-04 gettextize + + * Makefile.in.in: New file, from gettext-0.11.5. + +2002-10-01 gettextize + + * Makefile.in.in: Upgrade to gettext-0.11.5. + * boldquot.sed: New file, from gettext-0.11.5. + * en@boldquot.header: New file, from gettext-0.11.5. + * en@quot.header: New file, from gettext-0.11.5. + * insert-header.sin: New file, from gettext-0.11.5. + * quot.sed: New file, from gettext-0.11.5. + * remove-potcdate.sin: New file, from gettext-0.11.5. + * Rules-quot: New file, from gettext-0.11.5. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-08-04 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + +2002-08-04 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-07-16 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-02-16 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + +2002-02-10 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + +2002-02-10 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + * cat-id-tbl.c: Remove file. + * stamp-cat-id: Remove file. + diff --git a/linphone/po/Makefile.in.in b/linphone/po/Makefile.in.in new file mode 100644 index 000000000..5022b8b18 --- /dev/null +++ b/linphone/po/Makefile.in.in @@ -0,0 +1,403 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2006 by Ulrich Drepper +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.16 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = @MSGFMT@ +MSGFMT_no = @MSGFMT@ +MSGFMT_yes = @MSGFMT_015@ +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +# Makevars gets inserted here. (Don't remove this line!) + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: all-@USE_NLS@ + +all-yes: stamp-po +all-no: + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + $(mkdir_p) $(DESTDIR)$(datadir) + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + $(mkdir_p) $(DESTDIR)$(datadir) + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && $(SHELL) ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/linphone/po/Makevars b/linphone/po/Makevars new file mode 100644 index 000000000..32692ab4b --- /dev/null +++ b/linphone/po/Makevars @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Free Software Foundation, Inc. + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/linphone/po/Makevars.template b/linphone/po/Makevars.template new file mode 100644 index 000000000..32692ab4b --- /dev/null +++ b/linphone/po/Makevars.template @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Free Software Foundation, Inc. + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/linphone/po/POTFILES.in b/linphone/po/POTFILES.in new file mode 100644 index 000000000..1cbaf3490 --- /dev/null +++ b/linphone/po/POTFILES.in @@ -0,0 +1,18 @@ +# List of source files containing translatable strings. + +gtk/main.c +gtk/interface.c +gtk/callbacks.c +gtk/support.c +gtk/propertybox.c +gtk/gui_utils.c +gtk/linphone.c +gtk/presence.c +gtk/friends.c +gtk/addressbook.c + +coreapi/linphonecore.c +coreapi/misc.c +coreapi/exevents.c +coreapi/presence.c + diff --git a/linphone/po/Rules-quot b/linphone/po/Rules-quot new file mode 100644 index 000000000..9c2a995e3 --- /dev/null +++ b/linphone/po/Rules-quot @@ -0,0 +1,47 @@ +# Special Makefile rules for English message catalogs with quotation marks. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/linphone/po/boldquot.sed b/linphone/po/boldquot.sed new file mode 100644 index 000000000..4b937aa51 --- /dev/null +++ b/linphone/po/boldquot.sed @@ -0,0 +1,10 @@ +s/"\([^"]*\)"/“\1â€/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“â€/""/g +s/“/“/g +s/â€/â€/g +s/‘/‘/g +s/’/’/g diff --git a/linphone/po/cat-id-tbl.c b/linphone/po/cat-id-tbl.c new file mode 100644 index 000000000..e69de29bb diff --git a/linphone/po/cs.po b/linphone/po/cs.po new file mode 100644 index 000000000..a389ae6cb --- /dev/null +++ b/linphone/po/cs.po @@ -0,0 +1,1049 @@ +# translation of linphone.po to cs_CZ +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Klara Cihlarova , 2005. +# Petr Pisar , 2006, 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: linphone-2.0.0\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2007-11-21 17:50+0100\n" +"Last-Translator: Petr Pisar \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "Volný SIP videofon" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Soubor" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Adresář" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Historie volání" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Zobrazit volání" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "UkonÄit" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "NápovÄ›da" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "Zde zadejte SIP adresu nebo telefonní Äíslo" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "SIP adresa:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Zobrazit adresář" + +#: gtk/interface.c:261 +msgid "..." +msgstr "…" + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Proxy:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Volat nebo\n" +"pÅ™ijmout" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"ZavÄ›sit nebo\n" +"odmítnout" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Nebo poslat zprávu!" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Zobrazit více…" + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Úroveň pÅ™ehrávání:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Úroveň nahrávání:" + +#: gtk/interface.c:354 +msgid "Ring level:" +msgstr "Úroveň vyzvánÄ›ní:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Zvuk" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "Povolit obraz" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "Obraz" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "Ovládání" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Dosažitelný" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Mám práci, jsem zpÄ›t za " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "Druhá strana bude informována, že se vrátíte za X minut" + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "PryÄ" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "NeruÅ¡it" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "DoÄasnÄ› mimo" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Alternativní služba" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Přítomnost" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Zadejte Äísla pro zaslání DTMF." + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" +" 3\n" +"def" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" +" 2\n" +"abc" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" +" 4\n" +"ghi" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" +" 5\n" +"jkl" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" +" 6\n" +"mno" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" +" 7\n" +"pqrs" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" +" 8\n" +"tuv" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" +" 9\n" +"wxyz" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Přátelé online" + +#: gtk/interface.c:849 gtk/interface.c:3029 +msgid "Linphone" +msgstr "Linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"© 2001\n" +"Vyrobeno ve Staré Dobré EvropÄ›" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone je program pro IP telefonii.\n" +"Je kompatibilní s protokoly SIP a RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "http://www.linphone.org/" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parametry" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "Použít IPv6 síť (je-li dostupná)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Jestliže jste v síti podporující IPv6 protokol a chcete-li, aby jej linphone " +"používal, zapnÄ›te tuto volbu." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "Obecné" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Tato volba je urÄena pouze pro uživatele v intranetu za firewallem. Pokud to " +"není váš případ, nevyplňujte." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "Bez firewallu" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "Pro odhad veÅ™ejné adresy použít tento STUN server:" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "VeÅ™ejná adresa firewallu:" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "Volby průchodu NATem (experimentální)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Velikosti vyrovnávací fronty v milisekundách (potlaÄení rozptylu):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "RTP port pro zvuk:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP vlastnosti" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "Místo RTP rfc2833 použít pro DTMF pÅ™enos SIP INFO zprávu" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "DoporuÄeno je RTP-RFC2833." + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Ostatní" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Síť" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Zvukové zařízení pro pÅ™ehrávání:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "mikrofon" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "line" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "Zvukové zařízení pro nahrávání:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Zdroj nahrávání:" + +#: gtk/interface.c:1277 +msgid "Ring sound device" +msgstr "Zvukové zařízení pro vyzvánÄ›ní:" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "ZvonÄ›ní:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "PotlaÄit ozvÄ›nu (projeví se na druhém konci)" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "Vyberte soubor" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Test" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Vlastnosti zvuku" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Zvukové zařízení" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Spustit uživatelského agenta SIP na portu:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Je doporuÄeno používat port 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP port" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "VaÅ¡e SIP adresa:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Automaticky uhodnout platné jméno" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identita" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "PÅ™idat proxy/registraci" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Upravit" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Odstranit" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Vzdálené služby" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "Vyprázdnit vÅ¡echny ověřovací informace (uživatelské jméno, heslo…)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Ověřovací informace" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Seznam audio kodeků podle preference:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Kodeky zvuku" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "Kodeky obrazu" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Povolit" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Zakázat" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "Odchozí šířka pásma (kb/s):" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "Příchozí šířka pásma (kb/s):" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Poznámka: Kodeky oznaÄené ÄervenÄ› nelze u vaÅ¡eho typu pÅ™ipojení použít." + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Nejsou dostupné žádné informace" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Informace o kodeku" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "Kodeky zvuku a obrazu" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Kodeky" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Adresář" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Vybrat" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informace" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Uživatel je momentálnÄ› nedostupný, ale navrhuje tyto alternativní formy " +"kontaktu:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Žádné." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Konfigurace proxy a registrace" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "SmÄ›rování (volitelné):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "SIP proxy:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "SIP identita:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "RegistraÄní období:" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Odeslat registraci:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "ZveÅ™ejnit svůj stav:" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Upravit kontaktní informace" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Jméno:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Pravidlo pÅ™ihlášení:" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Odeslat pÅ™ihlášení (podle online stavu osoby)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Informace o kontaktu" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Nové příchozí pÅ™ihlášení" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "Obdrželi jste nové pÅ™ihlášení…" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Odmítnout" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "PÅ™ijmout" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Žádost o ověření" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "pro doménu je vyžadováno ověření" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "ID uživatele:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "heslo:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "uživatelské jméno:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "doména:" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone – historie volání" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Diskuzní skupina" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Text:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Diskuze s %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Nelze najít soubor s obrázkem: %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "ÚÄet" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Povoleno" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Zakázáno" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Jméno" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Rychlost (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Stav" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Min. rychlost (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "Neomezená" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "Volající žádá o rezervaci zdrojů. Souhlasíte?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"Volající nepoužívá rezervaci zdrojů. \t\t\t\t\tChcete pÅ™esto pokraÄovat?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "linphone – příchozí hovor z %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"Obdrželi jste pÅ™ihlášení od %s. Znamená to, že si tato osoba pÅ™eje být " +"informována o vaÅ¡em stavu přítomnosti (online, zaneprázdnÄ›n, pryÄ…).\n" +"Souhlasíte?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Pro doménu %s je vyžadováno ověření" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Žádná" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Stav" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "Zdržet" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "Odmítnout" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "Å patnÄ› zadaná SIP adresa: SIP adresa má tvar sip:uživatel@doména" + +#: gtk/addressbook.c:226 +msgid "Contact list" +msgstr "Seznam kontaktů" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "ZameÅ¡kané hovory: %i" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "pÅ™eruÅ¡en" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "dokonÄen" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "promeÅ¡kán" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s v %s\n" +"Od: %s\n" +"Pro: %s\n" +"Stav: %s\n" +"Trvání: %i min %i s\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Příchozí hovor" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Odchozí hovor" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Zdá se, že váš poÄítaÄ je pÅ™ipojen do IPv6 sítÄ›. StandardnÄ› linphone používá " +"pouze IPv4. Prosím, povedtÄ› zmÄ›ny v konfiguraci programu, pokud chcete " +"používat IPv6." + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "PÅ™ipraven." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "Hledá se adresa pomocí STUN…" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "STUN vyhledávání dokonÄeno…" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Vyhledává se umístÄ›ní Äísla…" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Toto Äíslo nelze vyhledat." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Å patnÄ› zadaná SIP adresa. Adresa má mít tento formát " + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "Promiňte, vedení více souÄasných hovorů není podporováno!" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "Kontaktuji" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "Nelze volat." + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "PÅ™ipojeno." + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "Hovor skonÄil." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "Žádná adresa NATu/firewallu nebyla zadána!" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "Neplatná adresa NATu '%s': '%s" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Váš poÄítaÄ používá zvukový ovladaÄ ALSA. Jde o nejlepší\n" +"volbu. Linphone vÅ¡ak potÅ™ebuje ke své práci modul emulace\n" +"oss, který chybí. Prosím zadejte jako uživatel root příkaz\n" +"'modprobe snd-pcm-oss', kterým modul zavede." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Váš poÄítaÄ používá zvukový ovladaÄ ALSA. Jde o nejlepší\n" +"volbu. Linphone vÅ¡ak potÅ™ebuje ke své práci modul mixer emulace\n" +"oss, který chybí. Prosím zadejte jako uživatel root příkaz\n" +"'modprobe snd-mixer-oss', kterým modul zavede." + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "Hovor ukonÄen." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Cíl je nedostupný." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Uživatel je zaneprázdnÄ›n." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Uživatel je doÄasnÄ› nedostupný." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Dotaz pÅ™eruÅ¡en." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "Uživatel si nepÅ™eje být ruÅ¡en." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Volání odmítnuto." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Chybný dotaz" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Uživatele nelze na dané adrese zastihnout." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Vzdálený uživatel nemá podporu pro žádný z navržených kodeků." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "VyprÅ¡ení Äasového limitu." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Vzdálený poÄítaÄ byl nalezen, ale odmítl pÅ™ipojení." + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "vás volá." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "PÅ™esmÄ›rováno na %s…" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Uživatel je nedostupný, ale navrhuje tyto alternativní\n" +"setkání:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "ÄŒasná média." + +#: coreapi/exevents.c:837 +#, c-format +msgid "Registration on %s failed: %s" +msgstr "Registrace na %s selhala: %s" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "odpovÄ›Ä nedorazila vÄas" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "Registrace na %s byla úspěšná." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "PryÄ" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "ÄŒekám na schválení" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "Online" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "ZaneprázdnÄ›n" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "Na chvíli pryÄ" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "Na příjmu" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "Na obÄ›dÄ›" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "ZavÅ™eno" + +#~ msgid "enter sip uri here" +#~ msgstr "Sem zadejte SIP URI" + +#~ msgid "User manual" +#~ msgstr "Uživatelská příruÄka" + +#~ msgid "Ring sound selection" +#~ msgstr "VýbÄ›r zvonÄ›ní" + +#~ msgid "Communication ended." +#~ msgstr "Komunikace ukonÄena." + +#~ msgid "Call cancelled." +#~ msgstr "Volání pÅ™eruÅ¡eno." + +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "VnÄ›jší IP adresa firewallu (v teÄkové notaci):" + +#~ msgid "Index" +#~ msgstr "Rejstřík" + +#~ msgid "Address" +#~ msgstr "Adresa" + +#~ msgid "28k modem" +#~ msgstr "28k modem" + +#~ msgid "56k modem" +#~ msgstr "56k modem" + +#~ msgid "64k modem (numeris)" +#~ msgstr "64k modem" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL nebo kabelový modem" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet nebo podobný" + +#~ msgid "Connection type:" +#~ msgstr "Typ pÅ™ipojení:" + +#~ msgid "Server address" +#~ msgstr "Adresa serveru:" + +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone nemůže otevřít zvukové zařízení %s. PÅ™ekontrolujte nastavení a " +#~ "funkÄnost zvukové karty." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Zde zadejte SIP adresu osoby, které si pÅ™ejete volat." + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "PÅ™ijmout nebo\n" +#~ "odmítnout" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s. Zkusit znovu po %i min." diff --git a/linphone/po/de.po b/linphone/po/de.po new file mode 100644 index 000000000..ddb4cd508 --- /dev/null +++ b/linphone/po/de.po @@ -0,0 +1,1245 @@ +# SIP Telephony Application. +# Copyright (C) 2001, 2002 Free Software Foundation, Inc. +# Simon Morlat , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: linphone 0.7.1\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2003-05-23 17:51-0400\n" +"Last-Translator: Jean-Jacques Sarton , Ursula Herles-" +"Hartz \n" +"Language-Team: Deutsch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "Ein freies SIP Video-Fone" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Start" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Adressbuch" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Gesprächsverlauf" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Zeigt Gespräche" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "Beenden" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "Hilfe" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "Sip-Adresse oder Telefonnummer eingeben." + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Sip-Adresse:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Adressbuch" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Benutze Proxy-Server:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Anrufen oder\n" +"Entgegennehmen" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"Auflegen\n" +"oder Abweisen" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Oder Chat" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Mehr anzeigen" + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Abhörpegel" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Aufnamepegel" + +#: gtk/interface.c:354 +msgid "Ring level:" +msgstr "Klingelpegel" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Ton" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "Video einschalten" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "Video" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "Kontrolle" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Erreichbar" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Beschäftigt, wieder erreichbar in " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" +"Der Teilnehmer wird informiert, dass Sie in X Minuten wieder anwesend sind." + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "mn" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Abwesend" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Nicht stören" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Unterwegs" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Andere Dienste" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Anwesenheit" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Zifferntasten drücken, um DTMF zu senden" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "" + +#: gtk/interface.c:561 +msgid "0" +msgstr "" + +#: gtk/interface.c:567 +msgid "#" +msgstr "" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Meine online Freunde" + +#: gtk/interface.c:849 gtk/interface.c:3029 +msgid "Linphone" +msgstr "Linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"C: 2001\n" +"In Alt Europa erzeugt" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone ist ein web-phone.\n" +"Es ist mit den SIP- und RTP-Protokollen kompatibel." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parameter" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "IPv6 Netzwerk (falls vorhanden) verwenden" + +# msgstr "Teilnehmer zur Zeit nicht ansprechbar." +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Ankreuzen wenn Sie ein ipv6 Netz haben und wenn Sie es wünschen dass " +"linphone es verwendet" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Diese Option gilt nur für Anwender in einem privaten Netzwerk oder wenn der " +"Rechner durch einen Firewall geschützt ist. Andernfalls wird das Feld nicht " +"ausgefüllt" + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "Kein Firewall" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "Dieses STUN Server verwenden um die Firewalladresse zu Ermitteln" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "Firewall Adresse von Hand angeben" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "NAT-Transversaloptionen (experimentell)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Anzahl der gepufferten Pakete (Jitterausgleich):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "Sound RTP Port:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP-Eigenschaften" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "Benutze SIP INFO Nachricht statt RTP rfc2833 für DTMF Übertragung" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 wird empfohlen" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Andere" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Netzwerk" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Ton Wiedergabegerät:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "Mikrofon" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "Leitung" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "Audio Aufnahmegerät:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Aufnahmequelle:" + +#: gtk/interface.c:1277 +msgid "Ring sound device" +msgstr "Klingel Wiedergabegerät:" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "Klingelton:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" +"Echounterdrückung einschalten (eliminiert das von Gesprächspartnet gehörter " +"Echo)" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Anhören" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Audio Eigenschaften" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Audiogerät" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Sip \"user agent\" an Port:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Wir empfehlen, Port 5060 zu verwenden" + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP-Port" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Ihre Sip-Adresse:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Automatisch einen gültigen Hostnamen erraten" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identität" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Proxy/Registrator hinzufügen" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Bearbeiten" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Entfernen" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Dienste auf entferntem Server" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" +"Alle gespeicherten Authentifikationsinformationen löschen (Benutzername, " +"Passwort,...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Authentifikationsinformation" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Liste von Audio-CoDecs in der Reihenfolge ihrer Präferenz" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Eigenschaften des Audiocodecs" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "Videocodecs" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Freigeben" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Sperren" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "Upload-Bandbreite (kbit/sec):" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "Download-Bandbreite (kbit/sec):" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Notiz: Rot markierten Codecs können bei Ihrer Internetverbindungsart nicht " +"verwendet werden." + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Informationen nicht verfügbar" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Codec Information" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "Audio und Video Codecs" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Codecs" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Adressbuch" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Auswählen" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Information" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Teilnehmer nicht erreichbar. Bitte stattdessen nachstehende Ressource " +"verwenden:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Nichts." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Proxy/Registrator Konfigurationsbox" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Route (optional):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "SIP Proxy:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "SIP Identität" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Registrierungsdauer." + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Sende Registrierung:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Anwesenheit Information publzieren" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Bearbeite Kontaktinformationen" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Name:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Subskription Police" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Sende Subskription (zeige Onlinestatus der Person an)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Kontaktinformationen" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Neu ankommende Subskription" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "Sie haben eine neue Subskription empfangen" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Ablehnen" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Annehmen" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Authentifikation erfordert" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "Authentifikation erforderlich für Bereich" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "Benutzer ID:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "Passwort" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "Benutzername:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "Bereich:" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - Gesprächsverlauf" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Chat Raum" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Text" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Chat mit %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Pixmapdatei %s nicht gefunden" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "Konto" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Freigegeben" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Gesperrt" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Name" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Rate (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Status" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Min Bitrate (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "Unbegrenzt" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "Der Anrufer erbittet Resourcenreservierung. Sind Sie einverstanden?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"Der Anrufer benutzt keine Resourcenreservierung. \t\t\t\t\tWollen Sie " +"dennoch fortfahren?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "Linphone- empfängt ein Anruf von %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"Sie haben eine Subskription von %s empfangen. Das heißt, dass diese Person " +"ber Ihre Anwesenheitsinformation benachrichtigt werden will (erreichbar, " +"beschäftig, abwesend...).\n" +"Sind Sie einverstanden ?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Authentifikation erforderlich für Bereich %s" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Keinen" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Anwesenheitsstatus" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "Warten" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "Abweisen" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"Fehlerhafte Sip-Adresse. Eine Sip-Adresse hat folgenden Aufbau " + +#: gtk/addressbook.c:226 +msgid "Contact list" +msgstr "Kontaktliste" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "Sie haben %i Anruf(e) in Abwesenheit." + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "abgebrochen" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "beendet" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "verpasst" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s am %sVon: %s\n" +"An: %s\n" +"Status: %s\n" +"Dauer: %i mn %i sec\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Eingehendes Gespr�h" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Abgehendes Gespräch" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Ihr Rechner scheint an einen IPv6 Netz angeschlossen zu sein. " +"Linphoneverwendet normalerweise IPv4. Bitte Konfiguration anpassen wenn sie " +"IPv6 verwenden wollen" + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "Bereit" + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "Stun Ermittlung läuft..." + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "Stun Ermittlung beendet..." + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Suche Telefonnummernziel.." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Konnte dies Nummer nicht auflösen." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Sip-Adresse kann nicht bestimmt werden. Eine Sip-Adresse hat folgenden " +"Aufbau " + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "Mehrfachen gleichzeitigen Anrufen nicht unterstützt !" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "Rufe an" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "Konnte kein Anruf vornehmen" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Verbunden." + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "Anruf beendet" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "Keine Nat/Firewall Adresse vorgegeben !" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "Ungültige NAT Adresse '%s' : '%s'" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Ihre Rechner verwendet anscheinend einen ALSA-Soundtreiber.\n" +"Dies ist die beste Lösung; allerdings ist die von Linphone benötigte pcm OSS " +"Emulation\n" +"nicht vorhanden. Für die Einbindung des Moduls\n" +"bitte den Befehl 'modprobe snd-pcm-oss' als Anwender-Root verwenden." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Ihre Rechner verwendet anscheinend einen ALSA-Soundtreiber.\n" +"Dies ist die beste Lösung; allerdings ist die von Linphone benötigte pcm OSS " +"Emulation\n" +"nicht vorhanden. Fr die Einbindung des Moduls\n" +"bitte den Befehl 'modprobe snd-pcm-oss' als Anwender-Root verwenden." + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "Anruf beendet" + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Konnte Ziel nicht erreichen" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Besetzt." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Teilnehmer zur Zeit nicht ansprechbar." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Anruf annulliert." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "Teilnehmer möchte nicht gestört werden." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Anruf abgewiesen" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Fehlerhafte Anfrage" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Teilnehmer ist unter der angegebene Adresse nicht erreichbar." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Die Gegenstelle untersttzt die angebotenen Codecs nicht." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Zeitberschreitung." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Die Gegenstelle hat die Verbindung abgewiesen." + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "ruft Sie an" + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Nach %s umgeleitet..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Teilnehmer nicht erreichbar. Bitte versuchen Sie es unter nachstehender " +"Ressource:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Registrierung auf %s schlug fehl (Zeitberschreitung)." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "Registrierung auf %s erfolgreich." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "Gegangen" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "Warte aud Bestätigung" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "Verbunden" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "Besetzt" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "Bald wieder da" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "Am Höhrer" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "Beim Essen" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "enter sip uri here" +#~ msgstr "Sip URI eingeben" + +#~ msgid "User manual" +#~ msgstr "Anwender-Handbuch" + +#~ msgid "Ring sound selection" +#~ msgstr "Klingelton ausw�len" + +#~ msgid "Communication ended." +#~ msgstr "Kommunikation beendet." + +#~ msgid "Call cancelled." +#~ msgstr "Anruf annulliert" + +#, fuzzy +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "IP-Adresse des Firewall (in Punktnotation)" + +#~ msgid "Address" +#~ msgstr "Adresse" + +#, fuzzy +#~ msgid "Server address" +#~ msgstr "Server-Adresse:" + +#~ msgid "28k modem" +#~ msgstr "28K Modem" + +#~ msgid "56k modem" +#~ msgstr "56K Modem" + +#~ msgid "64k modem (numeris)" +#~ msgstr "64K Modem (ISDN)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL oder Kabel-Modem" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet oder äquivalent" + +#~ msgid "Connection type:" +#~ msgstr "Verbindungstyp:" + +#, fuzzy +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone kann das Soundgerät nicht öffnen. Prfen Sie nach, ob die " +#~ "Soundkarte vollst�dig konfiguriert und funktionsfähig ist." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "" +#~ "Geben Sie die Sip-Adresse des Anwenders, den Sie anrufen möchten, hier " +#~ "ein." + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "Auflegen oder\n" +#~ "Abweisen" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s. In %i Minuten wieder versuchen." + +#~ msgid "Timeout..." +#~ msgstr "Zeitüberschreitung..." + +#~ msgid "Connection" +#~ msgstr "Verbindung" + +#, fuzzy +#~ msgid "" +#~ "Add address\n" +#~ "book" +#~ msgstr "Adressbuch" + +#~ msgid "Toggle this if you want to be registered on a remote server." +#~ msgstr "" +#~ "Bitte ankreuzen, wenn Sie auf einem Sip-Server registriert werden wollen." + +#~ msgid "Address of record:" +#~ msgstr "Adresse des Eintrags:" + +#~ msgid "" +#~ "The password used for registration. On some servers it is not necessary" +#~ msgstr "" +#~ "Passwort für die Registrierung. Bei manchen Servern nicht erforderlich." + +#~ msgid "Use this registrar server as outbound proxy." +#~ msgstr "Verwenden Sie diesen Registrarserver als externen proxy." + +#~ msgid "sip address:" +#~ msgstr "SIP-Adresse:" + +#~ msgid "Display name:" +#~ msgstr "Angezeigter Name:" + +#~ msgid "Modify" +#~ msgstr "Ändern" + +#~ msgid "Registering..." +#~ msgstr "Registrierung" + +#~ msgid "" +#~ "You are currently using the i810_audio driver.\n" +#~ "This driver is buggy and so does not work with Linphone.\n" +#~ "We suggest that you replace it by its equivalent ALSA driver,\n" +#~ "either with packages from your distribution, or by downloading\n" +#~ "ALSA drivers at http://www.alsa-project.org." +#~ msgstr "" +#~ "Sie verwenden zur Zeit den i810_audio Treiber.\n" +#~ "Diese Treiber ist fehlerhaft und funktioniert nicht mit Linphone\n" +#~ "Wir empfehlen, den Treiber entweder durch das ALSA-Treiber-Paket von " +#~ "ihrer Distribution\n" +#~ "zu ersetzen oder die gewnschten ALSA-Treiber von http://www.alsa-project." +#~ "org\n" +#~ "zu beziehen und zu installieren" + +#~ msgid "Unregistration successfull." +#~ msgstr "Abmeldung erfolgreich." + +#~ msgid "Select network interface to use:" +#~ msgstr "Netzwerkschnittstelle wählen:" + +#~ msgid "Network interface properties" +#~ msgstr "Eigenschaften der Netzwerkschnittstelle" + +#~ msgid "RTP" +#~ msgstr "RTP" + +#~ msgid "Audio" +#~ msgstr "Audio" + +#~ msgid "C: 2001" +#~ msgstr "April 2001" + +#~ msgid "Add" +#~ msgstr "Hinzufgen" + +#~ msgid "Threads not supported by glib. Upgrade your glib.\n" +#~ msgstr "" +#~ "Threads werden von glib nicht unterstützt. Bitte aktualisieren Sie Ihre " +#~ "glib.\n" + +#~ msgid "Run linphone as a gnome-applet." +#~ msgstr "Linphone als gnome-Applet ausfhren." + +#~ msgid "Run linphone as a daemon (for use without gnome)." +#~ msgstr "Linphone als daemon ausführen (Verwendung ohne Gnome)." + +#~ msgid "" +#~ "Cannot find network previously used interface %s.\n" +#~ "If your computer is temporary connected to the internet, please connect " +#~ "and then run linphone.\n" +#~ "If you want to change your default network interface, go to the " +#~ "parameters 'box." +#~ msgstr "" +#~ "Linphone konnte die zuvor verwendete Netzwerkschnittstelle %s nicht " +#~ "finden.\n" +#~ "Wenn linphone nur temporär am Internet angeschlossen ist, stellen Sie " +#~ "eine Verbindung her und rufen Sie linphone erneut auf.\n" +#~ "Wenn Sie die vorgegebene Netzwerkschnittstelle ändern wollen, wählen Sie " +#~ "bitte \"Einstellungen\"." + +#~ msgid "" +#~ "Linphone cannot open the audio device.\n" +#~ "It may be caused by other programs using it.\n" +#~ "Do you want linphone to kill these programs (esd or artsd) ?" +#~ msgstr "" +#~ "Linphone kann die Soundschnittstelle nicht öffnen.\n" +#~ "Dies kann durch andere Applikationen verursacht sein.\n" +#~ "Möchten sie diese Programme (esd oder artsd) beenden?" + +#~ msgid "label37" +#~ msgstr "label37" + +#~ msgid "Use it as a:" +#~ msgstr "Verwenden als:" + +#~ msgid "Redirect server" +#~ msgstr "Umleitungs-Server" + +#~ msgid "Outbound proxy" +#~ msgstr "Ausgehender Proxy-Server" + +#~ msgid "" +#~ "Toggle this button if the registrar must be used to proxy calls through a " +#~ "firewall." +#~ msgstr "" +#~ "Verwenden Sie diesen Knopf, falls der Registrar zum Tunneln durch einen " +#~ "Firewall verwendet werden muß" + +#~ msgid "kbit/s" +#~ msgstr "Kbits/s" + +#~ msgid "OSS" +#~ msgstr "OSS" + +#~ msgid "ALSA" +#~ msgstr "ALSA" + +#~ msgid "Automatically kill applications using soundcard when needed" +#~ msgstr "Applikationen die die Soundkarte verwenden, automatisch beenden." + +#~ msgid "" +#~ "Your computer is connected to several networks. Check in the global " +#~ "parameters if Linphone uses the one that you want." +#~ msgstr "" +#~ "Ihr Rechner ist an mehere Netze angeschlossen. Stellen Sie sicher, daß in " +#~ "den Globalen Parametern die richtige Schnittstelle selektiert ist." + +#~ msgid "" +#~ "Linphone failed to open the sound device. See the README file included in " +#~ "the distribution for details." +#~ msgstr "" +#~ "Linphone konnte die Soundschnittstelle nicht öffnen. Weitere " +#~ "Informationen finden Sie in der README-Datei (enthalten in der " +#~ "Distribution)." + +#~ msgid "Interface not found." +#~ msgstr "Schnittstelle nicht gefunden." + +#~ msgid "Warning" +#~ msgstr "Warnung" + +#~ msgid "" +#~ "Linphone cannot open the sound device. It may be caused by other programs " +#~ "using it. Do you want linphone to kill these programs (esd or artsd) ?" +#~ msgstr "" +#~ "Linphone kann die Soundschnittstelle nicht öffnen. Dies kann durch andere " +#~ "Applikationen verursacht sein. Möchten sie diese Programme (esd oder " +#~ "artsd) beenden?" + +#~ msgid "Linphone shutdowns" +#~ msgstr "Linphone Ende" + +#~ msgid "Linphone shutdowns..." +#~ msgstr "Linphone Ende..." + +#~ msgid "" +#~ "Please, wait a few seconds untils linphone unregisters your sip addess " +#~ "from registrar server..." +#~ msgstr "Bitte einige Sekunden warten, bis Sip-Adresse ausgetragen ist." + +#~ msgid "Bad formuled sip address." +#~ msgstr "SIP-Adresse fehlerhaft." + +#~ msgid "Couldn't create pixmap from file: %s" +#~ msgstr "Konnte Pixmap nicht aus Datei %s erzeugen." + +#~ msgid "" +#~ "Linphone did not detect any valid network interface. If you use a " +#~ "temporary internet connection, please connect and then run linphone again." +#~ msgstr "" +#~ "Linphone konnte keine Netzwerkschnittstelle finden. Wenn Sie nur eine " +#~ "temporäre Internetverbindung haben, bitte erneut eine Internetverbindung " +#~ "herstellen und linphone nochmals starten." + +#~ msgid "List of network interfaces on your system." +#~ msgstr "Vorhandene Netzwerkschnittstellen ihres Systems" diff --git a/linphone/po/en@boldquot.header b/linphone/po/en@boldquot.header new file mode 100644 index 000000000..fedb6a06d --- /dev/null +++ b/linphone/po/en@boldquot.header @@ -0,0 +1,25 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/linphone/po/en@quot.header b/linphone/po/en@quot.header new file mode 100644 index 000000000..a9647fc35 --- /dev/null +++ b/linphone/po/en@quot.header @@ -0,0 +1,22 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/linphone/po/es.po b/linphone/po/es.po new file mode 100644 index 000000000..eefea265a --- /dev/null +++ b/linphone/po/es.po @@ -0,0 +1,1283 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Linphone 0.9.1\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2002-10-15 HO:MI+ZONE\n" +"Last-Translator: Nelson Benitez \n" +"Language-Team: es \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Agenda" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +#, fuzzy +msgid "Enter sip address or phone number here" +msgstr "La direccion SIP del servidor de registro." + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "SIP:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Direccion SIP" + +#: gtk/interface.c:247 +#, fuzzy +msgid "Shows the address book" +msgstr "Muestra la Agenda" + +#: gtk/interface.c:261 +msgid "..." +msgstr "" + +#: gtk/interface.c:269 gtk/interface.c:2519 +#, fuzzy +msgid "Proxy to use:" +msgstr "Servidor Proxy" + +#: gtk/interface.c:278 +#, fuzzy +msgid "" +"Call or\n" +"answer" +msgstr "" +"Llamar o\n" +"Responder" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Mostrar mas..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Nivel de reproduccion:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Nivel de Grabacion:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Nivel de Grabacion:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Sonido" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "Activado" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Disponible" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Ocupado, estare de vuelta en " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "Se le comunicara a la otra persona que estaras de vuelta en X minutos" + +#: gtk/interface.c:431 +msgid "5" +msgstr "10" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Ausente" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "No molestar" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Vengo enseguida" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Servicio alternativo" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Estado" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Pulsa los digitos para mandar DTMFs." + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone es un telefono para Internet.\n" +"Es compatible con los protocolos SIP y RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parametros" + +#: gtk/interface.c:1061 +#, fuzzy +msgid "Use IPv6 network (if available)" +msgstr "El usuario le dice que volvera enseguida." + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +#, fuzzy +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Esta opcion es solo para usuarios en una red privada, detras de un " +"cortafuegos. Siese no es tu caso, deja esto vacio." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +#, fuzzy +msgid "NAT traversal options (experimental)" +msgstr "Opciones para NAT transversal (experimental)" + +#: gtk/interface.c:1156 +#, fuzzy +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Numero de milisegundos en el buffer(compensacion jitter):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "Puerto RTP usado para audio:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "Propiedades de RTP" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Red" + +#: gtk/interface.c:1225 +#, fuzzy +msgid "Playback sound device:" +msgstr "Usar dispositivo de sonido:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "microfono" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "linea" + +#: gtk/interface.c:1250 +#, fuzzy +msgid "Capture sound device:" +msgstr "Usar dispositivo de sonido:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Fuente de grabacion:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Usar dispositivo de sonido:" + +#: gtk/interface.c:1285 +#, fuzzy +msgid "Ring sound:" +msgstr "Fuente de grabacion:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Propiedades de sonido" + +#: gtk/interface.c:1347 +#, fuzzy +msgid "Sound device" +msgstr "Usar dispositivo de sonido:" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Ejecutar SIP user agent en el puerto:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Se recomienda encarecidamente usar el puerto 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "Puerto SIP" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Tu direccion SIP:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identidad" + +#: gtk/interface.c:1467 +#, fuzzy +msgid "Add proxy/registrar" +msgstr "Usar el registro SIP" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Borrar" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Servicios Remotos:" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" + +#: gtk/interface.c:1547 +#, fuzzy +msgid "Authentication information" +msgstr "Informacion de codec" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lista de codecs de audio, en orden de preferencia:" + +#: gtk/interface.c:1595 +#, fuzzy +msgid "Audio codecs" +msgstr "Propiedades del codec de Audio" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "Propiedades del codec de Audio" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Activado" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Desactivado" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "Nota: Los codecs en ROJO no son adecuados para tu conexion a internet." + +#: gtk/interface.c:1720 +#, fuzzy +msgid "No information availlable" +msgstr "Informacion no disponible" + +#: gtk/interface.c:1727 +#, fuzzy +msgid "Codec information" +msgstr "Informacion de codec" + +#: gtk/interface.c:1731 +#, fuzzy +msgid "Audio and video codecs" +msgstr "Propiedades del codec de Audio" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Codecs" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Agenda" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Seleccionar" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informacion" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Usuario no disponible en este momento pero le invita a contactarle usando el " +"siguiente recurso alternativo:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Ninguno." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "" + +#: gtk/interface.c:2344 +#, fuzzy +msgid "SIP Identity:" +msgstr "Identidad" + +#: gtk/interface.c:2359 +#, fuzzy +msgid "Registration Period:" +msgstr "Se ha registrado con exito." + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "" + +#: gtk/interface.c:2381 +#, fuzzy +msgid "Publish presence information:" +msgstr "Informacion de codec" + +#: gtk/interface.c:2466 +#, fuzzy +msgid "Edit contact information" +msgstr "(Ninguna informacion de contacto !)" + +#: gtk/interface.c:2505 +#, fuzzy +msgid "Name:" +msgstr "Nombre" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +#, fuzzy +msgid "Contact information" +msgstr "Informacion de codec" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +#, fuzzy +msgid "password:" +msgstr "Tu Contraseña:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "No se pudo encontrar el archivo pixmap: %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Activado" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Desactivado" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Nombre" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Estado" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +#, fuzzy +msgid "None" +msgstr "Ninguno." + +#: gtk/friends.c:117 +#, fuzzy +msgid "Presence status" +msgstr "Estado" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +#, fuzzy +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"Direccion SIP mal escrita. Una direccion SIP es " + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Contactando " + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" + +#: coreapi/linphonecore.c:692 +#, fuzzy +msgid "Ready" +msgstr "Preparado." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "" + +#: coreapi/linphonecore.c:1138 +#, fuzzy +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Direccion SIP mal escrita. Una direccion SIP es " + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "Contactando " + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Conectado." + +#: coreapi/linphonecore.c:1550 +#, fuzzy +msgid "Call ended" +msgstr "Llamada cancelada." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Tu ordenador parece estar usando los controladores de ALSA.\n" +"Esa es la mejor eleccion. Sin embargo el modulo de emulacion pcm de OSS\n" +"no se encuentra y linphone lo necesita. Por favor ejecute\n" +"'modprobe snd-pcm-oss' como root para cargarlo." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Tu ordenador parece estar usando los controladores de ALSA.\n" +"Esa es la mejor eleccion. Sin embargo el modulo de emulacion mixer de OSS\n" +"no se encuentra y linphone lo necesita. Por favor ejecute\n" +" 'modprobe snd-mixer-oss' como root para cargarlo." + +#: coreapi/exevents.c:115 +#, fuzzy +msgid "Call terminated." +msgstr "Llamada cancelada." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "El usuario esta ocupado." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "El usuario le dice que volvera enseguida." + +#: coreapi/exevents.c:148 +#, fuzzy +msgid "Request Cancelled." +msgstr "Llamada cancelada." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "El usuario no quiere que lo molesten." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Llamada cancelada." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "No se encontro ningun usuario en la direccion indicada." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "El usuario remoto no soporta ninguno de los codecs propuestos." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Tiempo agotado." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Se encontro host remoto pero rechazo la conexion." + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "le esta llamando." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Usuario no disponible en este momento pero le invita\n" +"a contactarle usando el siguiente recurso alternativo:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Se ha registrado con exito." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "Se ha registrado con exito." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +#, fuzzy +msgid "Gone" +msgstr "Ninguno." + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "linea" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "Manual de Usuario" + +#~ msgid "Communication ended." +#~ msgstr "Comunicacion finalizada." + +#~ msgid "Call cancelled." +#~ msgstr "Llamada cancelada." + +#, fuzzy +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Direccion IP del cortafuegos (en notacion con puntos):" + +#~ msgid "Index" +#~ msgstr "Indice" + +#~ msgid "Address" +#~ msgstr "Direccion" + +#, fuzzy +#~ msgid "Server address" +#~ msgstr "Direccion del Servidor:" + +#~ msgid "28k modem" +#~ msgstr "modem 28k" + +#~ msgid "56k modem" +#~ msgstr "modem 56k" + +#~ msgid "64k modem (numeris)" +#~ msgstr "modem 64k (numeris)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL o Cable" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet o equivalente" + +#~ msgid "Connection type:" +#~ msgstr "Tipo de conexion:" + +#, fuzzy +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone no pudo abrir el dispositivo de audio. Asegurese que su tarjeta " +#~ "de sonido esta completamente configurada y operativa." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Escribe aqui la direccion SIP de la persona que quieres llamar." + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "Descolgar o\n" +#~ "Rechazar" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s. Reintentar tras %i minutos." + +#, fuzzy +#~ msgid "Timeout..." +#~ msgstr "Tiempo agotado." + +#~ msgid "Connection" +#~ msgstr "Conexion" + +#, fuzzy +#~ msgid "" +#~ "Add address\n" +#~ "book" +#~ msgstr "Agenda" + +#~ msgid "Toggle this if you want to be registered on a remote server." +#~ msgstr "Marcar opcion si desea registrarse en un servidor remoto." + +#~ msgid "Address of record:" +#~ msgstr "Nombre de registro:" + +#~ msgid "" +#~ "The password used for registration. On some servers it is not necessary" +#~ msgstr "" +#~ "La contraseña usada para registrarse. En algunos servidores no es " +#~ "necesaria" + +#~ msgid "Use this registrar server as outbound proxy." +#~ msgstr "Usar el servidor de registro como outbound proxy." + +#~ msgid "sip address:" +#~ msgstr "Direccion SIP:" + +#~ msgid "Display name:" +#~ msgstr "Nombre a mostrar:" + +#~ msgid "Modify" +#~ msgstr "Modificar" + +#~ msgid "Registering..." +#~ msgstr "Registrando..." + +#~ msgid "" +#~ "You are currently using the i810_audio driver.\n" +#~ "This driver is buggy and so does not work with Linphone.\n" +#~ "We suggest that you replace it by its equivalent ALSA driver,\n" +#~ "either with packages from your distribution, or by downloading\n" +#~ "ALSA drivers at http://www.alsa-project.org." +#~ msgstr "" +#~ "Estas usando actualmente el controlador i810_audio.\n" +#~ "Ese controlador tiene errores y por tanto no funciona con Linphone.\n" +#~ "Le recomendamos que lo sustituya por su controlador equivalente de ALSA,\n" +#~ "ya sea mediante paquetes de su distribucion, o descargando\n" +#~ "controladores ALSA de http://www.alsa-project.org." + +#~ msgid "Unregistration successfull." +#~ msgstr "Cancelacion del registro completada." + +#~ msgid "3" +#~ msgstr "3" + +#~ msgid "2" +#~ msgstr "2" + +#~ msgid "4" +#~ msgstr "4" + +#~ msgid "6" +#~ msgstr "6" + +#~ msgid "7" +#~ msgstr "7" + +#~ msgid "8" +#~ msgstr "8" + +#~ msgid "9" +#~ msgstr "9" + +#~ msgid "C: 2001" +#~ msgstr "Abril 2001" + +#~ msgid "Select network interface to use:" +#~ msgstr "Selecciona la interfaz de red para usar:" + +#~ msgid "Network interface properties" +#~ msgstr "Propiedades de Interfaz de Red:" + +#~ msgid "RTP" +#~ msgstr "RTP" + +#~ msgid "Add" +#~ msgstr "Añadir" + +#~ msgid "Threads not supported by glib. Upgrade your glib.\n" +#~ msgstr "Threads no soportados por glib. Actualize su glib.\n" + +#~ msgid "Run linphone as a gnome-applet." +#~ msgstr "Lanzar linphone como un gnome-applet." + +#~ msgid "Run linphone as a daemon (for use without gnome)." +#~ msgstr "Ejecutar linphone como demonio (para uso sin gnome)." + +#~ msgid "" +#~ "Cannot find network previously used interface %s.\n" +#~ "If your computer is temporary connected to the internet, please connect " +#~ "and then run linphone.\n" +#~ "If you want to change your default network interface, go to the " +#~ "parameters 'box." +#~ msgstr "" +#~ "No se puede encontrar la interfaz de red usada previamente %s.\n" +#~ "Si tu ordenador esta conectado temporalmente a Internet, por favor " +#~ "conecta y entonces ejecuta linphone.\n" +#~ "Si quieres cambiar tu interfaz de red predeterminada, ve a la opcion " +#~ "Parametros." + +#, fuzzy +#~ msgid "" +#~ "Linphone cannot open the audio device.\n" +#~ "It may be caused by other programs using it.\n" +#~ "Do you want linphone to kill these programs (esd or artsd) ?" +#~ msgstr "" +#~ "Linphone no puede abrir el dispositivo de audio.\n" +#~ " Puede deberse a que otros programas lo esten usando.\n" +#~ "¿ Quiere que Linphone cierre esos programas (esd o artsd) ?" + +#~ msgid "Use it as a:" +#~ msgstr "Usarlo como un:" + +#~ msgid "Redirect server" +#~ msgstr "Servidor de Redireccionamiento" + +#~ msgid "Outbound proxy" +#~ msgstr "Outbound proxy" + +#~ msgid "" +#~ "Togle this button if the registrar must be used to proxy calls through a " +#~ "firewall." +#~ msgstr "" +#~ "Marcar esta opcion si el servidor de registro debe ser usado para " +#~ "llamadas a proxy a traves de un cortafuegos." + +#~ msgid "OSS" +#~ msgstr "OSS" + +#~ msgid "ALSA" +#~ msgstr "ALSA" + +#~ msgid "Automatically kill applications using soundcard when needed" +#~ msgstr "" +#~ "Cerrar aplicaciones que usen la tarjeta de sonido cuando se necesite." + +#~ msgid "" +#~ "Your computer is connected to several networks. Check in the global " +#~ "parameters if Linphone uses the one that you want." +#~ msgstr "" +#~ "Tu ordenador esta conectado a varias redes. Revisa en los Parametros " +#~ "globales si Linphone usa la que necesitas." + +#~ msgid "" +#~ "Linphone failed to open the sound device. See the README file included in " +#~ "the distribution for details." +#~ msgstr "" +#~ "Linphone fallo al abrir el dispositivo de sonido. Vea el archivo README " +#~ "incluido en la distribucion para mas detalles." + +#~ msgid "Interface not found." +#~ msgstr "Interfaz no encontrada." + +#~ msgid "Warning" +#~ msgstr "Atencion" + +#~ msgid "" +#~ "Linphone cannot open the sound device. It may be caused by other programs " +#~ "using it. Do you want linphone to kill these programs (esd or artsd) ?" +#~ msgstr "" +#~ "Linphone no puede abrir el dispositivo de sonido. Puede deberse a que " +#~ "otros programaslo esten usando. ¿ Quiere que Linphone cierre esos " +#~ "programas (esd o artsd) ?" + +#~ msgid "Linphone shutdowns" +#~ msgstr "Linphone esta terminando..." + +#~ msgid "Linphone shutdowns..." +#~ msgstr "Linphone esta terminando..." + +#~ msgid "" +#~ "Please, wait a few seconds untils linphone unregisters your sip addess " +#~ "from registrar server..." +#~ msgstr "" +#~ "Por favor, espere unos segundos hasta que Linphone cancele el registro de " +#~ "su direccion SIP en el servidor de registros..." + +#~ msgid "Bad formuled sip address." +#~ msgstr "Direccion SIP mal escrita." + +#~ msgid "Couldn't create pixmap from file: %s" +#~ msgstr "No se pudo crear pixmap desde el archivo: %s" + +#~ msgid "" +#~ "Linphone did not detect any valid network interface. If you use a " +#~ "temporary internet connection, please connect and then run linphone again." +#~ msgstr "" +#~ "Linphone no detecto ninguna interfaz de red valida. Si usas una conexion " +#~ "temporal a Internet, por favor conecta y vuelve a ejecutar Linphone." + +#~ msgid "List of network interfaces on your system." +#~ msgstr "Lista de interfaces de red en tu sistema." + +#~ msgid "" +#~ "RTP est le mode de transport de la voix. Modifier ces paramètres pour " +#~ "tenter d'améliorer la qualité de la communication si celle-ci est " +#~ "dégradée." +#~ msgstr "" +#~ "RTP es el modelo de transporte de la voz. Modifica estos parametros para " +#~ "intentar mejorar la calidad de la comunicacion, si es que.es mala." + +#~ msgid "Use rtp port:" +#~ msgstr "Puerto RTP:" + +#~ msgid "" +#~ "Les codecs ou vocodeurs sont les algorithmes utilisés pour compresser la " +#~ "voix." +#~ msgstr "" +#~ "Los codecs o codificadores/decodificadores son los algoritmos usados para " +#~ "comprimir la voz." + +#~ msgid "" +#~ "Vous pouvez ajuster avec cet onglet des paramètre liés à votre carte son." +#~ msgstr "Puede modificar estos parametros a su gusto." diff --git a/linphone/po/fr.po b/linphone/po/fr.po new file mode 100644 index 000000000..0d05546fc --- /dev/null +++ b/linphone/po/fr.po @@ -0,0 +1,1031 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Simon Morlat , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: Linphone 0.9.1\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2002-12-06 17:33+0100\n" +"Last-Translator: Simon Morlat \n" +"Language-Team: french \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Aller à" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Carnet d'adresses" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Historique des appels" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Affichage des appels" + +#: gtk/interface.c:188 +#, fuzzy +msgid "Exit" +msgstr "Editer" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Adresse sip:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Affiche le carnet d'adresses" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Serveur proxy" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Appeler ou\n" +"Répondre" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"Raccrocher\n" +"ou refuser" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Ou chatter !" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Plus d'options..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Niveau d'écoute:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Niveau d'enregistrement:" + +#: gtk/interface.c:354 +msgid "Ring level:" +msgstr "Volume de la sonnerie :" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Son" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "video active" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "Video" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "Controles" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Joignable" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Occupé, de retour dans " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" +"Vos correspondants seront informés que vous serez de retour dans X minutes" + +#: gtk/interface.c:431 +msgid "5" +msgstr "" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Absent" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Ne pas déranger" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "En déplacement" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Autre service" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Présence" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Utiliser ce clavier pour envoyer des DTMFs." + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "" + +#: gtk/interface.c:561 +msgid "0" +msgstr "" + +#: gtk/interface.c:567 +msgid "#" +msgstr "" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Mes amis en ligne" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"Avril 2001\n" +"Fabriqué en France" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone est un téléhone internet.\n" +"Il est compatible avec les protocoles SIP et RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Paramètres" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "Utiliser un réseau IPv6 (si disponible)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Cocher cette case si vous êtes sur un réseau IPv6 et que vous voulez que " +"linphone l'utilise." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Utiliser ceci si vous êtes dans un réseau privé derrière un pare-feu et que " +"vous souhaitez passer des appels vers l'internet public." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "Pas de pare-feu" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "Utiliser ce serveur STUN pour deviner l'adresse du pare feu:" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "Donner l'addresse du pare-feu manuellement:" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "Options d'utilisation avec un pare-feu (expérimental)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Temps de bufferisation (jitter compensation):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "Port RTP pour l'audio:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "Paramètres RTP" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" +"Utilise les messages SIP INFO à la place des RTP RFC2833 pour signaler les " +"DTMFs" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 est recommandé" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Autre" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Réseau" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Carte son (pour l'écoute)" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "micro" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "line" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "Carte son (pour le micro) :" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Source d'enregistrement:" + +#: gtk/interface.c:1277 +msgid "Ring sound device" +msgstr "Carte son (pour la sonnerie) :" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "Son de sonnerie:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" +"Annulation d'écho active (annule l'écho entendu par votre correspondant)" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Ecouter" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Paramètres son" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Carte son" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "SIP user agent sur le port:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Il est FORTEMENT recommand�d'utiliser le port 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "Port SIP" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Votre adresse sip:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Choix automatique du nom d'hôte (recommandé)" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identité" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Ajouter un proxy ou un registrar" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Editer" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Supprimer" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Services sur serveur distant" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" +"Effacer les informations d'authentification (utilisateur, mot de passe...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Information d'authentification" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Liste des codecs audio, par ordre de préférence:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Codecs audio" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "Codecs video" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Active" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Désactive" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "Bande passante montante (kbit/sec)" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "Bande passante descendante (kbit/sec)" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Remarque: les codecs en rouge ne sont pas utilisables compte tenu de votre " +"type de connection internet." + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Pas d'information disponible" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Information sur le codec" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "Codecs audio et video" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Carnet d'adresses" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Sélectionner" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Votre correspondant n'est pas joignable actuellement mais il vous propose\n" +"de le contacter en utilisant le moyen alternatif suivant:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Aucun." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Paramétrage des proxy" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Route (optionnel):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "Proxy SIP:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "Identité SIP:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Période d'enregistrement" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Enregistrement (REGISTER):" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Envoyer les informations de presence" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Editer le contact" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Nom:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Politique concernant les souscriptions:" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Envoie une soucription (pour connaitre la disponibilit�de la personne)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Information sur le contact" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Nouvelle souscription entrante" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "Vous avez reçu une souscription..." + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Refuser" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Accepter" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Vous devez vous authentifier" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "Authentification requise sur le realm" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "mot de passe:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "nom d'utilisateur:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - Historique des appels" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Texte:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Chat avec %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Ne peut trouvé l'icone : %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "Compte" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Activé" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Désactivé" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Nom" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Fréquence (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Etat" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Débit min. (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "Pas de limite" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" +"Votre correspondant propose d'utiliser des m?anismes de r?ervation de " +"ressources. Souhaitez-vous accepter ?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"Votre correspondant n'utilise pas de m?anisme de r?ervation de ressources. " +"Souhaitez-vous continuer tout de m?e ?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "linphone - appel entrant de %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"Vous avez reçu une souscription de %s. Cela signifie que cette personne " +"souhaite être au courant de votre disponibilité au téléhone (en ligne, " +"occupé, parti...)\n" +"Etes vous d'accord ?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Authentification requise sur le realm %s" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Aucun" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Info de présence" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +#, fuzzy +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"Adresse SIP mal formulée. Une address sip ressemble à " + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Appel de" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "Vous avez manqué %i appel(s)" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "abandonné" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "terminé" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "manqué" + +#: coreapi/linphonecore.c:223 +#, fuzzy, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s le %sDe: %s\n" +"A destination de: %s\n" +"Etat: %s\n" +"Durée: %i mn %i sec\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Appel entrant" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Appel sortant" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Votre machine semble être connectée à un réseau IPv6. Par defaut linphone " +"utilise toujours de l'IPv4. Merci de mettre à jour votre configuration si " +"vous souhaitez utilisez un réseau IPv6." + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "Prêt." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "Découverte STUN en cours" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "Découverte STUN effectuée." + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Recherche de la destination du numéro de téléphone..." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "La destination n'a pu être trouvée." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Adresse SIP mal formulée. Une address sip ressemble à " + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "Désolé, vous ne pouvez appeler plusieurs personnes simultanément !" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "Appel de" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "Echec" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "En ligne." + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "Appel terminé." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "Adresse nat invalide '%s' : %s" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Votre ordinateur semble utiliser les pilotes sons ALSA.\n" +"C'est en g��al le meilleur choix, cependant un module\n" +"d'emulation oss est manquant et linphone en a besoin.\n" +"Veuillez s'il vous plait executer la commande\n" +"'modprobe snd-pcm-oss' en tant que root afin de le charger." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Votre ordinateur semble utiliser les pilotes sons ALSA. C'est en g��al le\n" +"meilleur choix, cependant un module d'emulation est manquant et linphone en\n" +"a besoin. Veuillez s'il vous plait executer la commande\n" +"'modprobe snd-mixer-oss' en tant que root afin de le charger." + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "Appel terminé." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Impossible de joindre votre correspondant." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Occupé..." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "L'usager est temporairement indisponible." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Requête annulée." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "L'usager ne souhaite pas être dérangé" + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Appel décliné." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Requete erronée" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "L'utilisateur n'a pu être trouvé à l'addresse spécifiée" + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Votre correspondant ne supporte aucun des codecs proposés." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Temps d'attente dépassé..." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "La machine distante a été trouvée mais a refusé la connexion." + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "vous appelle." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Redirigé vers %s ..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Votre correspondant n'est pas joignable actuellement mais il vous propose\n" +"de le contacter en utilisant le moyen alternatif suivant:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Echec de l'enregistrement sur %s (trop long)" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "Enregistrement sur %s effectué." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "Parti" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "En attente" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "Disponible" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "Occupé" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "De retour" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "Au téléphone" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "A table" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "Eteint" + +#~ msgid "enter sip uri here" +#~ msgstr "entrer une adresse sip ici" + +#~ msgid "User manual" +#~ msgstr "Manuel de l'utilisateur" + +#~ msgid "Ring sound selection" +#~ msgstr "Selection de la sonnerie" + +#~ msgid "Communication ended." +#~ msgstr "Communication termin�." + +#~ msgid "Call cancelled." +#~ msgstr "Appel annulé" + +#~ msgid "28k modem" +#~ msgstr "modem 28k" + +#~ msgid "56k modem" +#~ msgstr "modem 56k" + +#~ msgid "64k modem (numeris)" +#~ msgstr "modem 64k (numeris)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "modem ADSL ou cable" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet ou semblable" + +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Adresse IP du pare-feu (de.ce.format.la) :" + +#~ msgid "Connection type:" +#~ msgstr "Type de connexion:" + +#~ msgid "Address" +#~ msgstr "Adresse" + +#~ msgid "Server address" +#~ msgstr "Adresse du serveur:" + +#, fuzzy +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone n'a pu utilis?votre carte son. Veuillez v?ifier qu'elle " +#~ "fonctionne correctement." diff --git a/linphone/po/hu.po b/linphone/po/hu.po new file mode 100644 index 000000000..ff0f2ee12 --- /dev/null +++ b/linphone/po/hu.po @@ -0,0 +1,986 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2007-12-14 11:12+0100\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "Egy ingyenes SIP video-telefon" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Ugrás" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Címjegyzék" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Hivás elÅ‘zmények" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Mutasd a hívásokat" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "Kilépés" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "Help" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "Gépeld ide a sip címet vagy a telefonszámot" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Sip cím:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Mutasd a címjegyzéket" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Használt SIP Proxy:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Hívás vagy\n" +"Válasz" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"Lerak vagy\n" +"Nem válaszol" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Vagy chat-elj!" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "További beállítások..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Lejátszási hangerÅ‘:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Felvételi hangerÅ‘:" + +#: gtk/interface.c:354 +msgid "Ring level:" +msgstr "Csengetési hangerÅ‘:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Hang" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "Video engedélyezés" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "Video" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "Vezérlés" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "ElérhetÅ‘" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Foglalt vagyok, jövök vissza" + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "A másik fél tájékoztatva lesz, hogy X perc alatt vissza fogsz jönni" + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "perc" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Nem elérhetÅ‘" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Ne zavarj" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Ideiglenesen nem elérhetÅ‘" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Ãtirányítás" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "ElérhetÅ‘" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Nyomja le a számokat a DTMF küldéshez" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" +" 3\n" +"def" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" +" 2\n" +"abc" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" +" 4\n" +"ghi" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" +" 5\n" +"jkl" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" +" 6\n" +"mno" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" +" 7\n" +"pqrs" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" +" 8\n" +"tuv" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" +" 9\n" +"wxyz" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "ElérhetÅ‘ partnerek" + +#: gtk/interface.c:849 gtk/interface.c:3029 +msgid "Linphone" +msgstr "Linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"C: 2001\n" +"Made in Old Europe" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"A Linphone egy web-telefon.\n" +"SIP és RTP kompatíbilis." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "http://www.linphone.org" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Paraméterek" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "IPv6 hálózat használata (ha elérhetÅ‘)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "Ha egy IPv6 hálózat elérhetÅ‘, akkor a linphone használja azt." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "Ãltalános" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Ez az opció azoknak a felhasználóknak kell, akik egy privát hálózaton tűzfal " +"mögül interneteznek. Egyébként üresen kell hagyni." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "Nincs tűzfal" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "STUN szerver használata a tűzfal címének meghatározásához." + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "Tűzfal külsÅ‘ címe:" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "NAT beállítások áttekintése (kísérleti)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "A pufferelt milisecondok száma (jitter compensation):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "RTP port, audió használatra:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP beállítások" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "Használj SIP INFO üzenetet RTP rfc2833 helyett a DTMF átvitelnél" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 az ajánlott." + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Egyéb" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Hálózat" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Lejátszó hang eszköz:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "mikrofon" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "line" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "FelvevÅ‘ hang eszköz:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Felvételi forrás:" + +#: gtk/interface.c:1277 +msgid "Ring sound device" +msgstr "CsengÅ‘hang forrás:" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "CsengÅ‘hang:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" +"Visszhang törlés engedélyezése (törli a visszhangot, amit hall a távoli " +"partner" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "Fájl kiválasztás" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Hallgatás" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Hang beállítások" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Hang eszköz" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "SIP felhasználó ügynök által használt port:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "ErÅ‘sen ajánlott az 5060-as port használata." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP port" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Saját sip cím:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Automatikus valós hostnév megállapítása" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Azonosító" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Proxy vagy regisztráció hozzáadás" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Szerkesztés" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Eltávolítás" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Távoli szolgáltatások" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" +"Az összes tárolt hitelesítési információ törlése (felhasználónév, jelszó...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Hitelesítési információ" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Az audió kódoló-dekódolók listája, a preferencia rendjében:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Audio kodekek" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "Audio kodekek" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Engedélyezés" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Tiltás" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "Feltöltési sávszélesség (kbit/sec):" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "Letöltési sávszélesség (kbit/sec):" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Figyelem: A pirosban lévÅ‘ kodekek nem használhatók a jelenlegi " +"internetkapcsolattal." + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Nem érhetÅ‘ el információ" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Kodekinformáció" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "Audio és video kodekek" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Kodekek" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Címjegyzék" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Kiválasztás" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Információk" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"A felhasználó jelenleg nem elérhetÅ‘, de kéri, hogy lépj vele kapcsolatba itt:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Nincs." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Proxy/Regisztráció konfigurációs doboz" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Út (nem kötelezÅ‘):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "SIP Proxy:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "SIP azonosító:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Regisztrálási IdÅ‘köz:" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Regisztárció küldés:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Jelenléti információ közlése:" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Kapcsolatinformációk szerkesztése" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Név:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Láthatósági szabály:" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Láthatóság küldése (látszik a személy elérhetÅ‘ségi státusza)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Kapcsolatiinformáció" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Új beérkezÅ‘ elÅ‘fizetés" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "Megkaptál egy új elÅ‘fizetést." + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Hulladék" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Elfogad" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Hitelesítést kértek" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "Hitelesítési kérelem a tartománynak" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "felhasználói azonosító:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "jelszó:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "felhasználónév:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "tartomány:" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - HíváselÅ‘zmények" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Chat szoba" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Szöveg:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Chat-elés %s -el" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Nemtalálható a pixmap fájl: %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "Hozzáférés" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Engedélyezve" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Tiltva" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Név" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Érték (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Ãllapot" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Min bitrate (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "Korlátlan" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "A hívó forrásfoglalást kér. Egyetértesz?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"A hívó nem használ forrásfoglalást. \t\t\t\t\tÃgy is szeretnéd folytatni?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "linphone - hívást fogad innen %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"Kaptál egy elÅ‘fizetést tÅ‘le %s. Ez azt jelenti, hogy ez a személy szeretné, " +"hogy értesítsék a jelenlétinformációd (online, elfoglalt, away...).\n" +"Egyetértesz?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Hitelesítési kérelem ebbÅ‘l a tartományból %s" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Nincs" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Jelenlét státusz" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "Várakozás" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "Tiltás" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "Rossz sip cím: egy sip cím általában így néz ki: user@domain" + +#: gtk/addressbook.c:226 +msgid "Contact list" +msgstr "Kapcsolatilista" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "Van %i elhibázott hivás." + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "megszakítva" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "befejezve" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "elhibázva" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s nél %s\n" +"Tól: %s\n" +"Ig: %s\n" +"Ãllapot: %s\n" +"IdÅ‘tartam: %i perc %i másodperc\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "BeérkezÅ‘ hívás" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "KimenÅ‘ hívás" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"A géped úgy tűnik, hogy csatlakozik egy IPv6 hálózathoz. Alapból a linphone " +"mindig az IPv4-et használja. Frissítsd a konfigurációdat, ha használni " +"akarod az IPv6-ot" + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "Kész" + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "Stun keresés folyamatban..." + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "Stun keresés kész..." + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Telefonszám-cél keresése..." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Nem sikkerült értelmezni a számot." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Az adott szám nem értelmezhetÅ‘. Egy sip cím általában így néz ki: user@domain" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "Bocsánat, a többszörös egyidejű hívások még nem támogatottak!" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "Kapcsolódás" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "nem sikerült hívni" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Kapcsolódva." + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "Hívás vége" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "Nincs nat/tűzfal cím megadva!" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "Hibás nat cím '%s' : %s" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"A számítógéped úgy tűnik, hogy ALSA hangot használ.\n" +"Ez a legjobb választás. Mindazonáltal a pcm* OSS emuláció modulra\n" +" a linphone-nak szüksége van és ez hiányzik. Kérem futassa le a\n" +"'modprobe snd-pcm-oss' parancsot rendszergazdaként." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"A számítógéped úgy tűnik, hogy ALSA hangot használ.\n" +"Ez a legjobb választás. Mindazonáltal a mixer OSS emuláció modulra\n" +" a linphone-nak szüksége van és ez hiányzik. Kérem futassa le a\n" +"'modprobe snd-pcm-oss' parancsot rendszergazdaként." + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "A hívás befejezve." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "A cél elérhetetlen." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "A felhasználó foglalt." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "A felhasználó ideiglenesen nem elérhetÅ‘" + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Kérelem elutasítva." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "A felhasználó nem akarja, hogy zavarják." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Hívás elutasítva" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Rossz kérés" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Nem telálható felhasználó at adott címen." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "" +"A távoli felhasználó nem rendelkezik a javasolt kódoló-dekódolókkal (codecs)" + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "IdÅ‘túllépés." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "A távoli gép elérhetÅ‘, de a kapcsolatot visszautasította." + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "kapcsolatba lép veled." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Ãtirányítva idw %s..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"A felhasználó nem elérhetÅ‘ pillanatnyilag de meghívja Önt\n" +"thogy lépjen kapcsolatba vele miközben használja a következÅ‘ alternatív " +"erÅ‘forrást:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "Korai médiák." + +#: coreapi/exevents.c:837 +#, c-format +msgid "Registration on %s failed: %s" +msgstr "A regisztáció a %s -n nem sikerült: %s" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "idÅ‘túllépés után nincs válasz" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "A regisztáció a %s -n sikerült." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "Elveszítve" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "Jóváhagyásra vár" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "ElérhetÅ‘" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "Foglalt" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "Legyen igazad" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "Telefonál" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "Ebédelni ment" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "Lezárva" diff --git a/linphone/po/insert-header.sin b/linphone/po/insert-header.sin new file mode 100644 index 000000000..b26de01f6 --- /dev/null +++ b/linphone/po/insert-header.sin @@ -0,0 +1,23 @@ +# Sed script that inserts the file called HEADER before the header entry. +# +# At each occurrence of a line starting with "msgid ", we execute the following +# commands. At the first occurrence, insert the file. At the following +# occurrences, do nothing. The distinction between the first and the following +# occurrences is achieved by looking at the hold space. +/^msgid /{ +x +# Test if the hold space is empty. +s/m/m/ +ta +# Yes it was empty. First occurrence. Read the file. +r HEADER +# Output the file's contents by reading the next line. But don't lose the +# current line while doing this. +g +N +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/linphone/po/it.po b/linphone/po/it.po new file mode 100644 index 000000000..680e6c73e --- /dev/null +++ b/linphone/po/it.po @@ -0,0 +1,1026 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Linphone 0.9.1\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2002-10-15 HO:MI+ZONE\n" +"Last-Translator: Alberto Zanoni \n" +"Language-Team: it \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Rubrica" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +#, fuzzy +msgid "Enter sip address or phone number here" +msgstr "Indirizzo sip del server segretario." + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Indirizzo sip:" + +#: gtk/interface.c:247 +#, fuzzy +msgid "Shows the address book" +msgstr "Rubrica" + +#: gtk/interface.c:261 +msgid "..." +msgstr "" + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "" + +#: gtk/interface.c:278 +#, fuzzy +msgid "" +"Call or\n" +"answer" +msgstr "" +"Chiamare o\n" +"Rispondere" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Mostra altre opzioni..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Livello di riproduzione:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Livello di registrazione:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Livello di registrazione:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Suono" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "Attivato" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Raggiungibile" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Occupato, torno fra " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "L'altro utente sarà informato che sarai di ritorno in X minuti" + +#: gtk/interface.c:431 +msgid "5" +msgstr "" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Assente" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Non disturbare" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Temporaneamente non disponibile" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Servizio alternativo" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Presenza" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "" + +#: gtk/interface.c:561 +msgid "0" +msgstr "" + +#: gtk/interface.c:567 +msgid "#" +msgstr "" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone è un telefono su internet.\n" +"E' compatibile con i protocolli SIP et RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parametri" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "" + +#: gtk/interface.c:1156 +#, fuzzy +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Numero dei pacchetti bufferizzati (compensazione jitter):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Rete" + +#: gtk/interface.c:1225 +#, fuzzy +msgid "Playback sound device:" +msgstr "Driver del suono:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "microfono" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "linea" + +#: gtk/interface.c:1250 +#, fuzzy +msgid "Capture sound device:" +msgstr "Driver del suono:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Sorgente di registrazione:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Driver del suono:" + +#: gtk/interface.c:1285 +#, fuzzy +msgid "Ring sound:" +msgstr "Sorgente di registrazione:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "" + +#: gtk/interface.c:1347 +#, fuzzy +msgid "Sound device" +msgstr "Driver del suono:" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Agente utente SIP sulla porta:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Si raccomanda FORTEMENTE di utilizzare la porta 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Il tuo indirizzo sip:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "" + +#: gtk/interface.c:1467 +#, fuzzy +msgid "Add proxy/registrar" +msgstr "Usa il segretario sip" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Servizi remoti:" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" + +#: gtk/interface.c:1547 +#, fuzzy +msgid "Authentication information" +msgstr "Informazioni" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lista dei codec audio, in ordine di preferenza:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "Codec" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Attivato" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Disattivato" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Nota: i codec in rosso non sono utilizzabili per il tuo tipo di connessione " +"internet." + +#: gtk/interface.c:1720 +#, fuzzy +msgid "No information availlable" +msgstr "Informazioni" + +#: gtk/interface.c:1727 +#, fuzzy +msgid "Codec information" +msgstr "Informazioni" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Codec" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Rubrica" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Seleziona" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informazioni" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "" + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "" + +#: gtk/interface.c:2381 +#, fuzzy +msgid "Publish presence information:" +msgstr "Informazioni" + +#: gtk/interface.c:2466 +#, fuzzy +msgid "Edit contact information" +msgstr "Informazioni" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +#, fuzzy +msgid "Contact information" +msgstr "Informazioni" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +#, fuzzy +msgid "password:" +msgstr "Password:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +#, fuzzy +msgid "Enabled" +msgstr "Attivato" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +#, fuzzy +msgid "Disabled" +msgstr "Disattivato" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "" + +#: gtk/friends.c:117 +#, fuzzy +msgid "Presence status" +msgstr "Presenza" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Connessione" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "" + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "" + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "Connessione" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +#, fuzzy +msgid "Connected." +msgstr "Connessione" + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "" + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "" + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "" + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "" + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "" + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "" + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "" + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "" + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "" + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "Connessione" + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, c-format +msgid "Registration on %s failed: %s" +msgstr "" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "" + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "linea" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "Manuale utente" + +#, fuzzy +#~ msgid "Address" +#~ msgstr "Rubrica" + +#, fuzzy +#~ msgid "Server address" +#~ msgstr "Indirizzo server:" + +#~ msgid "28k modem" +#~ msgstr "modem 28k" + +#~ msgid "56k modem" +#~ msgstr "modem 56k" + +#~ msgid "64k modem (numeris)" +#~ msgstr "modem 64k (numeris)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "modem ADSL o cavo" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet o equivalente" + +#~ msgid "Connection type:" +#~ msgstr "Tipo di connessione:" + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Inserire l'indirizzo sip dell'utente che si vuol chiamare." + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "Lasciare o\n" +#~ "Rifiutare" + +#~ msgid "Connection" +#~ msgstr "Connessione" + +#, fuzzy +#~ msgid "" +#~ "Add address\n" +#~ "book" +#~ msgstr "Rubrica" + +#~ msgid "Toggle this if you want to be registered on a remote server." +#~ msgstr "Clicare qui per la registrazione su un server remoto." + +#~ msgid "" +#~ "The password used for registration. On some servers it is not necessary" +#~ msgstr "" +#~ "Password usata per la registrazione. Su alcuni server non è necessaria" + +#~ msgid "sip address:" +#~ msgstr "Indirizzo sip:" + +#~ msgid "Display name:" +#~ msgstr "Mostra il nome:" diff --git a/linphone/po/ja.po b/linphone/po/ja.po new file mode 100644 index 000000000..3b8d13f50 --- /dev/null +++ b/linphone/po/ja.po @@ -0,0 +1,1156 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# »³¸ýÁ±Ìé , 2002. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: linphone 0.10\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2003-01-21 00:05+9000\n" +"Last-Translator: YAMAGUCHI YOSHIYA \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=EUC-JP\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "Linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "ÅÅÏÃÄ¢" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +#, fuzzy +msgid "Enter sip address or phone number here" +msgstr "¥ì¥¸¥¹¥È¥é¥µ¡¼¥Ð¡¼¤ÎSIP¥¢¥É¥ì¥¹" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Sip¥¢¥É¥ì¥¹:" + +#: gtk/interface.c:247 +#, fuzzy +msgid "Shows the address book" +msgstr "ÅÅÏÃÄ¢" + +#: gtk/interface.c:261 +msgid "..." +msgstr "" + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "" + +#: gtk/interface.c:278 +#, fuzzy +msgid "" +"Call or\n" +"answer" +msgstr "" +"ÅÅÏäò¤«¤±¤ë\n" +"ÅÅÏä˽Фë" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "¾ÜºÙ" + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "¼õÏò»ÎÌ" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Á÷Ïò»ÎÌ" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Á÷Ïò»ÎÌ" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "¥µ¥¦¥ó¥É" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "»ÈÍѤ¹¤ë" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "ºßÀÊÃæ" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "º£Àʤò¤Ï¤º¤·¤Æ¤¤¤Þ¤¹¡£" + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "ȯ¿®¼Ô¤Ï¡¢¤¢¤Ê¤¿¤¬Xʬ¸å¤ËÌá¤Ã¤Æ¤¯¤ë¤³¤È¤¬Ê¬¤«¤ê¤Þ¤¹¡£" + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "ʬ" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "ÂàÀÊÃæ" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "¼ê¤¬Î¥¤»¤Þ¤»¤ó" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "¤¹¤°Ìá¤ê¤Þ¤¹" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "¾¤ÎÏ¢Íí¼êÃʤò»È¤Ã¤Æ²¼¤µ¤¤" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "¾õÂÖ" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "DTMF¤òÁ÷¿®¤¹¤ë¤¿¤á¤Î¿ô»ú¤ò²¡¤·¤Æ²¼¤µ¤¤¡£" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "Linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÅÅÏäǤ¹¡£\n" +"SIP¡¦RTP¥×¥í¥È¥³¥ë¤È¸ß´¹À­¤¬¤¢¤ê¤Þ¤¹¡£" + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "¥Ñ¥é¥á¡¼¥¿¡¼" + +#: gtk/interface.c:1061 +#, fuzzy +msgid "Use IPv6 network (if available)" +msgstr "¥æ¡¼¥¶¡¼¤Ï¡¢º£½Ð¤é¤ì¤Þ¤»¤ó¡£" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "" + +#: gtk/interface.c:1156 +#, fuzzy +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "" +"¥Ð¥Ã¥Õ¥¡¤¹¤ë¥ß¥êÉÃ\n" +"(²»À¼¤¬ÅÓÀÚ¤ì¤ë¤È¤­¤ÏÂ礭¤¯¤·¤Þ¤¹)" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "¥ª¡¼¥Ç¥£¥ª¤Ë»ÈÍѤ¹¤ëRTP¥Ý¡¼¥ÈÈÖ¹æ" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "¥Í¥Ã¥È¥ï¡¼¥¯" + +#: gtk/interface.c:1225 +#, fuzzy +msgid "Playback sound device:" +msgstr "»ÈÍѤ¹¤ë¥µ¥¦¥ó¥É¥Ç¥Ð¥¤¥¹" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "¥Þ¥¤¥¯ÆþÎÏ" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "¥é¥¤¥óÆþÎÏ" + +#: gtk/interface.c:1250 +#, fuzzy +msgid "Capture sound device:" +msgstr "»ÈÍѤ¹¤ë¥µ¥¦¥ó¥É¥Ç¥Ð¥¤¥¹" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Ï¿²»¤¹¤ë²»¸»" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "»ÈÍѤ¹¤ë¥µ¥¦¥ó¥É¥Ç¥Ð¥¤¥¹" + +#: gtk/interface.c:1285 +#, fuzzy +msgid "Ring sound:" +msgstr "Ï¿²»¤¹¤ë²»¸»" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "¥µ¥¦¥ó¥É¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#: gtk/interface.c:1347 +#, fuzzy +msgid "Sound device" +msgstr "»ÈÍѤ¹¤ë¥µ¥¦¥ó¥É¥Ç¥Ð¥¤¥¹" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "SIP¥æ¡¼¥¶¡¼¥¨¡¼¥¸¥§¥ó¥È¤¬µ¯Æ°¤¹¤ë¥Ý¡¼¥È" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "5060È֥ݡ¼¥È¤ò»È¤¦¤³¤È¤ò¶¯¤¯¿ä¾©¤·¤Þ¤¹¡£" + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP¤Î¥Ý¡¼¥È" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "¤¢¤Ê¤¿¤ÎSIP¥¢¥É¥ì¥¹" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "¸Ä¿Í¾ðÊó" + +#: gtk/interface.c:1467 +#, fuzzy +msgid "Add proxy/registrar" +msgstr "SIP¥ì¥¸¥¹¥È¥é¤ò»È¤¦" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "ºï½ü¤¹¤ë" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "¥ê¥â¡¼¥È¤Î¥µ¡¼¥Ó¥¹" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" + +#: gtk/interface.c:1547 +#, fuzzy +msgid "Authentication information" +msgstr "¥³¡¼¥Ç¥Ã¥¯¤Î¾ðÊó" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "¥³¡¼¥Ç¥Ã¥¯¤Î¥ê¥¹¥È¤Ç¤¹¡£»È¤¤¤¿¤¤½ç¤Ëʤ٤Ƥ¯¤À¤µ¤¤¡£" + +#: gtk/interface.c:1595 +#, fuzzy +msgid "Audio codecs" +msgstr "¥ª¡¼¥Ç¥£¥ª¥³¡¼¥Ç¥Ã¥¯¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "¥ª¡¼¥Ç¥£¥ª¥³¡¼¥Ç¥Ã¥¯¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "»ÈÍѤ¹¤ë" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "»ÈÍѤ·¤Ê¤¤" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "Ãí°Õ:ÀÖ¤¤¿§¤Î¥³¡¼¥Ç¥Ã¥¯¤Ï¡¢¸½ºß¤Î¥Í¥Ã¥È¥ï¡¼¥¯ÀܳÊýË¡¤Ç¤Ï»È¤¨¤Þ¤»¤ó¡£" + +#: gtk/interface.c:1720 +#, fuzzy +msgid "No information availlable" +msgstr "ÆÃ¤Ë¾ðÊó¤Ï¤¢¤ê¤Þ¤»¤ó" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "¥³¡¼¥Ç¥Ã¥¯¤Î¾ðÊó" + +#: gtk/interface.c:1731 +#, fuzzy +msgid "Audio and video codecs" +msgstr "¥ª¡¼¥Ç¥£¥ª¥³¡¼¥Ç¥Ã¥¯¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "¥³¡¼¥Ç¥Ã¥¯" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "ÅÅÏÃÄ¢" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "ÁªÂò¤¹¤ë" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "¾ðÊó" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"¥æ¡¼¥¶¡¼¤ËÀܳ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤¬¡¢¥æ¡¼¥¶¡¼¤ÏÂå¤ï¤ê¤Î¼êÃʤ˾·ÂÔ¤·¤Æ¤¤¤Þ" +"¤¹¡£Â¾¤Î¼êÃʤÇÏ¢Íí¤ò¤È¤Ã¤Æ¤¯¤À¤µ¤¤¡£" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "¤¢¤ê¤Þ¤»¤ó¡£" + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "" + +#: gtk/interface.c:2344 +#, fuzzy +msgid "SIP Identity:" +msgstr "¸Ä¿Í¾ðÊó" + +#: gtk/interface.c:2359 +#, fuzzy +msgid "Registration Period:" +msgstr "ÅÐÏ¿¤·¤Þ¤·¤¿¡£" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "" + +#: gtk/interface.c:2381 +#, fuzzy +msgid "Publish presence information:" +msgstr "¥³¡¼¥Ç¥Ã¥¯¤Î¾ðÊó" + +#: gtk/interface.c:2466 +#, fuzzy +msgid "Edit contact information" +msgstr "(Àܳ¤¹¤ë¤¿¤á¤Î¾ðÊ󤬤¢¤ê¤Þ¤»¤ó!)" + +#: gtk/interface.c:2505 +#, fuzzy +msgid "Name:" +msgstr "̾Á°" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +#, fuzzy +msgid "Contact information" +msgstr "¥³¡¼¥Ç¥Ã¥¯¤Î¾ðÊó" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +#, fuzzy +msgid "password:" +msgstr "¥Ñ¥¹¥ï¡¼¥É" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "pixmap¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "»ÈÍѤ¹¤ë" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "»ÈÍѤ·¤Ê¤¤" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "̾Á°" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "¾õÂÖ" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "ºÇÄã¸Â¤Î¥Ó¥Ã¥È¥ì¡¼¥È (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +#, fuzzy +msgid "None" +msgstr "¤¢¤ê¤Þ¤»¤ó¡£" + +#: gtk/friends.c:117 +#, fuzzy +msgid "Presence status" +msgstr "¾õÂÖ" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +#, fuzzy +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"SIP¥¢¥É¥ì¥¹¤Î·Á¼°¥¨¥é¡¼¤Ç¤¹¡£SIP¥¢¥É¥ì¥¹¤Ï¡¢¤Î¤è¤¦¤Ê" +"·Á¼°¤Ç¤¹¡£" + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "ÀÜÂ³Ãæ" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" + +#: coreapi/linphonecore.c:692 +#, fuzzy +msgid "Ready" +msgstr "½àÈ÷´°Î»¡£" + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "" + +#: coreapi/linphonecore.c:1138 +#, fuzzy +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"SIP¥¢¥É¥ì¥¹¤Î·Á¼°¥¨¥é¡¼¤Ç¤¹¡£SIP¥¢¥É¥ì¥¹¤Ï¡¢¤Î¤è¤¦¤Ê" +"·Á¼°¤Ç¤¹¡£" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "ÀÜÂ³Ãæ" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Àܳ¤·¤Þ¤·¤¿¡£" + +#: coreapi/linphonecore.c:1550 +#, fuzzy +msgid "Call ended" +msgstr "ÄÌÏäϵñÈݤµ¤ì¤Þ¤·¤¿¡£" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤ÏALSA¥µ¥¦¥ó¥É¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ·¤Æ¤¤¤ë¤è¤¦¤Ç¤¹¡£\n" +"¤½¤ì¤ÏºÇÎɤÎÁªÂò¤Ç¤¹¡£¤·¤«¤·¡¢Linphone¤¬É¬ÍפȤ¹¤ë\n" +"pcm oss¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó¥â¥¸¥å¡¼¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£\n" +"¥í¡¼¥É¤¹¤ë¤¿¤á¤Ë¡¢¥ë¡¼¥È¸¢¸Â¤Ç'modprobe snd-pcm-oss'¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£" + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤ÏALSA¥µ¥¦¥ó¥É¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ·¤Æ¤¤¤ë¤è¤¦¤Ç¤¹¡£\n" +"¤½¤ì¤ÏºÇÎɤÎÁªÂò¤Ç¤¹¡£¤·¤«¤·¡¢Linphone¤¬É¬ÍפȤ¹¤ë\n" +"mixer oss¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó¥â¥¸¥å¡¼¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£\n" +"¥í¡¼¥É¤¹¤ë¤¿¤á¤Ë¡¢¥ë¡¼¥È¸¢¸Â¤Ç'modprobe snd-mixer-oss'¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£" + +#: coreapi/exevents.c:115 +#, fuzzy +msgid "Call terminated." +msgstr "ÄÌÏäϵñÈݤµ¤ì¤Þ¤·¤¿¡£" + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "¥æ¡¼¥¶¡¼¤Ï¥Ó¥¸¡¼¤Ç¤¹" + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "¥æ¡¼¥¶¡¼¤Ï¡¢º£½Ð¤é¤ì¤Þ¤»¤ó¡£" + +#: coreapi/exevents.c:148 +#, fuzzy +msgid "Request Cancelled." +msgstr "ÄÌÏäϥ­¥ã¥ó¥»¥ë¤µ¤ì¤Þ¤·¤¿¡£" + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "¥æ¡¼¥¶¡¼¤Ï¼ê¤¬Î¥¤»¤Ê¤¤¤è¤¦¤Ç¤¹¡£" + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "ÄÌÏäϵñÈݤµ¤ì¤Þ¤·¤¿¡£" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "¥æ¡¼¥¶¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£" + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Áê¼ê¦¤Ç¤Ï¡¢Ä󰯤·¤¿¥³¡¼¥Ç¥Ã¥¯¤ò°ì¤Ä¤â¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£" + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "»þ´ÖÀÚ¤ì¤Ç¤¹¡£" + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "¥ê¥â¡¼¥È¥Û¥¹¥È¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿¤¬¡¢Àܳ¤òµñÈݤµ¤ì¤Þ¤·¤¿¡£" + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "¤«¤éÅÅÏäǤ¹¡£" + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"¥æ¡¼¥¶¡¼¤ËÀܳ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤¬¡¢¥æ¡¼¥¶¡¼¤ÏÂå¤ï¤ê¤Î¼êÃʤ˾·ÂÔ¤·¤Æ¤¤¤Þ" +"¤¹¡£\n" +"¾¤Î¼êÃʤÇÏ¢Íí¤ò¤È¤Ã¤Æ¤¯¤À¤µ¤¤¡£" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "ÅÐÏ¿¤·¤Þ¤·¤¿¡£" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "ÅÐÏ¿¤·¤Þ¤·¤¿¡£" + +#: coreapi/presence.c:112 coreapi/presence.c:164 +#, fuzzy +msgid "Gone" +msgstr "¤¢¤ê¤Þ¤»¤ó¡£" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "¥é¥¤¥óÆþÎÏ" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "¥æ¡¼¥¶¡¼¥Þ¥Ë¥å¥¢¥ë" + +#~ msgid "Communication ended." +#~ msgstr "²ñÏäϽªÎ»¤·¤Þ¤·¤¿¡£" + +#~ msgid "Call cancelled." +#~ msgstr "ÄÌÏäϥ­¥ã¥ó¥»¥ë¤µ¤ì¤Þ¤·¤¿¡£" + +#~ msgid "Address" +#~ msgstr "¥¢¥É¥ì¥¹" + +#, fuzzy +#~ msgid "Server address" +#~ msgstr "¥µ¡¼¥Ð¡¼¤Î¥¢¥É¥ì¥¹" + +#~ msgid "28k modem" +#~ msgstr "28k¤Î¥â¥Ç¥à" + +#~ msgid "56k modem" +#~ msgstr "56k¤Î¥â¥Ç¥à" + +#~ msgid "64k modem (numeris)" +#~ msgstr "64K¤Î¥â¥Ç¥à(ISDN)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL¡¦CATV¥â¥Ç¥à" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "¥¤¡¼¥µ¥Í¥Ã¥È¤Ê¤É" + +#~ msgid "Connection type:" +#~ msgstr "Àܳ¤Î¥¿¥¤¥×" + +#, fuzzy +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone¤Ï¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£¥µ¥¦¥ó¥É¥«¡¼¥É¤ÎÀß" +#~ "Ä꤬´°Á´¤Ç¡¢Àµ¤·¤¯Æ°¤¤¤Æ¤¤¤ë¤«¤É¤¦¤«³Îǧ¤·¤Æ²¼¤µ¤¤¡£" + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "ÅÅÏäò¤«¤±¤¿¤¤Áê¼ê¤ÎSIP¥¢¥É¥ì¥¹¤òÆþÎϤ·¤Æ²¼¤µ¤¤¡£" + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "ÅÅÏäòÀÚ¤ë\n" +#~ "²ñÏäòµñÈÝ" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s¡£%i ʬ¸å¤Ë¤«¤±Ä¾¤·¤Æ²¼¤µ¤¤¡£" + +#, fuzzy +#~ msgid "Timeout..." +#~ msgstr "»þ´ÖÀÚ¤ì¤Ç¤¹¡£" + +#~ msgid "Connection" +#~ msgstr "¥³¥Í¥¯¥·¥ç¥ó" + +#, fuzzy +#~ msgid "" +#~ "Add address\n" +#~ "book" +#~ msgstr "ÅÅÏÃÄ¢" + +#~ msgid "Toggle this if you want to be registered on a remote server." +#~ msgstr "¥ê¥â¡¼¥È¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤ë¤È¤­¤Ï¡¢¥Á¥§¥Ã¥¯¤·¤Æ²¼¤µ¤¤¡£" + +#~ msgid "Address of record:" +#~ msgstr "ÅÐÏ¿¤¹¤ë¥¢¥É¥ì¥¹" + +#~ msgid "" +#~ "The password used for registration. On some servers it is not necessary" +#~ msgstr "ÅÐÏ¿¤Ë¥Ñ¥¹¥ï¡¼¥É¤òÍѤ¤¤Þ¤¹¡£É¬¿Ü¤Ç¤Ê¤¤¥µ¡¼¥Ð¡¼¤â¤¢¤ê¤Þ¤¹¡£" + +#~ msgid "Use this registrar server as outbound proxy." +#~ msgstr "¥ì¥¸¥¹¥È¥é¥µ¡¼¥Ð¡¼¤ò¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤È¤·¤Æ»ÈÍѤ·¤Þ¤¹¡£" + +#~ msgid "sip address:" +#~ msgstr "SIP¥¢¥É¥ì¥¹" + +#~ msgid "Display name:" +#~ msgstr "ɽ¼¨¤µ¤ì¤ë̾Á°" + +#~ msgid "Modify" +#~ msgstr "½¤Àµ" + +#~ msgid "Registering..." +#~ msgstr "ÅÐÏ¿Ãæ¡Ä¡Ä" + +#, fuzzy +#~ msgid "" +#~ "You are currently using the i810_audio driver.\n" +#~ "This driver is buggy and so does not work with Linphone.\n" +#~ "We suggest that you replace it by its equivalent ALSA driver,\n" +#~ "either with packages from your distribution, or by downloading\n" +#~ "ALSA drivers at http://www.alsa-project.org." +#~ msgstr "" +#~ "¸½ºß¡¢i810¥ª¡¼¥Ç¥£¥ª¥É¥é¥¤¥Ð¡¼¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£\n" +#~ "¤³¤Î¥É¥é¥¤¥Ð¡¼¤Ë¤Ï¥Ð¥°¤¬¤¢¤ê¡¢Linphone¤Ç¤Ï¤¦¤Þ¤¯Æ°ºî¤·¤Þ¤»¤ó¡£\n" +#~ "ALSA¥É¥é¥¤¥Ð¡¼¤ËÁêÅö¤¹¤ë\n" +#~ "¤¢¤Ê¤¿¤Î¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥¸¥ç¥ó¤Î¥Ñ¥Ã¥±¡¼¥¸¤«¡¢\n" +#~ "ALSA¥É¥é¥¤¥Ð¡¼(http://www.alsa-project.org)¤Ø¤Î¸ò´¹¤ò¿ä¾©¤·¤Þ¤¹¡£" + +#~ msgid "Unregistration successfull." +#~ msgstr "ÅÐÏ¿¤ò²ò½ü¤·¤Þ¤·¤¿¡£" + +#~ msgid "3" +#~ msgstr "3" + +#~ msgid "2" +#~ msgstr "2" + +#~ msgid "4" +#~ msgstr "4" + +#~ msgid "6" +#~ msgstr "6" + +#~ msgid "7" +#~ msgstr "7" + +#~ msgid "8" +#~ msgstr "8" + +#~ msgid "9" +#~ msgstr "9" + +#~ msgid "Select network interface to use:" +#~ msgstr "»ÈÍѤ¹¤ë¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ó¤Ç²¼¤µ¤¤" + +#~ msgid "Network interface properties" +#~ msgstr "¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î¥×¥í¥Ñ¥Æ¥£¡¼" + +#~ msgid "RTP" +#~ msgstr "RTP" + +#~ msgid "Audio" +#~ msgstr "¥ª¡¼¥Ç¥£¥ª" + +#~ msgid "C: 2001" +#~ msgstr "C: 2001" + +#~ msgid "/dev/dsp" +#~ msgstr "/dev/dsp" + +#~ msgid "/dev/dsp1" +#~ msgstr "/dev/dsp1" + +#~ msgid "/dev/dsp2" +#~ msgstr "/dev/dsp2" + +#~ msgid "/dev/dsp3" +#~ msgstr "/dev/dsp3" + +#~ msgid "Add" +#~ msgstr "Äɲ乤ë" + +#~ msgid "Set the selected address in linphone'main window." +#~ msgstr "ÁªÂò¤·¤¿¥¢¥É¥ì¥¹¤¬Linphone¤Î¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤Ë¸½¤ì¤Þ¤¹¡£" diff --git a/linphone/po/linphone.pot b/linphone/po/linphone.pot new file mode 100644 index 000000000..3f01f8818 --- /dev/null +++ b/linphone/po/linphone.pot @@ -0,0 +1,930 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "" + +#: gtk/interface.c:261 +msgid "..." +msgstr "" + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "" + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "" + +#: gtk/interface.c:354 +msgid "Ring level:" +msgstr "" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "" + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" + +#: gtk/interface.c:431 +msgid "5" +msgstr "" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "" + +#: gtk/interface.c:561 +msgid "0" +msgstr "" + +#: gtk/interface.c:567 +msgid "#" +msgstr "" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "" + +#: gtk/interface.c:849 gtk/interface.c:3029 +msgid "Linphone" +msgstr "" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "" + +#: gtk/interface.c:1277 +msgid "Ring sound device" +msgstr "" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "" + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "" + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" + +#: gtk/addressbook.c:226 +msgid "Contact list" +msgstr "" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "" + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "" + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "" + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "" + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "" + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "" + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "" + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "" + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "" + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "" + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "" + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "" + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "" + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, c-format +msgid "Registration on %s failed: %s" +msgstr "" + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "" + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" diff --git a/linphone/po/nl.po b/linphone/po/nl.po new file mode 100644 index 000000000..e61ff87c9 --- /dev/null +++ b/linphone/po/nl.po @@ -0,0 +1,1062 @@ +# translation of nl.po to Nederlands +# Dutch translation of linphone. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the linphone package. +# Taco Witte , 2005. +# Hendrik-Jan Heins , 2005. +# Hendrik-Jan Heins , 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: nl\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2007-09-05 10:40+0200\n" +"Last-Translator: Hendrik-Jan Heins \n" +"Language-Team: Nederlands \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "Een Vrije SIP video-telefoon" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Ga" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Adresboek" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Oproepgeschiedenis" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Oproepen weergeven" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "Einde" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "Help" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "Geef het SIP adres of telefoonnummer in" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "SIP-adres:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Het adresboek weergeven" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Te gebruiken proxy:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Oproepen of\n" +"beantwoorden" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"Ophangen\n" +"of weigeren" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Of chat!" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Meer weergeven..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Geluidssterkte afspelen:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Geluidssterkte opname:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Geluidssterkte opname:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Geluid" + +#: gtk/interface.c:382 +msgid "Enable video" +msgstr "Video aan" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "Video" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "Functies" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Bereikbaar" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Bezig; ik ben terug over " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" +"De andere partij zal worden geïnformeerd dat u over X minuten terug bent" + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Afwezig" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Niet storen" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Tijdelijk verplaatst" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Alternatieve dienst" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Aanwezigheid" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Druk op de cijfers om DTMF's te sturen" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" +" 3\n" +"def" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" +" 2\n" +"abc" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" +" 4\n" +"ghi" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" +" 5\n" +"jkl" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" +" 6\n" +"mno" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" +" 7\n" +"pqrs" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" +" 8\n" +"tuv" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" +" 9\n" +"wxyz" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Mijn online vrienden" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"C: 2001\n" +"Gemaakt in antiek Europa" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone is een webtelefoon.\n" +"Het werkt met de SIP- en RTP-protocollen." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "http://www.linphone.org" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parameters" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "Gebruik IPv6 netwerk (wanneer het beschikbaar is)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Wijzig dit wanneer u op een IPv6 netwerk zit en linphone daarop wilt " +"gebruiken." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "Globaal" + +#: gtk/interface.c:1081 +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Deze optie is alleen voor gebruikers in een lokaal netwerk, achter een " +"gateway: Wanneer u niet in deze situatie zit, laat dit dan leeg." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "Geen firewall" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "Gebruik deze STUN server om het firewall adres te achterhalen" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "Geef het firewall adres handmatig op" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "NAT-doorstuur opties (experimenteel)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Aantal gebufferde miliseconden (jitter compensatie):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "RTP-poort voor geluid:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP-eigenschappen" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "Gebruik SIP INFO bericht in plaats van RTP rfc2833 voor DTMF berichten" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 is de aanbevolen manier." + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Overige" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Netwerk" + +#: gtk/interface.c:1225 +#, fuzzy +msgid "Playback sound device:" +msgstr "Geluidsapparaat gebruiken:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "microfoon" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "lijn" + +#: gtk/interface.c:1250 +#, fuzzy +msgid "Capture sound device:" +msgstr "Geluidsapparaat gebruiken:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Bron voor opname:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Geluidsapparaat gebruiken:" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "Belgeluid:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" +"Activeer de echo-onderdrukking (onderdrukt de echo die de andere partij " +"hoort)" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "Kies bestand" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Luisteren" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Geluidseigenschappen" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Geluidsapparaat" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Start SIP gebruikerssysteem op poort:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Het wordt sterk aangeraden om poort 5060 te gebruiken." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP-poort" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Uw SIP-adres:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Automatisch een geldige hostnaam raden" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identiteit" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Voeg proxy/registratieserver toe" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Bewerken" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Verwijderen" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Externe diensten" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" +"Schoon alle opgeslagen authorisatie gegevens op (gebruikersnaam, " +"wachtwoord...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Authorisatie gegevens" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lijst met audio codecs, in volgorde van voorkeur:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Audio codecs" + +#: gtk/interface.c:1608 +msgid "Video Codecs" +msgstr "Video codecs" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Aan" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Uit" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "Upload bandbreedte (kbit/sec):" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "Download bandbreedte (kbit/sec):" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Opmerking: Met rood weergegeven codecs zijn niet bruikbaar vanwege het soort " +"internetverbinding dat u heeft" + +#: gtk/interface.c:1720 +#, fuzzy +msgid "No information availlable" +msgstr "Geen informatie beschikbaar" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Codec informatie" + +#: gtk/interface.c:1731 +msgid "Audio and video codecs" +msgstr "Audio en video codecs" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Codecs" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Adresboek" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Kiezen" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informatie" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"De gebruiker is op dit moment niet bereikbaar, maar hij nodigt u uit op de " +"volgende, alternatieve, manier contact met hem op te nemen:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Geen." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Proxy/registratieserver registratieveld" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Route (optioneel):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "SIP-proxy:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "SIP-identiteit:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Registratieperiode:" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Verstruur registratie:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Toon informatie over aanwezigheid:" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Bewerk contactgegevens" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Naam:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Aanmeldbeleid:" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Verstruur aanmelding (bekijk de online status van een persoon)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Contact informatie" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Nieuwe inkomende aanmelding" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "U heeft een nieuwe aanmelding ontvangen..." + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Weigeren" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Accepteren" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Authorisatie gevraagd" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "Authorisatie benodigd voor gebied" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "gebruikersID:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "wachtwoord:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "gebruikersnaam:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "gebied:" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - Oproepgeschiedenis" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Chat box" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Tekst:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Chat met %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Kon pixmap bestand %s niet vinden" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "Account" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Aan" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Uit" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Naam" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Frequentie (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Status" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Minimale bitrate (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "Ongelimiteerd" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "De beller vraagt om reservering van bronnen. Gaat u accoord?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"De beller gebruikt geen bron reservatie. \t\t\t\t\tWilt u toch doorgaan?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "Linphone - binnenkomend gesprek van %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"U heeft een aanmelding ontvangen van %s. Dit betekent dat deze persoon een " +"melding wil ontvangen wat betreft uw status (online, bezig, weg...).\n" +"Gaat u accoord?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Authorisatie benodigd voor gebied %s" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Geen" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Aanwezigheidsstatus" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "Wachten" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "Weigeren" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"Slecht geformuleerd SIP-adres. Een SIP-adres ziet er uit als sip:" +"gebruikersnaam@domeinnaam" + +#: gtk/addressbook.c:226 +msgid "Contact list" +msgstr "Contactlijst" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "U heeft %i oproep(en) gemist." + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "afgebroken" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "voltooid" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "gemist" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s op %s\n" +"Van: %s\n" +"Aan: %s\n" +"Status: %s\n" +"Tijdsduur: %i mins %i secs\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Inkomende oproep" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Uitgaande oproep" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Uw machine lijkt verbonden te zijn met een IPv6 netwerk. Standaard gebruikt " +"linphone altijd IPv4. Wijzig uw configuratie wanneer u IPv6 wilt gebruiken." + +#: coreapi/linphonecore.c:692 +msgid "Ready" +msgstr "Gereed." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "STUN adres wordt opgezocht..." + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "STUN adres gevonden..." + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Zoekt de lokatie van het telefoonnummer..." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Kon dit nummer niet vinden." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Slecht geformuleerd SIP-adres. Een SIP-adres ziet er uit als sip:" +"gebruikersnaam@domeinnaam" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "Helaas, meerdere gelijktijdige gesprekken wordt nog niet ondersteund!" + +#: coreapi/linphonecore.c:1198 +msgid "Contacting" +msgstr "Verbinden" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "Kon niet oproepen" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Verbonden." + +#: coreapi/linphonecore.c:1550 +msgid "Call ended" +msgstr "Oproep beeindigd" + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "Geen NAT/firewall adres opgegeven" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "Ongeldig NAT adres '%s' : %s" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Uw computer maakt schijnbaar gebruik van ALSA geluidsdrivers.\n" +"Dit is de beste keuze. Maar de pcm oss emulatie module mist\n" +"en linphone heeft deze nodig. Geeft u alstublieft het commando\n" +"'modprobe snd-pcm-oss' als root om de module te laden." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Uw computer maakt schijnbaar gebruik van ALSA geluidsdrivers.\n" +"Dit is de beste keuze. Maar de mixer oss emulatie module mist\n" +"en linphone heeft deze nodig. Geeft u alstublieft het commando\n" +"'modprobe snd-mixer-oss' als root om de module te laden." + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "Oproep beeindigd." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Kon bestemming niet bereiken." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Gebruiker is bezet." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Gebruiker is tijdelijk niet beschikbaar." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Verzoek geannuleerd." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "De gebruiker wenst niet gestoord te worden." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Oproep geweigerd." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Slecht geformuleerd verzoek" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Gebruiker kan niet worden gevonden bij opgegeven adres." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "De externe gebruiker ondersteunt geen van de voorgestelde codecs." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Time-out." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Externe machine is gevonden, maar verbinding is geweigerd." + +#: coreapi/exevents.c:312 +msgid "is contacting you." +msgstr "belt u." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Doorgeschakeld naar %s..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"De gebruiker is op dit moment niet bereikbaar, maar hij nodigt u uit om\n" +"op de volgende, alternatieve, manier contact met hem op te nemen:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Registratie op %s mislukt (time-out)." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, c-format +msgid "Registration on %s successful." +msgstr "Registratie op %s gelukt." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +msgid "Gone" +msgstr "Weg" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "Wachten op accoord" + +#: coreapi/presence.c:133 +msgid "Online" +msgstr "Aanwezig" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "Bezet" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "Kom zo terug" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "Aan de telefoon" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "Aan het lunchen" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "Gesloten" + +#~ msgid "User manual" +#~ msgstr "Handleiding" + +#~ msgid "Ring sound selection" +#~ msgstr "Belgeluid keuze" + +#~ msgid "Communication ended." +#~ msgstr "Communicatie beëindigd." + +#~ msgid "Call cancelled." +#~ msgstr "Oproep geannuleerd." + +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Extern IP adres van de firewall (in x.x.x.x notatie):" + +#~ msgid "Index" +#~ msgstr "Index" + +#~ msgid "Address" +#~ msgstr "Adres" + +#~ msgid "Server address" +#~ msgstr "Serveradres" + +#~ msgid "28k modem" +#~ msgstr "28k modem" + +#~ msgid "56k modem" +#~ msgstr "56k modem" + +#~ msgid "64k modem (numeris)" +#~ msgstr "64k modem (ISDN)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL- of kabelmodem" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet of vergelijkbaar" + +#~ msgid "Connection type:" +#~ msgstr "Soort verbinding:" + +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone kon het geluidsapparaat %s niet openen. Controleer of uw " +#~ "geluidskaart goed is ingesteld en werkt." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Geef hier het SIP-adres op van de persoon die u wilt bellen." + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "Ophangen\n" +#~ "of weigeren" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s. Opnieuw proberen na %i minu(u)t(en)." diff --git a/linphone/po/pl.po b/linphone/po/pl.po new file mode 100644 index 000000000..7027ffc7f --- /dev/null +++ b/linphone/po/pl.po @@ -0,0 +1,1122 @@ +# SIP Telephony Application. +# Copyright (C) 2001, 2002 Free Software Foundation, Inc. +# Simon Morlat , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: linphone 0.7.1\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2003-08-22 12:50+0200\n" +"Last-Translator: Robert Nasiadek \n" +"Language-Team: Polski \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Książka adresowa" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "" + +#: gtk/interface.c:188 +msgid "Exit" +msgstr "" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +#, fuzzy +msgid "Enter sip address or phone number here" +msgstr "Adres serwera rejestracji sip" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Adres sip:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Pokazuje książkÄ™ adresowÄ…" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "" + +#: gtk/interface.c:278 +#, fuzzy +msgid "" +"Call or\n" +"answer" +msgstr "" +"ZadzwoÅ„ lub\n" +"Odpowiedz" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Pokaż wiÄ™cej" + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Poziom odtwarzania:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Poziom nagrywania:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Poziom nagrywania:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "DźwiÄ™k" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "Włączone" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "DostÄ™pny" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "ZajÄ™ty, wrócÄ™ za " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "Osoba zostanie powiadomiona, że wrócisz za X minut." + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "mn" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "ZajÄ™ty" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Nie przeszkadzać" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Tymczasowo niedostÄ™pny" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Alternatywny adres" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Obecność" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Nacisnij cyfry, aby wysÅ‚ać DTMFy." + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone jest telefonem internetowym.\n" +"Jest kompatybilny z protokolami SIP i RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parametr" + +#: gtk/interface.c:1061 +#, fuzzy +msgid "Use IPv6 network (if available)" +msgstr "Osoba jest tymczasowo niedostÄ™pna." + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +#, fuzzy +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Ta opcja jest tylko dla osób w sieci prywatnej, znajdujÄ…cych siÄ™ za " +"firewallem. Jeżeli nie jesteÅ› w takiej sytuacji, nie zmieniaj tej opcji." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "Opcje NAT traversal (eksperymentalne)" + +#: gtk/interface.c:1156 +#, fuzzy +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Czas bufora w milisekundach (kompensacja jitter):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "Port RTP dla dźwiÄ™ku:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "WÅ‚aÅ›ciwoÅ›ci RTP" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "" + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Sieć" + +#: gtk/interface.c:1225 +#, fuzzy +msgid "Playback sound device:" +msgstr "Użyj tego urzÄ…dzenia dźwiÄ™ku:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "mikrofon" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "linia" + +#: gtk/interface.c:1250 +#, fuzzy +msgid "Capture sound device:" +msgstr "Użyj tego urzÄ…dzenia dźwiÄ™ku:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "ŹródÅ‚o nagrywania:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Użyj tego urzÄ…dzenia dźwiÄ™ku:" + +#: gtk/interface.c:1285 +#, fuzzy +msgid "Ring sound:" +msgstr "ŹródÅ‚o nagrywania:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "WÅ‚aÅ›ciwoÅ›ci dźwiÄ™ku" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "DźwiÄ™k" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Uruchom agenta sip na porcie:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Rekomendowane jest użycie portu 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "Port SIP" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Twój adres sip:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Tożsamość" + +#: gtk/interface.c:1467 +#, fuzzy +msgid "Add proxy/registrar" +msgstr "Użyj rejestracji sip" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Zdalne usÅ‚ugi" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" + +#: gtk/interface.c:1547 +#, fuzzy +msgid "Authentication information" +msgstr "Informacje o kodeku" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lista kodeków audio, w kolejnoÅ›ci preferencji:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Kodeki audio" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "Kodeki audio" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Włączony" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Wyłącz" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Uwaga: Czerwone kodeki nie mogÄ… być użyte, ze wzglÄ™du na typTwojego " +"połącznia z internetem." + +#: gtk/interface.c:1720 +#, fuzzy +msgid "No information availlable" +msgstr "Brak informacji" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Informacje o kodeku" + +#: gtk/interface.c:1731 +#, fuzzy +msgid "Audio and video codecs" +msgstr "Kodeki audio" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Kodeki" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Książka adresowa" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Wybierz" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informacja" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Użytkownik nie jest dostÄ™pny, ale proponuje kontakt poprzez alternatywny " +"adres:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Brak." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "" + +#: gtk/interface.c:2344 +#, fuzzy +msgid "SIP Identity:" +msgstr "Tożsamość" + +#: gtk/interface.c:2359 +#, fuzzy +msgid "Registration Period:" +msgstr "Rejestracja powiodÅ‚a siÄ™." + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "" + +#: gtk/interface.c:2381 +#, fuzzy +msgid "Publish presence information:" +msgstr "Informacje o kodeku" + +#: gtk/interface.c:2466 +#, fuzzy +msgid "Edit contact information" +msgstr "(Brak informacji kontaktowych !)" + +#: gtk/interface.c:2505 +#, fuzzy +msgid "Name:" +msgstr "Nazwa" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +#, fuzzy +msgid "Contact information" +msgstr "Informacje o kodeku" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "" + +#: gtk/interface.c:2799 +#, fuzzy +msgid "password:" +msgstr "Twoje hasÅ‚o:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Nie można znaleźć pixmapy: %s" + +#: gtk/propertybox.c:207 +msgid "Account" +msgstr "" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Włączone" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Wyłączone" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Nazwa" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Jakość (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Status" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Min przepustowość (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +#, fuzzy +msgid "None" +msgstr "Brak." + +#: gtk/friends.c:117 +#, fuzzy +msgid "Presence status" +msgstr "Obecność" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +#, fuzzy +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "Nie poprawny adres sip. Adres sip wyglÄ…da tak " + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Dzwonie do " + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "" + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "" + +#: coreapi/linphonecore.c:223 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" + +#: coreapi/linphonecore.c:692 +#, fuzzy +msgid "Ready" +msgstr "Gotowy." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "" + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "" + +#: coreapi/linphonecore.c:1138 +#, fuzzy +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "Nie poprawny adres sip. Adres sip wyglÄ…da tak " + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "Dzwonie do " + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Połączony" + +#: coreapi/linphonecore.c:1550 +#, fuzzy +msgid "Call ended" +msgstr "Rozmowa odrzucona." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Używasz sterowników ALSA do dźwiÄ™ku.\n" +"To jest najlepszy wybór. Jednak brakuje moduÅ‚u emulacji pcm oss,\n" +"a Linphone go wymaga. Uruchom 'modprobe snd-pcm-oss' jako root,\n" +"aby go zaÅ‚adować" + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Używasz sterowników ALSA do dźwiÄ™ku.\n" +"To jest najlepszy wybór. Jednak brakuje moduÅ‚u emulacji mixera oss,\n" +"a Linphone go wymaga. Uruchom 'modprobe snd-mixer-oss' jako root,\n" +"aby go zaÅ‚adować" + +#: coreapi/exevents.c:115 +#, fuzzy +msgid "Call terminated." +msgstr "Rozmowa odrzucona." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "" + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Osoba jest zajÄ™ta." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Osoba jest tymczasowo niedostÄ™pna." + +#: coreapi/exevents.c:148 +#, fuzzy +msgid "Request Cancelled." +msgstr "Połączenie odwoÅ‚ane." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "Osoba nie chce, aby jej przeszkadzać." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Rozmowa odrzucona." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Osoba nie istnieje pod tym adresem." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Osoba nie posiada żadnych zaproponowanych kodeków." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "UpÅ‚ynÄ…Å‚ limit czasu." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Serwer istnieje, ale odrzuciÅ‚ połączenie." + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "dzwoni do Ciebie." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "" + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Użytkownik nie jest dostÄ™pny, ale proponuje kontakt poprzez alternatywny " +"adres:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Rejestracja powiodÅ‚a siÄ™." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "Rejestracja powiodÅ‚a siÄ™." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +#, fuzzy +msgid "Gone" +msgstr "Brak." + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "linia" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "PodrÄ™cznik" + +#~ msgid "Communication ended." +#~ msgstr "Komunikacja zakoÅ„czona." + +#~ msgid "Call cancelled." +#~ msgstr "Połączenie odwoÅ‚ane." + +#, fuzzy +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Adres IP firewall'u (w notacji kropkowej):" + +#~ msgid "Index" +#~ msgstr "Indeks" + +#~ msgid "Address" +#~ msgstr "Adres" + +#, fuzzy +#~ msgid "Server address" +#~ msgstr "Adres serwera:" + +#~ msgid "28k modem" +#~ msgstr "Modem 28K" + +#~ msgid "56k modem" +#~ msgstr "Modem 56K" + +#~ msgid "64k modem (numeris)" +#~ msgstr "Modem ISDN 64K" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL lub połączenie kablowe" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "LAN lub podobne" + +#~ msgid "Connection type:" +#~ msgstr "Typ połączenia:" + +#, fuzzy +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone nie mógÅ‚ otworzyć urzÄ…dzenia dźwiÄ™ku. Sprawdź czy Twoja karta " +#~ "jest dobrze skonfigurowana." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Tutaj wpisz adres sip osoby, do której chcesz zadzwonić" + +#~ msgid "" +#~ "Release or\n" +#~ "Refuse" +#~ msgstr "" +#~ "Rozłącz lub\n" +#~ "Odmów" + +#~ msgid "%s. Retry after %i minute(s)." +#~ msgstr "%s. Spróbuj za %i minut." + +#, fuzzy +#~ msgid "Timeout..." +#~ msgstr "UpÅ‚ynÄ…Å‚ limit czasu." + +#~ msgid "Connection" +#~ msgstr "LÄ…cze" + +#, fuzzy +#~ msgid "" +#~ "Add address\n" +#~ "book" +#~ msgstr "Książka adresowa" + +#~ msgid "Toggle this if you want to be registered on a remote server." +#~ msgstr "Włącz to, jeżeli chcesz siÄ™ zarejestrować na zdalnym serwerze." + +#~ msgid "Address of record:" +#~ msgstr "Adres do rejestracji:" + +#~ msgid "" +#~ "The password used for registration. On some servers it is not necessary" +#~ msgstr "HasÅ‚o do rejestracji. Na niektórych serwerach nie jest wymagane" + +#~ msgid "Use this registrar server as outbound proxy." +#~ msgstr "Użyj tego serwera rejestracji jako zewnÄ™trznego proxy" + +#~ msgid "sip address:" +#~ msgstr "Adres SIP:" + +#~ msgid "Display name:" +#~ msgstr "WyÅ›wietlana nazwa:" + +#~ msgid "Modify" +#~ msgstr "ZmieÅ„" + +#~ msgid "Registering..." +#~ msgstr "Rejestruje..." + +#~ msgid "" +#~ "You are currently using the i810_audio driver.\n" +#~ "This driver is buggy and so does not work with Linphone.\n" +#~ "We suggest that you replace it by its equivalent ALSA driver,\n" +#~ "either with packages from your distribution, or by downloading\n" +#~ "ALSA drivers at http://www.alsa-project.org." +#~ msgstr "" +#~ "Używasz sterownika i810_audio.\n" +#~ "Ten sterownik ma błędy i nie dziaÅ‚a z Linphone\n" +#~ "Sugerujemy zmiane sterowników na ich odpowiedniki ALSA z pakietów Twojej " +#~ "dystrybucji,\n" +#~ "lub ze strony http://www.alsa-project.org/." + +#~ msgid "Unregistration successfull." +#~ msgstr "Derejestracja powiodÅ‚a siÄ™." + +#~ msgid "3" +#~ msgstr "3" + +#~ msgid "2" +#~ msgstr "2" + +#~ msgid "4" +#~ msgstr "4" + +#~ msgid "6" +#~ msgstr "6" + +#~ msgid "7" +#~ msgstr "7" + +#~ msgid "8" +#~ msgstr "8" + +#~ msgid "9" +#~ msgstr "9" diff --git a/linphone/po/pt_BR.po b/linphone/po/pt_BR.po new file mode 100644 index 000000000..518f0fee0 --- /dev/null +++ b/linphone/po/pt_BR.po @@ -0,0 +1,1012 @@ +# Portuguese translations for gnomebaker package. +# Copyright (C) 2005 THE linphone COPYRIGHT HOLDER +# This file is distributed under the same license as the linphone package. +# Rafael Caesar Lenzi , 2005. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: linphone-1.1.0\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2006-07-11 23:30+0200\n" +"Last-Translator: Rafael Caesar Lenzi \n" +"Language-Team: pt_BR \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Ir" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Catálogo de endereços" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Histórico de chamadas" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Exibir chamadas" + +#: gtk/interface.c:188 +#, fuzzy +msgid "Exit" +msgstr "Editar" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "Endereço sip:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Exibe o catálogo de endereços" + +#: gtk/interface.c:261 +msgid "..." +msgstr "" + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Proxy à usar:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Ligar ou\n" +"atender" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +"Desligar\n" +"ou recusar" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Ou bate-papo!" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Exibir mais..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Volume do auto-falante:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Volume do microfone:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Volume do microfone:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Som" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "Ativado" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Ocupado, volto em " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" + +#: gtk/interface.c:431 +msgid "5" +msgstr "" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Ocupado" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Não perturbe" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Movido temporáriamente" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Serviço alternativo" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Presença" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" + +#: gtk/interface.c:513 +msgid "1" +msgstr "" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" + +#: gtk/interface.c:555 +msgid "*" +msgstr "" + +#: gtk/interface.c:561 +msgid "0" +msgstr "" + +#: gtk/interface.c:567 +msgid "#" +msgstr "" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Meus amigos online" + +#: gtk/interface.c:849 gtk/interface.c:3029 +msgid "Linphone" +msgstr "" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone é um web-fone.\n" +"Ele é compatível com os protocolos SIP e RTP." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parâmetros" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "Usar rede IPv6 (se disponível)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Marque isto se você estiver em uma rede IPv6, e deseja que o linphone este " +"protocolo." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "" + +#: gtk/interface.c:1081 +#, fuzzy +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Esta opção é somente para usuários de uma rede privada, atrás de um gateway. " +"Se você não está nesta situação, deixe isto em braco." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "Opções de NAT(Experimental)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Número de segundos em bueffer:" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "Porta RTP usada para audio:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "Propriedades RTP:" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "Usar mensagem SIP INFO em vez de RTP rfc2833 para transmissão de DTMF" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 é a maneira recomendada." + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Outro" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Rede" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Dispositivo de som:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "microfone" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "linha" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "Dispositivo de captura de som:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Origem de gravação:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Dispositivo de som" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "Som do toque:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Escutar" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Propriedades de som" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Dispositivo de som" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Executar agente sip na porta:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "É altamente recomendavel usar a porta 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "Porta SIP" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Seu endereço SIP:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Adquirir automaticamente um nome de servidor válido." + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identificação" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Adicionar proxy/registrador" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Editar" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Remover" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Serviços remotos" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "" +"Limpar todas as informações de autenticação (nomes de usuário, senha...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Informações de autenticação" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lista de codecs de audio, em ordem de preferência:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Codec's de áudio" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "Codec's de áudio" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Ativado" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Desativar" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Informações não disponíveis" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Informações sobre o codec" + +#: gtk/interface.c:1731 +#, fuzzy +msgid "Audio and video codecs" +msgstr "Codec's de áudio" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Catálogo de endereços" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Selecionar" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Informações" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Nenhum" + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Configuração de proxy/registrador" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Rota (opcional):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "Proxy SIP:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "Identificação SIP:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Período do registo:" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Enviar registro:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Informar informação de presença" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Edicar informação de contato" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Nome:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Informação de contato" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "" + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Recusar" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Aceitar" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Autenticação requerida" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "Identificação:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "Senha:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "Usuário" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - Histórico de chamadas" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Sala de bate-papo" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Texto:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Bate-papo com %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Não é possível achar arquivo pixmap: %s" + +#: gtk/propertybox.c:207 +#, fuzzy +msgid "Account" +msgstr "Aceitar" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Ativado" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Desativado" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Nome" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Taxa (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Bitrate mínimo (kbits/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "Linphone - Recebendo chamada de %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Nenhum" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Status de presença" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Contatando " + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "Você perdeu %i ligação(ões)." + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "Abortado" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "Competado" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "Perdido" + +#: coreapi/linphonecore.c:223 +#, fuzzy, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s em %sDe: %s\n" +"Para: %s\n" +"Status: %s\n" +"Duração: %i min %i seg\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Camadas recebidas" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Chamadas efetuadas" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Sua máquina aparentemente está conectada em uma rede IPv6. Por padrão o " +"linphone sempre usa IPv4. Por favor atualize sua configuração se deseja usar " +"IPv6" + +#: coreapi/linphonecore.c:692 +#, fuzzy +msgid "Ready" +msgstr "Pronto." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Procurando por telefone de destino..." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Não foi possível encontrar este número." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "Contatando " + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Conectado." + +#: coreapi/linphonecore.c:1550 +#, fuzzy +msgid "Call ended" +msgstr "Chamada cancelada." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" + +#: coreapi/exevents.c:115 +msgid "Call terminated." +msgstr "" + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Não foi possível alcançar o detino." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Usuário está ocupado." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Usuário está temporáriamente indisponível." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Pedido cancelado." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "" + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "" + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Usuário não pode ser encontrado no endereço especificado." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "" + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Tempo esgotado." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Servidor de destino encontrado, porém recusou a conexão." + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "está chamado você." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Redirecionado para %s..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Registro falhou (tempo esgotado)." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "Registro em %s efetuado." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +#, fuzzy +msgid "Gone" +msgstr "Nenhum" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "linha" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "Manual do usuário" + +#~ msgid "Ring sound selection" +#~ msgstr "Seleção de toque" + +#~ msgid "Communication ended." +#~ msgstr "Comunicação encerrada." + +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Endereço externo do firewall:" + +#~ msgid "Index" +#~ msgstr "Ãndice" + +#~ msgid "Address" +#~ msgstr "Endereço" + +#~ msgid "Server address" +#~ msgstr "Endereço do servidor" + +#~ msgid "28k modem" +#~ msgstr "Modem 28k" + +#~ msgid "56k modem" +#~ msgstr "Modem 56l" + +#~ msgid "64k modem (numeris)" +#~ msgstr "Modem 64k" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL ou Cable modem" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet ou equivalente" + +#~ msgid "Connection type:" +#~ msgstr "Tipo de conexão:" + +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone não pode abrir dispositivo de áudio %s. Verifique se sua placa " +#~ "de som está configurada e funcionando." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Escreva aqui o endereço sip da pessoa que você quer ligar." diff --git a/linphone/po/quot.sed b/linphone/po/quot.sed new file mode 100644 index 000000000..0122c4631 --- /dev/null +++ b/linphone/po/quot.sed @@ -0,0 +1,6 @@ +s/"\([^"]*\)"/“\1â€/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“â€/""/g diff --git a/linphone/po/remove-potcdate.sin b/linphone/po/remove-potcdate.sin new file mode 100644 index 000000000..2436c49e7 --- /dev/null +++ b/linphone/po/remove-potcdate.sin @@ -0,0 +1,19 @@ +# Sed script that remove the POT-Creation-Date line in the header entry +# from a POT file. +# +# The distinction between the first and the following occurrences of the +# pattern is achieved by looking at the hold space. +/^"POT-Creation-Date: .*"$/{ +x +# Test if the hold space is empty. +s/P/P/ +ta +# Yes it was empty. First occurrence. Remove the line. +g +d +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/linphone/po/sv.po b/linphone/po/sv.po new file mode 100644 index 000000000..a91d9be6b --- /dev/null +++ b/linphone/po/sv.po @@ -0,0 +1,1063 @@ +# Swedish translation of linphone. +# Copyright (C) 2005 THE linphone'S COPYRIGHT HOLDER +# This file is distributed under the same license as the linphone package. +# Daniel Nylander , 2005. +# , fuzzy +# +# +msgid "" +msgstr "" +"Project-Id-Version: linphone 1.1.0\n" +"Report-Msgid-Bugs-To: linphone-developers@nongnu.org\n" +"POT-Creation-Date: 2008-08-26 14:26+0200\n" +"PO-Revision-Date: 2005-11-23 13:51+0100\n" +"Last-Translator: Daniel Nylander \n" +"Language-Team: Swedish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: gtk/main.c:58 +msgid "A free SIP video-phone" +msgstr "" + +#: gtk/interface.c:138 +msgid "linphone" +msgstr "linphone" + +#: gtk/interface.c:155 +msgid "Go" +msgstr "Allmänt" + +#: gtk/interface.c:162 +msgid "Address book" +msgstr "Addressbok" + +#: gtk/interface.c:174 +msgid "Call history" +msgstr "Samtalshistorik" + +#: gtk/interface.c:177 +msgid "Shows calls" +msgstr "Visa samtal" + +#: gtk/interface.c:188 +#, fuzzy +msgid "Exit" +msgstr "Redigera" + +#: gtk/interface.c:196 +msgid "Help" +msgstr "" + +#: gtk/interface.c:236 +msgid "Enter sip address or phone number here" +msgstr "" + +#: gtk/interface.c:237 gtk/interface.c:1398 gtk/interface.c:2335 +#: gtk/interface.c:2357 gtk/interface.c:2497 +msgid "sip:" +msgstr "sip:" + +#: gtk/interface.c:239 gtk/interface.c:2512 +msgid "Sip address:" +msgstr "SIP-address:" + +#: gtk/interface.c:247 +msgid "Shows the address book" +msgstr "Visar addressboken" + +#: gtk/interface.c:261 +msgid "..." +msgstr "..." + +#: gtk/interface.c:269 gtk/interface.c:2519 +msgid "Proxy to use:" +msgstr "Proxy att använda:" + +#: gtk/interface.c:278 +msgid "" +"Call or\n" +"answer" +msgstr "" +"Ring eller\n" +" svara" + +#: gtk/interface.c:283 +msgid "" +"Hangup\n" +"or refuse" +msgstr "" +" Lägg på\n" +"eller vägra" + +#: gtk/interface.c:288 +msgid "Or chat !" +msgstr "Eller chatta !" + +#: gtk/interface.c:310 +msgid "Show more..." +msgstr "Visa mer..." + +#: gtk/interface.c:332 +msgid "Playback level:" +msgstr "Uppspelningsnivå:" + +#: gtk/interface.c:343 +msgid "Recording level:" +msgstr "Inspelningsnivå:" + +#: gtk/interface.c:354 +#, fuzzy +msgid "Ring level:" +msgstr "Inspelningsnivå:" + +#: gtk/interface.c:365 +msgid "Sound" +msgstr "Ljud" + +#: gtk/interface.c:382 +#, fuzzy +msgid "Enable video" +msgstr "Aktiverad" + +#: gtk/interface.c:387 +msgid "Video" +msgstr "" + +#: gtk/interface.c:392 +msgid "Controls" +msgstr "" + +#: gtk/interface.c:410 +msgid "Reachable" +msgstr "Tillgänglig" + +#: gtk/interface.c:421 +msgid "Busy, I'll be back in " +msgstr "Borta, kommer tillbaka om " + +#: gtk/interface.c:430 +msgid "The other party will be informed that you'll be back in X minutes" +msgstr "" +"Den andra parten kommer att informeras om att du är tillbaka om X minuter" + +#: gtk/interface.c:431 +msgid "5" +msgstr "5" + +#: gtk/interface.c:433 +msgid "mn" +msgstr "min" + +#: gtk/interface.c:438 coreapi/presence.c:146 +msgid "Away" +msgstr "Borta" + +#: gtk/interface.c:444 +msgid "Do not disturb" +msgstr "Stör ej" + +#: gtk/interface.c:450 +msgid "Moved temporarily" +msgstr "Flyttad temporärt" + +#: gtk/interface.c:456 +msgid "Alternative service" +msgstr "Alternativ tjänst" + +#: gtk/interface.c:466 +msgid "URL:" +msgstr "URL:" + +#: gtk/interface.c:475 +msgid "Presence" +msgstr "Närvaro" + +#: gtk/interface.c:492 +msgid "Press digits to send DTMFs." +msgstr "Tryck siffror för att skicka som DTMF" + +#: gtk/interface.c:501 +msgid "" +" 3\n" +"def" +msgstr "" +" 3\n" +"def" + +#: gtk/interface.c:507 +msgid "" +" 2\n" +"abc" +msgstr "" +" 2\n" +"abc" + +#: gtk/interface.c:513 +msgid "1" +msgstr "1" + +#: gtk/interface.c:519 +msgid "" +" 4\n" +"ghi" +msgstr "" +" 4\n" +"ghi" + +#: gtk/interface.c:525 +msgid "" +" 5\n" +"jkl" +msgstr "" +" 5\n" +"jkl" + +#: gtk/interface.c:531 +msgid "" +" 6\n" +"mno" +msgstr "" +" 6\n" +"mno" + +#: gtk/interface.c:537 +msgid "" +" 7\n" +"pqrs" +msgstr "" +" 7\n" +"pqrs" + +#: gtk/interface.c:543 +msgid "" +" 8\n" +"tuv" +msgstr "" +" 8\n" +"tuv" + +#: gtk/interface.c:549 +msgid "" +" 9\n" +"wxyz" +msgstr "" +" 9\n" +"wxyz" + +#: gtk/interface.c:555 +msgid "*" +msgstr "*" + +#: gtk/interface.c:561 +msgid "0" +msgstr "0" + +#: gtk/interface.c:567 +msgid "#" +msgstr "#" + +#: gtk/interface.c:573 +msgid "DTMF" +msgstr "DTMF" + +#: gtk/interface.c:590 +msgid "My online friends" +msgstr "Mina vänner som är online" + +#: gtk/interface.c:849 gtk/interface.c:3029 +#, fuzzy +msgid "Linphone" +msgstr "linphone" + +#: gtk/interface.c:850 gtk/interface.c:3030 +msgid "" +"C: 2001\n" +"Made in Old Europe" +msgstr "" +"C: 2001\n" +"Tillverkad i Gamla Europa" + +#: gtk/interface.c:851 gtk/interface.c:3031 +msgid "" +"Linphone is a web-phone.\n" +"It is compatible with SIP and RTP protocols." +msgstr "" +"Linphone är en webbtelefon.\n" +"Den är kompatibel med SIP och RTP-protokollen." + +#: gtk/interface.c:854 +msgid "http://www.linphone.org" +msgstr "" + +#: gtk/interface.c:1028 +msgid "Parameters" +msgstr "Parametrar" + +#: gtk/interface.c:1061 +msgid "Use IPv6 network (if available)" +msgstr "Använd IPv6-nätverk (om tillgänglig)" + +#: gtk/interface.c:1064 +msgid "" +"Toggle this if you are on an ipv6 network and you wish linphone to use it." +msgstr "" +"Aktivera denna om du är ansluten till ett IPv6-nätverk och vill att linphone " +"ska använda det." + +#: gtk/interface.c:1066 +msgid "Global" +msgstr "Global" + +#: gtk/interface.c:1081 +#, fuzzy +msgid "" +"These options is only for users in a private network, behind a gateway. If " +"you are not in this situation, then leave this empty." +msgstr "" +"Denna funktion är bara för användare i ett privat nätverk bakom en " +"förmedlingsnod. Om du inte befinner dig i denna situation bör du lämna denna " +"blank." + +#: gtk/interface.c:1091 +msgid "No firewall" +msgstr "" + +#: gtk/interface.c:1099 +msgid "Use this STUN server to guess firewall address :" +msgstr "" + +#: gtk/interface.c:1107 +msgid "Specify firewall address manually:" +msgstr "" + +#: gtk/interface.c:1127 +msgid "NAT traversal options (experimental)" +msgstr "Inställning för NAT Traversal (experimentell)" + +#: gtk/interface.c:1156 +msgid "Number of buffered miliseconds (jitter compensation):" +msgstr "Antal millisekunder för buffert (jitterkompensation):" + +#: gtk/interface.c:1164 +msgid "RTP port used for audio:" +msgstr "RTP-port som används för ljud:" + +#: gtk/interface.c:1171 +msgid "RTP properties" +msgstr "RTP-egenskaper" + +#: gtk/interface.c:1189 +msgid "Use SIP INFO message instead of RTP rfc2833 for DTMF transmitting" +msgstr "" +"Använd SIP INFO-meddelande istället för RTP rfc2833 för sändning av DTMF" + +#: gtk/interface.c:1192 +msgid "RTP-RFC2833 is the recommended way." +msgstr "RTP-RFC2833 är rekommenderat." + +#: gtk/interface.c:1194 +msgid "Other" +msgstr "Annan" + +#: gtk/interface.c:1199 +msgid "Network" +msgstr "Nätverk" + +#: gtk/interface.c:1225 +msgid "Playback sound device:" +msgstr "Ljudenhet för uppspelning:" + +#: gtk/interface.c:1240 gtk/propertybox.c:629 gtk/propertybox.c:654 +msgid "micro" +msgstr "micro" + +#: gtk/interface.c:1241 gtk/propertybox.c:632 gtk/propertybox.c:655 +msgid "line" +msgstr "line" + +#: gtk/interface.c:1250 +msgid "Capture sound device:" +msgstr "Ljudenhet för inspelning:" + +#: gtk/interface.c:1270 +msgid "Recording source:" +msgstr "Inspelningskälla:" + +#: gtk/interface.c:1277 +#, fuzzy +msgid "Ring sound device" +msgstr "Ljudenhet" + +#: gtk/interface.c:1285 +msgid "Ring sound:" +msgstr "Ringsignal:" + +#: gtk/interface.c:1305 +msgid "Enable echo-canceler (cancels the echo heard by the remote party)" +msgstr "" + +#: gtk/interface.c:1319 +msgid "Choose file" +msgstr "" + +#: gtk/interface.c:1339 +msgid "Listen" +msgstr "Lyssna" + +#: gtk/interface.c:1343 +msgid "Sound properties" +msgstr "Ljudegenskaper" + +#: gtk/interface.c:1347 +msgid "Sound device" +msgstr "Ljudenhet" + +#: gtk/interface.c:1365 +msgid "Run sip user agent on port:" +msgstr "Kör SIP-agent på port:" + +#: gtk/interface.c:1374 +msgid "It is strongly recommended to use port 5060." +msgstr "Det rekommenderas starkt att använda port 5060." + +#: gtk/interface.c:1376 +msgid "SIP port" +msgstr "SIP-port" + +#: gtk/interface.c:1393 +msgid "Your sip address:" +msgstr "Din SIP-address:" + +#: gtk/interface.c:1407 +msgid "@" +msgstr "@" + +#: gtk/interface.c:1416 +msgid "Automatically guess a valid hostname" +msgstr "Gissa automatiskt ett giltigt värdnamn" + +#: gtk/interface.c:1420 +msgid "Identity" +msgstr "Identitet" + +#: gtk/interface.c:1467 +msgid "Add proxy/registrar" +msgstr "Lägg till proxy/registrar" + +#: gtk/interface.c:1488 gtk/interface.c:2114 +msgid "Edit" +msgstr "Redigera" + +#: gtk/interface.c:1509 +msgid "Remove" +msgstr "Ta bort" + +#: gtk/interface.c:1513 +msgid "Remote services" +msgstr "Fjärrtjänster" + +#: gtk/interface.c:1543 +msgid "Clear all stored authentication information (username,password...)" +msgstr "Rensa all lagra autentiseringsinformation (användarnamn,lösenord...)" + +#: gtk/interface.c:1547 +msgid "Authentication information" +msgstr "Autentiseringsinformation" + +#: gtk/interface.c:1551 +msgid "SIP" +msgstr "SIP" + +#: gtk/interface.c:1574 +msgid "List of audio codecs, in order of preference:" +msgstr "Lista av ljudkodare, sorterade efter önskemål:" + +#: gtk/interface.c:1595 +msgid "Audio codecs" +msgstr "Ljudkodare" + +#: gtk/interface.c:1608 +#, fuzzy +msgid "Video Codecs" +msgstr "Ljudkodare" + +#: gtk/interface.c:1644 +msgid "Enable" +msgstr "Aktivera" + +#: gtk/interface.c:1665 +msgid "Disable" +msgstr "Stäng av" + +#: gtk/interface.c:1673 +msgid "Upload bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1681 +msgid "Download bandwidth (kbit/sec):" +msgstr "" + +#: gtk/interface.c:1708 +msgid "" +"Note: Codecs in red are not usable regarding to your connection type to the " +"internet." +msgstr "" +"Notera: Kodare som är rödmarkerade är inte användbara enligt din " +"anslutningstyp mot Internet." + +#: gtk/interface.c:1720 +msgid "No information availlable" +msgstr "Ingen information tillgänglig" + +#: gtk/interface.c:1727 +msgid "Codec information" +msgstr "Information om kodare" + +#: gtk/interface.c:1731 +#, fuzzy +msgid "Audio and video codecs" +msgstr "Ljudkodare" + +#: gtk/interface.c:1736 +msgid "Codecs" +msgstr "Kodare" + +#: gtk/interface.c:2044 +msgid "Address Book" +msgstr "Addressbok" + +#: gtk/interface.c:2140 +msgid "Select" +msgstr "Välj" + +#: gtk/interface.c:2199 +msgid "Information" +msgstr "Information" + +#: gtk/interface.c:2217 +msgid "" +"User is not reachable at the moment but he invites you to contact him using " +"the following alternate ressource:" +msgstr "" +"Användare är inte tillgänglig för ögonblicket men han/hon inbjuder du att " +"kontakta honom/henne med följande alternativa resurser:" + +#: gtk/interface.c:2224 +msgid "None." +msgstr "Ingen." + +#: gtk/interface.c:2285 gtk/interface.c:2394 +msgid "Proxy/Registrar configuration box" +msgstr "Konfiguration av proxy/registrar" + +#: gtk/interface.c:2315 +msgid "Route (optional):" +msgstr "Rutt (valfri):" + +#: gtk/interface.c:2337 +msgid "SIP Proxy:" +msgstr "SIP-proxy:" + +#: gtk/interface.c:2344 +msgid "SIP Identity:" +msgstr "SIP-identitet:" + +#: gtk/interface.c:2359 +msgid "Registration Period:" +msgstr "Registreringsperiod:" + +#: gtk/interface.c:2374 +msgid "Send registration:" +msgstr "Skicka registrering:" + +#: gtk/interface.c:2381 +msgid "Publish presence information:" +msgstr "Publisera närvaroinformation:" + +#: gtk/interface.c:2466 +msgid "Edit contact information" +msgstr "Redigera kontaktinformation" + +#: gtk/interface.c:2505 +msgid "Name:" +msgstr "Namn:" + +#: gtk/interface.c:2526 +msgid "Subscribe policy:" +msgstr "Prenumerationspolicy:" + +#: gtk/interface.c:2533 +msgid "Send subscription (see person's online status)" +msgstr "Skicka prenumeration (se personens online-status)" + +#: gtk/interface.c:2537 +msgid "Contact information" +msgstr "Kontaktinformation" + +#: gtk/interface.c:2608 +msgid "New incoming subscription" +msgstr "Ny inkommande prenumeration" + +#: gtk/interface.c:2628 +msgid "You have received a new subscription..." +msgstr "Du har tagit emot en ny prenumeration..." + +#: gtk/interface.c:2655 +msgid "Refuse" +msgstr "Vägra" + +#: gtk/interface.c:2676 gtk/addressbook.c:57 +msgid "Accept" +msgstr "Acceptera" + +#: gtk/interface.c:2729 +msgid "Authentication requested" +msgstr "Autentiserings krävs" + +#: gtk/interface.c:2755 +msgid "Authentication required for realm" +msgstr "Autentisering krävs för domän" + +#: gtk/interface.c:2791 +msgid "userid:" +msgstr "användar-id:" + +#: gtk/interface.c:2799 +msgid "password:" +msgstr "lösenord:" + +#: gtk/interface.c:2807 +msgid "username:" +msgstr "användarnamn:" + +#: gtk/interface.c:2815 +msgid "realm:" +msgstr "domän:" + +#: gtk/interface.c:2876 +msgid "Linphone - Call history" +msgstr "Linphone - Samtalshistorik" + +#: gtk/interface.c:2943 +msgid "Chat Room" +msgstr "Chattrum" + +#: gtk/interface.c:2971 +msgid "Text:" +msgstr "Text:" + +#: gtk/callbacks.c:600 +#, c-format +msgid "Chat with %s" +msgstr "Chatta med %s" + +#: gtk/support.c:90 gtk/support.c:114 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "Kunde inte hitta bildfil: %s" + +#: gtk/propertybox.c:207 +#, fuzzy +msgid "Account" +msgstr "Acceptera" + +#: gtk/propertybox.c:439 gtk/propertybox.c:524 gtk/propertybox.c:536 +#: gtk/propertybox.c:883 +msgid "Enabled" +msgstr "Aktiverad" + +#: gtk/propertybox.c:440 gtk/propertybox.c:884 +msgid "Disabled" +msgstr "Avstängd" + +#: gtk/propertybox.c:458 gtk/friends.c:110 +msgid "Name" +msgstr "Namn" + +#: gtk/propertybox.c:464 +msgid "Rate (Hz)" +msgstr "Takt (Hz)" + +#: gtk/propertybox.c:470 +msgid "Status" +msgstr "Status" + +#: gtk/propertybox.c:476 +msgid "Min bitrate (kbit/s)" +msgstr "Minimum bithastighet (kbit/s)" + +#: gtk/propertybox.c:504 gtk/propertybox.c:509 gtk/propertybox.c:1061 +#: gtk/propertybox.c:1072 +msgid "Unlimited" +msgstr "" + +#: gtk/linphone.c:215 +msgid "The caller asks for resource reservation. Do you agree ?" +msgstr "Inringaren frågar efter reservation av resurs. Godkänner du detta ?" + +#: gtk/linphone.c:218 +msgid "" +"The caller doesn't use resource reservation. \t\t\t\t\tDo you wish to " +"continue anyway ?" +msgstr "" +"Andra parten använder inte resursreservation. \t\t\t\t\tVill du fortsätta " +"ändå ?" + +#: gtk/linphone.c:245 +#, c-format +msgid "linphone - receiving call from %s" +msgstr "linphone - tar emot samtal från %s" + +#: gtk/linphone.c:272 +#, c-format +msgid "" +"You have received a subscription from %s.This means that this person wishes " +"to be notified of your presence information (online, busy, away...).\n" +"Do you agree ?" +msgstr "" +"Du har mottagit en prenumeration från %s. Detta betyder att denna person " +"önskar bli notifierad om din närvaroinformation (online, upptagen, " +"borta...)\n" +"Godkänner du detta ?" + +#: gtk/linphone.c:287 +#, c-format +msgid "Authentication required for realm %s" +msgstr "Autentisering krävs för domänen %s" + +#: gtk/linphone.c:410 +msgid "None" +msgstr "Ingen" + +#: gtk/friends.c:117 +msgid "Presence status" +msgstr "Närvarostatus" + +#: gtk/addressbook.c:55 +msgid "Wait" +msgstr "" + +#: gtk/addressbook.c:56 +msgid "Deny" +msgstr "" + +#: gtk/addressbook.c:124 +#, fuzzy +msgid "Bad sip address: a sip address looks like sip:user@domain" +msgstr "" +"Kunde inte tolka angiven SIP-address. En SIP URL ser normalt sett ut som sip:" +"användare@domän" + +#: gtk/addressbook.c:226 +#, fuzzy +msgid "Contact list" +msgstr "Kontaktar" + +#: coreapi/linphonecore.c:186 +#, c-format +msgid "You have missed %i call(s)." +msgstr "Du har %i missade samtal." + +#: coreapi/linphonecore.c:212 +msgid "aborted" +msgstr "avbruten" + +#: coreapi/linphonecore.c:215 +msgid "completed" +msgstr "genomförd" + +#: coreapi/linphonecore.c:218 +msgid "missed" +msgstr "missad" + +#: coreapi/linphonecore.c:223 +#, fuzzy, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" +"%s at %sFrån: %s\n" +"Till: %s\n" +"Status: %s\n" +"Längd: %i min %i sek\n" + +#: coreapi/linphonecore.c:224 +msgid "Incoming call" +msgstr "Inkommande samtal" + +#: coreapi/linphonecore.c:224 +msgid "Outgoing call" +msgstr "Utgående samtal" + +#: coreapi/linphonecore.c:410 +msgid "" +"Your machine appears to be connected to an IPv6 network. By default linphone " +"always uses IPv4. Please update your configuration if you want to use IPv6" +msgstr "" +"Din maskin verkar vara ansluten till ett IPv6-nätverk. Som standard använder " +"linphone alltid IPv4. Vänligen uppdatera din konfiguration om du vill " +"använda IPv6." + +#: coreapi/linphonecore.c:692 +#, fuzzy +msgid "Ready" +msgstr "Klar." + +#: coreapi/linphonecore.c:741 +msgid "Stun lookup in progress..." +msgstr "" + +#: coreapi/linphonecore.c:750 +msgid "Stun lookup done..." +msgstr "" + +#: coreapi/linphonecore.c:985 +msgid "Remote end seems to have disconnected, the call is going to be closed." +msgstr "" + +#: coreapi/linphonecore.c:1077 +msgid "Looking for telephone number destination..." +msgstr "Letar efter destination för telefonnummer..." + +#: coreapi/linphonecore.c:1079 +msgid "Could not resolve this number." +msgstr "Kunde inte slå upp detta nummer." + +#: coreapi/linphonecore.c:1138 +msgid "" +"Could not parse given sip address. A sip url usually looks like sip:" +"user@domain" +msgstr "" +"Kunde inte tolka angiven SIP-address. En SIP URL ser normalt sett ut som sip:" +"användare@domän" + +#: coreapi/linphonecore.c:1187 +msgid "Sorry, having multiple simultaneous calls is not supported yet !" +msgstr "" + +#: coreapi/linphonecore.c:1198 +#, fuzzy +msgid "Contacting" +msgstr "Kontaktar" + +#: coreapi/linphonecore.c:1235 +msgid "could not call" +msgstr "" + +#: coreapi/linphonecore.c:1524 coreapi/exevents.c:41 +msgid "Connected." +msgstr "Ansluten." + +#: coreapi/linphonecore.c:1550 +#, fuzzy +msgid "Call ended" +msgstr "Samtal vägrades." + +#: coreapi/linphonecore.c:1846 +msgid "No nat/firewall address supplied !" +msgstr "" + +#: coreapi/linphonecore.c:1858 coreapi/linphonecore.c:1870 +#, c-format +msgid "Invalid nat address '%s' : %s" +msgstr "" + +#: coreapi/misc.c:130 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the pcm oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +"'modprobe snd-pcm-oss' as root to load it." +msgstr "" +"Din dator verkar använda ljuddrivare för ALSA.\n" +"Detta är det bästa valet. Dock saknas emuleringsmodulen\n" +"för OSS-PCM och linphone behöver den. Vänligen\n" +"kör \"modprobe snd-pcm-oss\" som root för att läsa in den." + +#: coreapi/misc.c:133 +msgid "" +"Your computer appears to be using ALSA sound drivers.\n" +"This is the best choice. However the mixer oss emulation module\n" +"is missing and linphone needs it. Please execute\n" +" 'modprobe snd-mixer-oss' as root to load it." +msgstr "" +"Din dator verkar använda ljuddrivare för ALSA.\n" +"Detta är det bästa valet. Dock saknas emuleringsmodulen\n" +"för OSS-mixern och linphone behöver den. Vänligen\n" +"kör \"modprobe snd-mixer-oss\" som root för att läsa in den." + +#: coreapi/exevents.c:115 +#, fuzzy +msgid "Call terminated." +msgstr "Samtal vägrades." + +#: coreapi/exevents.c:137 +msgid "Could not reach destination." +msgstr "Kunde inte nå destination." + +#: coreapi/exevents.c:146 +msgid "User is busy." +msgstr "Användaren är upptagen." + +#: coreapi/exevents.c:147 +msgid "User is temporarily unavailable." +msgstr "Användaren är temporärt ej tillgänglig." + +#: coreapi/exevents.c:148 +msgid "Request Cancelled." +msgstr "Begäran avbruten." + +#: coreapi/exevents.c:150 +msgid "User does not want to be disturbed." +msgstr "Användaren vill inte bli störd." + +#: coreapi/exevents.c:151 +msgid "Call declined." +msgstr "Samtal vägrades." + +#: coreapi/exevents.c:170 +msgid "Bad request" +msgstr "Felaktig begäran" + +#: coreapi/exevents.c:173 +msgid "User cannot be found at given address." +msgstr "Användaren kunde inte hittas på den angivna addressen." + +#: coreapi/exevents.c:176 +msgid "Remote user cannot support any of proposed codecs." +msgstr "Fjärranvändaren har inte stöd för någon av de förslagna kodarna." + +#: coreapi/exevents.c:202 +msgid "Timeout." +msgstr "Timeout." + +#: coreapi/exevents.c:205 +msgid "Remote host was found but refused connection." +msgstr "Fjärrvärden hittades med vägrade ta emot anslutningen." + +#: coreapi/exevents.c:312 +#, fuzzy +msgid "is contacting you." +msgstr "ringer dig." + +#: coreapi/exevents.c:392 +#, c-format +msgid "Redirected to %s..." +msgstr "Omdirigerad till %s..." + +#: coreapi/exevents.c:408 +msgid "" +"User is not reachable at the moment but he invites you\n" +"to contact him using the following alternate resource:" +msgstr "" +"Användare är inte tillgänglig för tillfället men han/hon inbjuder\n" +"dig att kontakta honom/henne med följande alternativa resurs:" + +#: coreapi/exevents.c:775 +msgid "Early media." +msgstr "" + +#: coreapi/exevents.c:837 +#, fuzzy, c-format +msgid "Registration on %s failed: %s" +msgstr "Registrering misslyckades (timeout)." + +#: coreapi/exevents.c:837 +msgid "no response timeout" +msgstr "" + +#: coreapi/exevents.c:851 +#, fuzzy, c-format +msgid "Registration on %s successful." +msgstr "Registrering på %s lyckades." + +#: coreapi/presence.c:112 coreapi/presence.c:164 +#, fuzzy +msgid "Gone" +msgstr "Ingen" + +#: coreapi/presence.c:129 +msgid "Waiting for Approval" +msgstr "" + +#: coreapi/presence.c:133 +#, fuzzy +msgid "Online" +msgstr "line" + +#: coreapi/presence.c:137 +msgid "Busy" +msgstr "" + +#: coreapi/presence.c:142 +msgid "Be Right Back" +msgstr "" + +#: coreapi/presence.c:151 +msgid "On The Phone" +msgstr "" + +#: coreapi/presence.c:156 +msgid "Out To Lunch" +msgstr "" + +#: coreapi/presence.c:160 +msgid "Closed" +msgstr "" + +#~ msgid "User manual" +#~ msgstr "Användarmanual" + +#~ msgid "Ring sound selection" +#~ msgstr "Val av ringsignal" + +#~ msgid "Communication ended." +#~ msgstr "Anslutning avslutad." + +#~ msgid "Call cancelled." +#~ msgstr "Samtal avbrutet." + +#~ msgid "Firewall 's external ip address (in dot notations):" +#~ msgstr "Brandväggens externa IP-address (i punktnotation):" + +#~ msgid "Index" +#~ msgstr "Index" + +#~ msgid "Address" +#~ msgstr "Address" + +#~ msgid "Server address" +#~ msgstr "Serveraddress" + +#~ msgid "28k modem" +#~ msgstr "28k modem" + +#~ msgid "56k modem" +#~ msgstr "56k modem" + +#~ msgid "64k modem (numeris)" +#~ msgstr "64k modem (numerisk)" + +#~ msgid "ADSL or Cable modem" +#~ msgstr "ADSL eller kabelmodem" + +#~ msgid "Ethernet or equivalent" +#~ msgstr "Ethernet eller liknande" + +#~ msgid "Connection type:" +#~ msgstr "Anslutningstyp:" + +#~ msgid "" +#~ "Linphone could not open audio device %s. Check if your sound card is " +#~ "fully configured and working." +#~ msgstr "" +#~ "Linphone kunde inte öppna ljudenheten %s. Kontrollera om ditt ljudkort är " +#~ "konfigurerat och fungerar." + +#~ msgid "Type here the sip address of the person you want to call." +#~ msgstr "Ange SIP-addressen för personen du vill ringa." diff --git a/linphone/reconfig-SuSE b/linphone/reconfig-SuSE new file mode 100755 index 000000000..8a9aea659 --- /dev/null +++ b/linphone/reconfig-SuSE @@ -0,0 +1,23 @@ +#!/bin/sh +echo "Generating build scripts in linphone..." +libtoolize --copy --force +chmod 644 macros/* +cp /opt/gnome2/share/aclocal/gnome2-macros/* macros/. +aclocal-1.6 -I macros +autoheader +automake-1.6 --add-missing --copy +autoconf +rm -rf config.cache + +echo "Generating build scripts in osipua..." +cd osipua && ./reconfig + +echo "Generating build scripts in oRTP..." +cd .. +cd oRTP && ./reconfig + +echo "Generating build scripts in speex..." +cd .. +cd speex && libtoolize --copy --force && aclocal-1.6 && automake-1.6 --add-missing --copy && autoconf -f + + diff --git a/linphone/share/.cvsignore b/linphone/share/.cvsignore new file mode 100644 index 000000000..3d11e0206 --- /dev/null +++ b/linphone/share/.cvsignore @@ -0,0 +1,4 @@ +Makefile +Makefile.in +*.raw +linphone.pc diff --git a/linphone/share/C/.cvsignore b/linphone/share/C/.cvsignore new file mode 100644 index 000000000..e1d20773b --- /dev/null +++ b/linphone/share/C/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +manual +manual.junk +manual.html diff --git a/linphone/share/C/Makefile.am b/linphone/share/C/Makefile.am new file mode 100644 index 000000000..0d6136465 --- /dev/null +++ b/linphone/share/C/Makefile.am @@ -0,0 +1,8 @@ + +HELPLANG=C + +include ../Makefile.inc + +man_MANS = linphone.1 linphonec.1 sipomatic.1 + +EXTRA_DIST+=$(man_MANS) diff --git a/linphone/share/C/linphone.1 b/linphone/share/C/linphone.1 new file mode 100644 index 000000000..8c87c64dc --- /dev/null +++ b/linphone/share/C/linphone.1 @@ -0,0 +1,42 @@ +.\" Linphone is an internet phone compatible with the Session Initiation Protocol (SIP: RFC3261 ) +.TH "linphone" "1" "1.0.0" "Simon Morlat" "linphone" +.SH "NAME" +.LP +linphone \- Gnome interface of linphone, a SIP compatible +internet phone. +.SH "SYNTAX" +.LP +linphone [\fI\-\-help\fP] [\fI\-\-verbose\fP] + +.SH "DESCRIPTION" +.LP +Linphone can be started without any extra argument. All parameters are accessible from the property box. + +.SH "OPTIONS" +.LP +.TP +\fB\-\-help\fR +Output help information and exit. +.TP +\fB\-\-version\fR +Output version information and exit. +\fB\-\-verbose\fR +Output internal messages on stdout, this is useful for debugging. +.SH "FILES" +.LP +\fI~/.gnome2/linphone\fP +.br +This is where linphone reads its config information. You do not have to modify or edit this file. +.br + +.SH "ENVIRONMENT VARIABLES" + +.SH "EXAMPLES" + +.SH "AUTHORS" +.LP +Simon MORLAT +See the AUTHORS file inside linphone's source for more details. +.SH "SEE ALSO" +.LP +linphonec(1) sipomatic(1) diff --git a/linphone/share/C/linphonec.1 b/linphone/share/C/linphonec.1 new file mode 100644 index 000000000..c19bf2108 --- /dev/null +++ b/linphone/share/C/linphonec.1 @@ -0,0 +1,69 @@ +.\" Linphone is an internet phone compatible with the Session Initiation Protocol (SIP: RFC3261 ) +.TH "linphonec" "1" "1.0.0" "Florian Winterstein & Simon MORLAT" "linphone, internet phone" +.SH "NAME" +.LP +linphonec \- Console interface of linphone, a SIP compatible +internet phone. +.SH "SYNTAX" +.LP +linphonec [\fI\-d\fP] <\fIdebug_level\fP> [\fI\-l\fP] <\fIdebug_file\fP> [\fI\-c\fP] <\fIconfig_file\fP> +.br +linphonec \fI\-v\fP +.SH "DESCRIPTION" +.LP +Linphonec is the console version of originally Gnome internet phone linphone (http://www.linphone.org) . +.br +Linphonec can be started without arguments. It doesn't need any config file to start correctly and will create a default one at the first startup if the file does not exist. +By default the path of the config file is ~/.linphonerc . +Most parameters (proxy, passwords) can be changed from the command line, for some of them (path of sound rings), you'll need +to edit the .linphonerc config file. +.br +Once linphonec has started, linphonec wait for some commands and is ready to receive calls. +.br +The most important commands are +.br +.TP +call : to call someone. A sip url is in the form sip:user@host +.TP +terminate : to terminate a call +.TP +answer : to accept an incoming call. +.TP +help : to display interactive help. +.TP + + + +.SH "OPTIONS" +.LP +.TP +\fB\-d\fR <\fIdebug_level\fP> +Use debug mode with given verbosity (debug_level). The debug_level is an integer in the range 0..5 . +.TP +\fB\-h\fR +Output help information and exit. +.TP +\fB\-l\fR <\fIlog_file\fP> +Specifies a file where debug information will be written. Default is stdout. +.TP +\fB\-c\fR <\fIconfig_file\fP> +Specifies the config file to read at startup. +.TP +.SH "FILES" +.LP +\fI~/.linphonec\fP +.br + +.SH "ENVIRONMENT VARIABLES" +.LP +.SH "EXAMPLES" +.LP + +.SH "AUTHORS" +.LP +Florian Winterstein +.br +Simon Morlat +.SH "SEE ALSO" +.LP +linphone(1) sipomatic(1) diff --git a/linphone/share/C/manual.lyx b/linphone/share/C/manual.lyx new file mode 100644 index 000000000..e11ca3bc7 --- /dev/null +++ b/linphone/share/C/manual.lyx @@ -0,0 +1,654 @@ +#LyX 1.4.4 created this file. For more info see http://www.lyx.org/ +\lyxformat 245 +\begin_document +\begin_header +\textclass docbook +\language english +\inputencoding default +\fontscheme default +\graphics default +\paperfontsize default +\spacing single +\papersize default +\use_geometry false +\use_amsmath 1 +\cite_engine basic +\use_bibtopic false +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language french +\papercolumns 1 +\papersides 1 +\paperpagestyle default +\tracking_changes false +\output_changes true +\end_header + +\begin_body + +\begin_layout Title +Linphone's User Manual +\end_layout + +\begin_layout Date +July, 24th 2004 +\end_layout + +\begin_layout Section +Introduction +\end_layout + +\begin_layout Standard +Linphone is a simple web-phone. + It allows you to make two party-calls using an IP network like the internet. + What you need to run Linphone is : +\end_layout + +\begin_layout Itemize +a computer running the GNU/Linux operating system +\end_layout + +\begin_layout Itemize +gtk+>=2.4, in order to use the graphical interface (highly recommended!). + The console-only application (linphonec) does not need gtk but libreadline. +\end_layout + +\begin_layout Itemize +a sound card correctly configured to use the ALSA linux sound system +\end_layout + +\begin_layout Itemize +headphones or speakers +\end_layout + +\begin_layout Itemize +a microphone +\end_layout + +\begin_layout Itemize +a connection to a network (the Internet for example), using a modem, an + ethernet card, a Wifi adapter or anything else +\end_layout + +\begin_layout Standard +Since linphone needs to use the computer's sound system, before running + linphone, please make sure that no other application is using the audio + device. + +\end_layout + +\begin_layout Standard +Linphone is free, it is released under +\emph on +GNU Public License +\emph default +. +\end_layout + +\begin_layout Standard + +\emph on +WARNING: This software is provided with NO WARRANTY see file COPYING for + details. + This means you SHOULD NOT use linphone for confidential conversations: + there is NO encryption, so it is easy for any bad-intentioned person to + monitor the audio streams, and thus your conversation. + Note also that it is not recommended to run Linphone as root. +\end_layout + +\begin_layout Section +Running linphone +\end_layout + +\begin_layout Standard +Linphone can be run in three different ways: +\end_layout + +\begin_layout Itemize +as a normal application: in the gnome menu, linphone should appear in the + network sub-menu. + If you are not running gnome, you can execute linphone directly by typing + linphone in a terminal, for example. + Please note, that when linphone is not running, you cannot receive calls. +\end_layout + +\begin_layout Itemize +as a gnome applet: add the linphone applet by right-clicking on the gnome + panel, linphone appears in the network menu. + When linphone is running silently as a gnome panel, it is able to receive + calls even if its window is not shown. + If you want the main linphone window to appear, click on the applet. + When somebody calls you, the main window is shown and you will hear the + ring normally. +\end_layout + +\begin_layout Section +Making a call +\end_layout + +\begin_layout Subsection +Basic principles +\end_layout + +\begin_layout Standard +Linphone uses the Session Initiation Protocol (SIP) to establish a connection + with a remote host. + In this protocol each caller or callee is identified by a SIP url: sip:user_nam +e@host_name. + A SIP url's syntax like an email address, with a +\begin_inset Quotes sld +\end_inset + +sip: +\begin_inset Quotes sld +\end_inset + + prefix. +\end_layout + +\begin_layout Standard +User_name is probably your login account on a Unix machine, and host_name + is the machines fully qualified domain name (FQDN) or IP address. +\end_layout + +\begin_layout Standard +Note that SIP is a new telecommunication protocol designed to be simple, + and it is not compatible with H323 at all. +\end_layout + +\begin_layout Subsection +When IP address are not static, or not routable. +\end_layout + +\begin_layout Standard +For that purpose, you can register to a SIP provider or SIP proxy. + There exist several SIP proxies on the net, and some of them are free. + See, for example, http://iptel.org. + You'll have to get an account on the proxy and then tell linphone to use + it. + In this case, the user_name will assigned to you by the VoIP provider, + when you register, and host_name is the provider's host name (usually something + like sip.example.com). + +\end_layout + +\begin_layout Subsection +Test trial: If you have no friends to call at the moment (because it is + too late for example), but would like to know if linphone is really working. +\end_layout + +\begin_layout Standard +\begin_inset LatexCommand \label{sipomatic} + +\end_inset + +Since version 0.3.0, linphone comes with a test program called ' +\emph on +sipomatic +\emph default +'. + Sipomatic can answer automatically calls from linphone. + To do this: +\end_layout + +\begin_layout Itemize +run sipomatic from a terminal. + Sipomatic does not have a graphical interface, but you don't have to interact + with it, so it doesn't need one. + +\end_layout + +\begin_layout Itemize +Then type the following SIP url in the main window of linphone: sip:robot@127.0.0.1 +:5064 . + 127.0.0.1 is the local address for your computer, and robot is the name to + use for calling sipomatic. + 5064 is the port that sipomatic is listening to. + Normally you should always use 5060 (i.e the default port when no port is + specified) to call somebody, but sipomatic is the exception: it runs on + port 5064. + The reason for this is that linphone itself already runs on 5060, and you + cannot have two applications running on the same port, at the same time + and on the same machine. +\end_layout + +\begin_layout Itemize +Then press the call button. + After one second, sipomatic should answer to your call and you should hear + a short announcement. +\end_layout + +\begin_layout Section +\begin_inset LatexCommand \label{params} + +\end_inset + +Call parameters +\end_layout + +\begin_layout Subsection +\begin_inset LatexCommand \label{paramnetwork} + +\end_inset + +Network +\end_layout + +\begin_layout Standard +Linphone allows you to set your firewall address (see section 7) or a stun + server address that might help linphone calling and receiving calls. +\end_layout + +\begin_layout Standard +Linphone supports ipv6: you can enable it by toggling the +\begin_inset Quotes fld +\end_inset + +Enable ipv6 +\begin_inset Quotes frd +\end_inset + + checkbox. + However it can support Ipv6 and Ipv4 together. +\end_layout + +\begin_layout Subsection +\begin_inset LatexCommand \label{paramrtp} + +\end_inset + +RTP +\end_layout + +\begin_layout Standard +RTP (Real Time Protocol) is a protocol used to send media streams over networks. +\end_layout + +\begin_layout Itemize +RTP port: linphone uses default port 7078 to send and receive audio streams. + If you think port 7078 is used by another application, change it as you + wish. +\end_layout + +\begin_layout Itemize +Jitter compensation: This number represents the number of audio packets + linphone is waiting for before starting to play them. + If sometimes some audio packets are late, they have a greater chance to + be played. + Increase this parameter, if the other person's voice sounds 'chopped', + in order to improve the quality of the transmission. + This will however increase the delay (you will hear the remote user's talk + with a few seconds delay). + If, on the other hand, you are using a fast network, and you have good + audio drivers, you can set this parameters down to three packets, and you + will have a very small delay. +\end_layout + +\begin_layout Subsection +\begin_inset LatexCommand \label{paramsip} + +\end_inset + +SIP +\end_layout + +\begin_layout Standard +SIP (Session Initiation Protocol) is a protocol to establish and destroy + media sessions over a network. + In simple words, it's responsible for controlling calls. + It rings the remote user, initiates the call and terminates it when one + of the two parties hangs up. +\end_layout + +\begin_layout Itemize +SIP port: linphone uses default port 5060 to send and receive SIP packets. + It is highly recommended by SIP's RFC to use port 5060. + So, please don't change this unless you really know what you are doing. +\end_layout + +\begin_layout Itemize +Use registrar: toggle this button if you need the services of a remote SIP + server. + See section +\begin_inset Quotes eld +\end_inset + +Registering on a remote server +\begin_inset Quotes erd +\end_inset + + for details about this. +\end_layout + +\begin_layout Subsection +\begin_inset LatexCommand \label{paramcodec} + +\end_inset + +Codecs +\end_layout + +\begin_layout Standard +Codecs are algorithms especially designed to compress voice data. + For example, digitized voice in 16bit / 8000 Hz represents a data flow + of 128 kbits/second. + Using the GSM codec, this flow is reduced to 13 kbits/second, without significa +nt loss of quality. + Currently the best bitrate/quality compromise is achieved by using the + speex codec. +\end_layout + +\begin_layout Itemize +Codec choice: linphone can use several codecs. + Use buttons at the bottom of the codec list to put them in order of preference. + Note, that according to your network connection type, some codecs are not + usable. + They appear in red and they are not selectable. + You can decide to use or not a usable codec (in blue) by changing its status + with the enable/disable buttons at the bottom of the list. +\end_layout + +\begin_layout Itemize +Connection type: select how you are connected to the network you want to + use (in most cases that will be the internet). + This helps linphone configure itself according to the bandwidth of your + connection type. + For example some some high-bitrate codecs will be automatically disabled, + if you select connection with a 56k modem. +\end_layout + +\begin_layout Subsection +\begin_inset LatexCommand \label{paramaudio} + +\end_inset + +Audio parameters +\end_layout + +\begin_layout Standard +In this section you will find parameters related to your sound equipment. +\end_layout + +\begin_layout Itemize +Sound card choice: if you have several sound cards on your PC, you can select + the one to be used by linphone. +\end_layout + +\begin_layout Itemize +Source choice: in this combo box you can choose the recording source for + your voice. + In most cases it will be the microphone (mic). +\end_layout + +\begin_layout Section +Address book +\end_layout + +\begin_layout Standard +The address book lets you store and recall names and sip addresses of people. + +\end_layout + +\begin_layout Standard +When adding a new contact, a little contact box is displayed, where you + can fill in information about the person, mainly of course his SIP address. + Additionally you can toggle the +\begin_inset Quotes fld +\end_inset + +send subscription +\begin_inset Quotes frd +\end_inset + + button if you want the person to keep you informed of his online status + (ready, busy, gone...). + You can also choose to reject subscription from this person, meaning that + he will not be informed of your online status. +\end_layout + +\begin_layout Section +Using SIP proxies and registrar. +\end_layout + +\begin_layout Standard +Registering with a SIP server can be useful in two main cases: +\end_layout + +\begin_layout Itemize +Your machine does not have a public domain name, which prevents other users + to call you as they can't guess your IP address. + In this case, you can register with a proxy or redirect SIP server to get + a public SIP address. + For example, you are and let's suppose that there + exists a redirect or proxy SIP server at . + By registering as 'bob' with , your friends will be able + to call you at the address . + Of course, the user_name assigned to you by the SIP server may be different + from your login name on the local machine. + It can even be a number resembling a regular (PSTN) phone number, eg. + 5002000307. + The proxy or redirect server myserver.org will forward or redirect the calls + from your friends to your exact location. +\end_layout + +\begin_layout Standard +With linphone>=1.0.0 you can choose to use several proxies simultaneously. + Go to the property box, section sip, and click on add proxy. + You'll be prompted for a proxy address, route and your identity (also known + as address of record). + This information should be given to you by the SIP provider you registered + with. + Route can be omitted (ie. + is optional), so leave it empty in case you don't know what to put there. + The identity is the SIP address you are known by the proxy. + Other users on the network are supposed to always be able to find you at + this SIP address. +\end_layout + +\begin_layout Section +Behind a firewall +\end_layout + +\begin_layout Standard +In some cases the configuration of your network is such that linphone (or + any other SIP phone program) cannot tell with certainty, how other computers + on the network can talk to your computer. + This is usually the case, when your machine is behind a firewall/router + that uses the Network Address Translation (NAT) protocol (RFC 1631). + In order to find out linphone can use the services of a "Simple Traversal + of User datagram through Network address translators" (STUN) server (RFC + 3489). + If you are behind a NAT firewall/router put the name of your STUN server + in the respective field. + This information is usually provided to you by your SIP proxy/server and + most times, assuming that your SIP server is 'sip.example.com', it looks + like 'stun.example.com'. + You may also have to specify the port your STUN server listens to (default + 3478). +\end_layout + +\begin_layout Section +Problems +\end_layout + +\begin_layout Subsection +Connection problems +\end_layout + +\begin_layout Standard +Firewalls are the main cause of problems in call routing. + Check that udp ports are opened and masqueraded, and subscribe to a SIP + proxy outside: most proxies are able to handle firewalls issues themselves. + If not possible read section 7 (Behind a firewall). +\end_layout + +\begin_layout Subsection +Audio problems +\end_layout + +\begin_layout Quotation +Linphone seems to connect to the remote SIP url, it rings, but when the + callee answers, nothing happens and we can't hear each other. +\end_layout + +\begin_layout Itemize +Using your audio mixer program (eg. + 'alsamixer', 'kmix', or 'aumix') make make sure the audio output is not + muted and that the playback (master volume, PCM) and recording (mic) controls + are set to at least their medium values. +\end_layout + +\begin_layout Itemize +If the voice is sometimes interrupted, you can modify parameter RTP->jitter + compensation in the property box to greater values to avoid this. + But this will also increase the transmission delay. +\end_layout + +\begin_layout Itemize +If linphone cannot open the audio device, check if the user has the right + permissions to open /dev/dsp, and close all programs able to use audio + device (xmms, kaiman...), as at this point linphone cannot share the audio + device with other applications. +\end_layout + +\begin_layout Itemize +Use ALSA drivers (see +\begin_inset LatexCommand \url[http://www.alsa-project.org]{http://www.alsa-project.org} + +\end_inset + +). + Most distributions still use the old OSS kernel-official drivers, that + have big latency problems and are often buggy. + ALSA drivers are much better. + +\end_layout + +\begin_layout Section +Bugs reporting and suggestions +\end_layout + +\begin_layout Standard +First go to linphone's home page at +\begin_inset LatexCommand \url[http://www.linphone.org]{http://www.linphone.org} + +\end_inset + + to check if you have the latest version if linphone. +\end_layout + +\begin_layout Standard +If linphone crashes, send a report to the mailing list, linphone-users@nongnu.org. + If linphone does not work, but does not crash, please ensure you have read + this manual in its entirety before sending a bug report at the above address. + You can also send e-mail to the mailing list to request a specific feature, + that you think is missing from linphone. + Note that video support, and conferencing are planned features. + If someone is interested in helping with the translations of linphone to + other languages, s/he can send me a xx.po file based on the po/linphone.pot + file of the distribution. + You can also translate this user manual in other languages. + In any case, please contact me if you want more details. +\end_layout + +\begin_layout Section +Authors +\end_layout + +\begin_layout Standard +Simon MORLAT (simon.morlat@linphone.org) wrote: +\end_layout + +\begin_layout Itemize +main library (coreapi) +\end_layout + +\begin_layout Itemize +gnome interface (thanks to glade !) +\end_layout + +\begin_layout Itemize +RTP library (oRTP) +\end_layout + +\begin_layout Itemize +audio/video framework and wrappers (mediastreamer) +\end_layout + +\begin_layout Standard +Aymeric Moizard (jack@atosc.org) wrotes the osip and eXosip stacks that is + used by linphone. + +\end_layout + +\begin_layout Standard +The speex codec +\begin_inset LatexCommand \url[http://www.speex.org]{http://www.speex.org} + +\end_inset + + is a high quality low bitrate codec by Jean Marc Valin. +\end_layout + +\begin_layout Standard +The GSM library was written by : Jutta Degener and Carsten Bormann,Technische + Universitaet Berlin. +\end_layout + +\begin_layout Standard +The LPC10-1.5 library was written by: Andy Fingerhut Applied Research Laboratory + <-- this line is optional if Washington University, Campus Box 1045/Bryan + 509 you have limited space One Brookings Drive Saint Louis, MO 63130-4899 + jaf@arl.wustl.edu http://www.arl.wustl.edu/~jaf/ See text files in gsmlib and + lpc10-1.5 directories for further information. +\end_layout + +\begin_layout Standard +Icons by Pablo Marcelo Moia. +\end_layout + +\begin_layout Section +Thanks +\end_layout + +\begin_layout Standard +Thanks to Daemon Chaplin, for having done Glade, the gtk interface builder. +\end_layout + +\begin_layout Standard +Thanks to Aymeric Moizard, for his famous oSIP library. +\end_layout + +\begin_layout Standard +Thanks to Florian Winstertein, for the console interface of linphone. +\end_layout + +\begin_layout Standard +Thanks to Jean Marc Valin, for his great speex codec. +\end_layout + +\begin_layout Standard +Thanks to the authors of LPC10-1.5 and GSM code. +\end_layout + +\begin_layout Standard +Thanks to Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) for his RPMS. +\end_layout + +\begin_layout Standard +Thanks to Pablo Marcelo Moia for the great icons he has made for linphone. +\end_layout + +\begin_layout Standard +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/linphone/share/C/manual.sgml b/linphone/share/C/manual.sgml new file mode 100644 index 000000000..4d4155e71 --- /dev/null +++ b/linphone/share/C/manual.sgml @@ -0,0 +1,85 @@ + + + + + ]> + + +
+ +Linphone's User Manual +July, 24th 2004 +Introduction +Linphone is a simple web-phone. It allows you to make two party-calls using an IP network like the internet. What you need to run Linphone is : +a computer running the GNU/Linux operating systemgtk+>=2.4, in order to use the graphical interface (highly recommended!). The console-only application (linphonec) does not need gtk but libreadline.a sound card correctly configured to use the ALSA linux sound systemheadphones or speakersa microphonea connection to a network (the Internet for example), using a modem, an ethernet card, a Wifi adapter or anything elseSince linphone needs to use the computer's sound system, before running linphone, please make sure that no other application is using the audio device. +Linphone is free, it is released under GNU Public License. +WARNING: This software is provided with NO WARRANTY see file COPYING for details. This means you SHOULD NOT use linphone for confidential conversations: there is NO encryption, so it is easy for any bad-intentioned person to monitor the audio streams, and thus your conversation. Note also that it is not recommended to run Linphone as root. +Running linphone +Linphone can be run in three different ways: +as a normal application: in the gnome menu, linphone should appear in the network sub-menu. If you are not running gnome, you can execute linphone directly by typing linphone in a terminal, for example. Please note, that when linphone is not running, you cannot receive calls.as a gnome applet: add the linphone applet by right-clicking on the gnome panel, linphone appears in the network menu. When linphone is running silently as a gnome panel, it is able to receive calls even if its window is not shown. If you want the main linphone window to appear, click on the applet. When somebody calls you, the main window is shown and you will hear the ring normally. +Making a call + +Basic principles +Linphone uses the Session Initiation Protocol (SIP) to establish a connection with a remote host. In this protocol each caller or callee is identified by a SIP url: sip:user_name@host_name. A SIP url's syntax like an email address, with a “sip:“ prefix. +User_name is probably your login account on a Unix machine, and host_name is the machines fully qualified domain name (FQDN) or IP address. +Note that SIP is a new telecommunication protocol designed to be simple, and it is not compatible with H323 at all. +When IP address are not static, or not routable. +For that purpose, you can register to a SIP provider or SIP proxy. There exist several SIP proxies on the net, and some of them are free. See, for example, http://iptel.org. You'll have to get an account on the proxy and then tell linphone to use it. In this case, the user_name will assigned to you by the VoIP provider, when you register, and host_name is the provider's host name (usually something like sip.example.com). +Test trial: If you have no friends to call at the moment (because it is too late for example), but would like to know if linphone is really working. +Since version 0.3.0, linphone comes with a test program called 'sipomatic'. Sipomatic can answer automatically calls from linphone. To do this: +run sipomatic from a terminal. Sipomatic does not have a graphical interface, but you don't have to interact with it, so it doesn't need one. Then type the following SIP url in the main window of linphone: sip:robot@127.0.0.1:5064 . 127.0.0.1 is the local address for your computer, and robot is the name to use for calling sipomatic. 5064 is the port that sipomatic is listening to. Normally you should always use 5060 (i.e the default port when no port is specified) to call somebody, but sipomatic is the exception: it runs on port 5064. The reason for this is that linphone itself already runs on 5060, and you cannot have two applications running on the same port, at the same time and on the same machine.Then press the call button. After one second, sipomatic should answer to your call and you should hear a short announcement. +<!-- anchor id="params" -->Call parameters + +<!-- anchor id="paramnetwork" -->Network +Linphone allows you to set your firewall address (see section 7) or a stun server address that might help linphone calling and receiving calls. +Linphone supports ipv6: you can enable it by toggling the “Enable ipv6” checkbox. However it can support Ipv6 and Ipv4 together. +<!-- anchor id="paramrtp" -->RTP +RTP (Real Time Protocol) is a protocol used to send media streams over networks. +RTP port: linphone uses default port 7078 to send and receive audio streams. If you think port 7078 is used by another application, change it as you wish.Jitter compensation: This number represents the number of audio packets linphone is waiting for before starting to play them. If sometimes some audio packets are late, they have a greater chance to be played. Increase this parameter, if the other person's voice sounds 'chopped', in order to improve the quality of the transmission. This will however increase the delay (you will hear the remote user's talk with a few seconds delay). If, on the other hand, you are using a fast network, and you have good audio drivers, you can set this parameters down to three packets, and you will have a very small delay. +<!-- anchor id="paramsip" -->SIP +SIP (Session Initiation Protocol) is a protocol to establish and destroy media sessions over a network. In simple words, it's responsible for controlling calls. It rings the remote user, initiates the call and terminates it when one of the two parties hangs up. +SIP port: linphone uses default port 5060 to send and receive SIP packets. It is highly recommended by SIP's RFC to use port 5060. So, please don't change this unless you really know what you are doing.Use registrar: toggle this button if you need the services of a remote SIP server. See section “Registering on a remote server” for details about this. +<!-- anchor id="paramcodec" -->Codecs +Codecs are algorithms especially designed to compress voice data. For example, digitized voice in 16bit / 8000 Hz represents a data flow of 128 kbits/second. Using the GSM codec, this flow is reduced to 13 kbits/second, without significant loss of quality. Currently the best bitrate/quality compromise is achieved by using the speex codec. +Codec choice: linphone can use several codecs. Use buttons at the bottom of the codec list to put them in order of preference. Note, that according to your network connection type, some codecs are not usable. They appear in red and they are not selectable. You can decide to use or not a usable codec (in blue) by changing its status with the enable/disable buttons at the bottom of the list.Connection type: select how you are connected to the network you want to use (in most cases that will be the internet). This helps linphone configure itself according to the bandwidth of your connection type. For example some some high-bitrate codecs will be automatically disabled, if you select connection with a 56k modem. +<!-- anchor id="paramaudio" -->Audio parameters +In this section you will find parameters related to your sound equipment. +Sound card choice: if you have several sound cards on your PC, you can select the one to be used by linphone.Source choice: in this combo box you can choose the recording source for your voice. In most cases it will be the microphone (mic). +Address book +The address book lets you store and recall names and sip addresses of people. +When adding a new contact, a little contact box is displayed, where you can fill in information about the person, mainly of course his SIP address. Additionally you can toggle the “send subscription” button if you want the person to keep you informed of his online status (ready, busy, gone...). You can also choose to reject subscription from this person, meaning that he will not be informed of your online status. +Using SIP proxies and registrar. +Registering with a SIP server can be useful in two main cases: +Your machine does not have a public domain name, which prevents other users to call you as they can't guess your IP address. In this case, you can register with a proxy or redirect SIP server to get a public SIP address. For example, you are <sip:bob@no-host-name> and let's suppose that there exists a redirect or proxy SIP server at <sip:myserver.org>. By registering as 'bob' with <sip:myserver.org>, your friends will be able to call you at the address <sip:bob@myserver.org> . Of course, the user_name assigned to you by the SIP server may be different from your login name on the local machine. It can even be a number resembling a regular (PSTN) phone number, eg. 5002000307. The proxy or redirect server myserver.org will forward or redirect the calls from your friends to your exact location.With linphone>=1.0.0 you can choose to use several proxies simultaneously. Go to the property box, section sip, and click on add proxy. You'll be prompted for a proxy address, route and your identity (also known as address of record). This information should be given to you by the SIP provider you registered with. Route can be omitted (ie. is optional), so leave it empty in case you don't know what to put there. The identity is the SIP address you are known by the proxy. Other users on the network are supposed to always be able to find you at this SIP address. +Behind a firewall +In some cases the configuration of your network is such that linphone (or any other SIP phone program) cannot tell with certainty, how other computers on the network can talk to your computer. This is usually the case, when your machine is behind a firewall/router that uses the Network Address Translation (NAT) protocol (RFC 1631). In order to find out linphone can use the services of a "Simple Traversal of User datagram through Network address translators" (STUN) server (RFC 3489). If you are behind a NAT firewall/router put the name of your STUN server in the respective field. This information is usually provided to you by your SIP proxy/server and most times, assuming that your SIP server is 'sip.example.com', it looks like 'stun.example.com'. You may also have to specify the port your STUN server listens to (default 3478). +Problems + +Connection problems +Firewalls are the main cause of problems in call routing. Check that udp ports are opened and masqueraded, and subscribe to a SIP proxy outside: most proxies are able to handle firewalls issues themselves. If not possible read section 7 (Behind a firewall). +Audio problems +
+Linphone seems to connect to the remote SIP url, it rings, but when the callee answers, nothing happens and we can't hear each other. +
+Using your audio mixer program (eg. 'alsamixer', 'kmix', or 'aumix') make make sure the audio output is not muted and that the playback (master volume, PCM) and recording (mic) controls are set to at least their medium values.If the voice is sometimes interrupted, you can modify parameter RTP->jitter compensation in the property box to greater values to avoid this. But this will also increase the transmission delay.If linphone cannot open the audio device, check if the user has the right permissions to open /dev/dsp, and close all programs able to use audio device (xmms, kaiman...), as at this point linphone cannot share the audio device with other applications.Use ALSA drivers (see http://www.alsa-project.org). Most distributions still use the old OSS kernel-official drivers, that have big latency problems and are often buggy. ALSA drivers are much better.
+Bugs reporting and suggestions +First go to linphone's home page at http://www.linphone.org to check if you have the latest version if linphone. +If linphone crashes, send a report to the mailing list, linphone-users@nongnu.org. If linphone does not work, but does not crash, please ensure you have read this manual in its entirety before sending a bug report at the above address. You can also send e-mail to the mailing list to request a specific feature, that you think is missing from linphone. Note that video support, and conferencing are planned features. If someone is interested in helping with the translations of linphone to other languages, s/he can send me a xx.po file based on the po/linphone.pot file of the distribution. You can also translate this user manual in other languages. In any case, please contact me if you want more details. +Authors +Simon MORLAT (simon.morlat@linphone.org) wrote: +main library (coreapi)gnome interface (thanks to glade !)RTP library (oRTP)audio/video framework and wrappers (mediastreamer)Aymeric Moizard (jack@atosc.org) wrotes the osip and eXosip stacks that is used by linphone. +The speex codec http://www.speex.org is a high quality low bitrate codec by Jean Marc Valin. +The GSM library was written by : Jutta Degener and Carsten Bormann,Technische Universitaet Berlin. +The LPC10-1.5 library was written by: Andy Fingerhut Applied Research Laboratory <-- this line is optional if Washington University, Campus Box 1045/Bryan 509 you have limited space One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wustl.edu http://www.arl.wustl.edu/~jaf/ See text files in gsmlib and lpc10-1.5 directories for further information. +Icons by Pablo Marcelo Moia. +Thanks +Thanks to Daemon Chaplin, for having done Glade, the gtk interface builder. +Thanks to Aymeric Moizard, for his famous oSIP library. +Thanks to Florian Winstertein, for the console interface of linphone. +Thanks to Jean Marc Valin, for his great speex codec. +Thanks to the authors of LPC10-1.5 and GSM code. +Thanks to Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) for his RPMS. +Thanks to Pablo Marcelo Moia for the great icons he has made for linphone. +
\ No newline at end of file diff --git a/linphone/share/C/manual/.cvsignore b/linphone/share/C/manual/.cvsignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/linphone/share/C/manual/.cvsignore @@ -0,0 +1 @@ +*.html diff --git a/linphone/share/C/sipomatic.1 b/linphone/share/C/sipomatic.1 new file mode 100644 index 000000000..a1f21e8cf --- /dev/null +++ b/linphone/share/C/sipomatic.1 @@ -0,0 +1,70 @@ +.\" Sipomatic is a SIP phone server. It answers automatically to incoming calls by playing a short message. +.TH "sipomatic" "1" "1.0.0" "Simon Morlat" "linphone" +.SH "NAME" +.LP +sipomatic \- SIP auto\-responder from the linphone project. +.SH "SYNTAX" +.LP +sipomatic [\fI\-u\fP] <\fIsip\-url\fP> [\fI\-f\fP] <\fIannouce\-file\fP> [\fI\-s\fP] <\fIsend\-port\fP> +.LP +sipomatic \fI\-v\fP +.br +sipomatic \fI\-\-version\fP +.LP +sipomatic \fI\-h\fP +.br +sipomatic \fI\-\-help\fP +.SH "DESCRIPTION" +.LP +Sipomatic is primilarly a test tool for linphone. +It waits for incoming sip calls, and answer to them by playing a wav sound file on disk. The sended stream is encoded using the preferred codec of the calling sip\-phone. +.br +The default address of sipomatic is +It can be overriden with the \-u option. +.br +The default annouce file 'hello.wav' can be overriden with the \-f option. +.br +If you attempt to run several sipomatic on the same machine, then you will require the \-s option to specify explicitely the UDP port used by sipomatic to send its SIP messages. + +.SH "OPTIONS" +.LP +.TP +\fB\-u\fR <\fIurl\fP> +Set the sip url sipomatic listens to. The host part of address MUST always be a numerical ip address. The default url is sip:robot@127.0.0.1:5064 . +.TP +\fB\-f\fR <\fIannouce\-file\fP> +Specifies a 8000Hz 16 bits wav file to be played to the calling users. Default is usually /usr/share/sounds/linphone/hello.wav. +.TP +\fB\-s\fR <\fIsend\-port\fP> +Specifies explicitely the udp port number to be used to send SIP messages. +.TP +\fB\-v\fR +\fB\-\-version\fR +Output version information and exits. +.TP +\fB\-h\fR +\fB\-\-help\fR +Output help information and exits. +.TP +.SH "FILES" +.LP +\fI/usr/share/sounds/linphone/hello.raw\fP +.br +This is the file that sipomatic plays by default to the calling phones. +The format of this file is a 8000 Hz 16 bit wav file. +.br + +.SH "ENVIRONMENT VARIABLES" +.LP +.TP +\fBSIPOMATIC_URL\fP +Specifies the address sipomatic listens to. By default it is + . +.SH "EXAMPLES" + +.SH "AUTHORS" +.LP +Simon MORLAT +.SH "SEE ALSO" +.LP +linphone(1) linphonec(1) diff --git a/linphone/share/Makefile.am b/linphone/share/Makefile.am new file mode 100644 index 000000000..a15fe2ea7 --- /dev/null +++ b/linphone/share/Makefile.am @@ -0,0 +1,36 @@ + +SUBDIRS=C fr it ja cs + +LINPHONE_SOUNDS=ringback.wav hello8000.wav hello16000.wav +LINPHONE_RINGS=rings/orig.wav \ + rings/oldphone.wav \ + rings/rock.wav \ + rings/bigben.wav \ + rings/toy.wav \ + rings/sweet.wav \ + rings/synth.wav \ + rings/tapping.wav + +sounddir=$(datadir)/sounds/linphone + +sound_DATA=$(LINPHONE_SOUNDS) + +ringdir=$(datadir)/sounds/linphone/rings + +ring_DATA=$(LINPHONE_RINGS) + +#to be compliant with freedesktop.org: +linphone_fddir= $(datadir)/applications +linphone_fd_DATA= linphone.desktop + + +pkgconfigdir=$(libdir)/pkgconfig +pkgconfig_DATA=linphone.pc + +EXTRA_DIST = $(LINPHONE_SOUNDS) \ + $(LINPHONE_RINGS) \ + linphone.gnorba \ + linphone.desktop \ + linphone_applet.desktop \ + linphone.pc.in \ + Makefile.inc diff --git a/linphone/share/Makefile.inc b/linphone/share/Makefile.inc new file mode 100644 index 000000000..7deb66aae --- /dev/null +++ b/linphone/share/Makefile.inc @@ -0,0 +1,25 @@ +linphone_manualdir = $(datadir)/gnome/help/linphone/$(HELPLANG)/ + +linphone_help = \ + $(top_builddir)/share/$(HELPLANG) + +if ENABLE_MANUAL +all-local: $(linphone_help)/manual.html +else +all-local: +endif + +$(linphone_help)/manual.html: + rm -f $(linphone_help)/manual.html + sgmltools $(srcdir)/manual.sgml + +install-data-local: + $(mkdir_p) $(DESTDIR)/$(linphone_manualdir) + -cp -f $(linphone_help)/*.html $(DESTDIR)/$(linphone_manualdir)/. + -cp -f $(linphone_help)/*.css $(DESTDIR)/$(linphone_manualdir)/. + +uninstall-local: + rm -rf $(linphone_manualdir) + + +EXTRA_DIST= manual.lyx manual.sgml diff --git a/linphone/share/cs/.cvsignore b/linphone/share/cs/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/linphone/share/cs/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/linphone/share/cs/Makefile.am b/linphone/share/cs/Makefile.am new file mode 100644 index 000000000..8bd5c4057 --- /dev/null +++ b/linphone/share/cs/Makefile.am @@ -0,0 +1,8 @@ + +HELPLANG=cs + +mandir=@mandir@/$(HELPLANG) + +man_MANS = linphone.1 linphonec.1 sipomatic.1 + +EXTRA_DIST=$(man_MANS) diff --git a/linphone/share/cs/linphone.1 b/linphone/share/cs/linphone.1 new file mode 100644 index 000000000..2e9967cc0 --- /dev/null +++ b/linphone/share/cs/linphone.1 @@ -0,0 +1,49 @@ +.\" Encoding: ISO-8859-2 +.\" Linphone is an internet phone compatible with the Session Initiation Protocol (SIP: RFC3261 ) +.\" Translation into Czech by Petr Písaø , 2006-02-26 +.TH "linphone" "1" "1.0.0" "Simon Morlat" "linphone" +.do hla cs +.do hpf hyphen.cs +.SH "JMÉNO" +.LP +linphone \- Gnome rozhraní pro linphone, internetový telefon podporující SIP. +.SH "SYNTAXE" +.LP +linphone [\fI\-\-help\fP] [\fI\-\-verbose\fP] + +.SH "POPIS" +.LP +Linphone mù¾e být spu¹tìn bez jakýchkoliv parametrù. V¹echny parametry jsou +mìnitelné v nabídce Nastavení. + +.SH "VOLBY" +.LP +.TP +\fB\-\-help\fR +Vypí¹e tuto nápovìdu a skonèí. +.TP +\fB\-\-version\fR +Vypí¹e verzi programu a skonèí. +.TP +\fB\-\-verbose\fR +Na standardní výstup vypisuje vnitøní hlá¹ení programu. Toto je vhodné pøi +ladìní. +.SH "SOUBORY" +.LP +\fI~/.gnome2/linphone\fP +.br +Odtud linphone naèítá svoji konfiguraci. Tento soubor nemusíte mìnit. +.br + +.SH "PROMÌNNÉ PROSTØEDÍ" + +.SH "PØÍKLADY" + +.SH "AUTOØI" +.LP +Simon MORLAT +Pro podrobnosti nahlédnìte do souboru AUTHORS, který je souèástí zdrojových +kódù linphone. +.SH "VIZ TAKÉ" +.LP +linphonec(1) sipomatic(1) diff --git a/linphone/share/cs/linphonec.1 b/linphone/share/cs/linphonec.1 new file mode 100644 index 000000000..3073c824f --- /dev/null +++ b/linphone/share/cs/linphonec.1 @@ -0,0 +1,76 @@ +.\" Encoding: ISO-8859-2 +.\" Linphone is an internet phone compatible with the Session Initiation Protocol (SIP: RFC3261 ) +.\" Translation into Czech by Petr Písaø , 2006-02-26 +.TH "linphonec" "1" "1.0.0" "Florian Winterstein & Simon MORLAT" "linphone, internetový telefon" +.do hla cs +.do hpf hyphen.cs +.SH "JMÉNO" +.LP +linphonec \- Øádkové rozhraní k linphone, internetový telefon podporující SIP. +.SH "SYNTAXE" +.LP +linphonec [\fI\-d\fP] <\fIúroveò_ladìní\fP> [\fI\-l\fP] <\fIlogovací_soubor\fP> +[\fI\-c\fP] <\fIkonfiguraèní_soubor\fP> +.br +linphonec \fI\-v\fP +.SH "POPIS" +.LP +Linphonec je konzolová verze internetového telefonu linphone urèeného pro +Gnome prostøedí (http://www.linphone.org). +.LP +Linphonec mù¾e být spu¹tìn bez jakýchkoliv parametrù. Pro správné spu¹tìní +nepotøebuje ¾ádný konfiguraèní soubor. Pokud ten neexistuje, pøi prvním spu¹tìní +bude vytvoøen vzorový. +Standardnì je konfiguraèní soubor ulo¾en v ~/.linphonerc. +Vìt¹ina parametrù (proxy, hesla) mù¾e být zmìnìna z pøíkazové øádky. Nìkteré +z nich (cesta k souboru s vyzvánìním) v¹ak lze zmìnit jen úpravou +konfiguraèního souboru .linponerc. +.LP +Jakmile je linphonec spu¹tìn, oèekává pøíkazy a je pøipraven pøijímat hovory. +.LP +Nejdùle¾itìj¹í pøíkazy jsou: +.br +.TP +call zavolat nìkomu. sip_url je ve tvaru sip:user@host +.TP +terminate ukonèit hovor +.TP +answer pøijmout pøíchozí hovor +.TP +help zobrazit interaktivní nápovìdu + +.SH "VOLBY" +.LP +.TP +\fB\-d\fR <\fIúroveò_ladìní\fP> +Pou¾ije ladící re¾im s danou mírou upovídanosti (úroveò_ladìní). úroveò_ladìní +je celé èíslo v rozsahu 0..5. +.TP +\fB\-h\fR +Vypí¹e nápovìdu a skonèí. +.TP +\fB\-l\fR <\fIlogovací_soubor\fP> +Urèuje soubor, kam budou zapisovány ladící informace. Jinak se pou¾ije +standardní výstup. +.TP +\fB\-c\fR <\fIkonfiguraèní_soubor\fP> +Urèuje konfiguraèní soubor, který bude naèten pøi spu¹tìní. + +.SH "SOUBORY" +.LP +\fI~/.linphonec\fP +.br + +.SH "PROMÌNNÉ PROSTØEDÍ" +.LP +.SH "PØÍKLADY" +.LP + +.SH "AUTOØI" +.LP +Florian Winterstein +.br +Simon Morlat +.SH "VIZ TAKÉ" +.LP +linphone(1) sipomatic(1) diff --git a/linphone/share/cs/sipomatic.1 b/linphone/share/cs/sipomatic.1 new file mode 100644 index 000000000..bf9d35ca0 --- /dev/null +++ b/linphone/share/cs/sipomatic.1 @@ -0,0 +1,82 @@ +.\" Encoding: ISO-8859-2 +.\" Sipomatic is a SIP phone server. It answers automatically to incoming calls by playing a short message. +.\" Translation into Czech by Petr Písaø , 2006-02-26 +.TH "sipomatic" "1" "1.0.0" "Simon Morlat" "linphone" +.do hla cs +.do hpf hyphen.cs +.SH "JMÉNO" +.LP +sipomatic \- SIP auto\-responder z projektu linphone. +.SH "SYNTAXE" +.LP +sipomatic [\fI\-u\fP] <\fIsip\-url\fP> [\fI\-f\fP] <\fInahrávka\fP> +[\fI\-s\fP] <\fIodchozí_port\fP> +.LP +sipomatic \fI\-v\fP +.br +sipomatic \fI\-\-version\fP +.LP +sipomatic \fI\-h\fP +.br +sipomatic \fI\-\-help\fP +.SH "POPIS" +.LP +Sipomatic je základní testovací nástroj pro linphone. +Èeká na pøíchozí sipový hovor a odpoví na nìj pøehráním zvukového souboru typu +WAV z disku. Odeslaný zvukový proud je kódován preferovaným kodekem volajícího +sipového telefonu. +.LP +Výchozí adresa sipomaticu je . Mù¾e být zmìnìna +volbou \-u. +.br +Namísto výchozího oznamovacího souboru "hello.wav" lze vybrat jiný volbou \-f. +.br +Jestli¾e se budete pokou¹et spustit více sipomatic klientù na jednom stroji, +pak budete potøebovat volbou \-s explicitnì urèit UDP port, který bude pou¾it +k odeslání vlastních SIP zpráv. + +.SH "VOLBY" +.LP +.TP +\fB\-u\fR <\fIurl\fP> +Nastaví SIP URL, na které bude sipomatic poslouchat. Èást adresy se jménem +poèítaèe MUSÍ být v¾dy èíselná IP adresa. Výchozí URL je sip:robot@127.0.0.1:5064 +.TP +\fB\-f\fR <\fInahrávka\fP> +Urèuje 8000Hz 16bitový WAV soubor, který bude pøehrán volajícímu u¾ivateli. +Výchozí cesta bývá /usr/share/sounds/linphone/hello.wav. +.TP +\fB\-s\fR <\fIodchozí_port\fP> +Explicitnì definuje èíslo UDP portu, který bude pou¾it pro odchozí SIP zprávy. +.TP +\fB\-v\fR +\fB\-\-version\fR +Vytiskne informace o verzi a skonèí. +.TP +\fB\-h\fR +\fB\-\-help\fR +Vypí¹e nápovìdu a skonèí. +.LP +.SH "SOUBORY" +.LP +\fI/usr/share/sounds/linphone/hello.raw\fP +.br +Toto je soubor, který sipomatic standardnì pøehraje volajícímu telefonu. +Formát tohoto souboru je WAV vzorkovaný 16bitovou hodnotou s frekvencí +8000 Hz. +.br + +.SH "PROMÌNNÉ PROSTØEDÍ" +.LP +.TP +\fBSIPOMATIC_URL\fP +Definuje adresu, na které sipomatic poslouchá. Jinak je pou¾ita + +.SH "PØÍKLADY" + +.SH "AUTOØI" +.LP +Simon MORLAT +.SH "VIZ TAKÉ" +.LP +linphone(1) linphonec(1) diff --git a/linphone/share/fr/.cvsignore b/linphone/share/fr/.cvsignore new file mode 100644 index 000000000..e1d20773b --- /dev/null +++ b/linphone/share/fr/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +manual +manual.junk +manual.html diff --git a/linphone/share/fr/Makefile.am b/linphone/share/fr/Makefile.am new file mode 100644 index 000000000..6da5a815c --- /dev/null +++ b/linphone/share/fr/Makefile.am @@ -0,0 +1,3 @@ +HELPLANG=fr + +include ../Makefile.inc diff --git a/linphone/share/fr/manual.lyx b/linphone/share/fr/manual.lyx new file mode 100644 index 000000000..793c7f4c6 --- /dev/null +++ b/linphone/share/fr/manual.lyx @@ -0,0 +1,745 @@ +#LyX 1.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 218 +\textclass docbook +\language french +\inputencoding latin1 +\fontscheme default +\graphics default +\paperfontsize default +\spacing single +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language french +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + + +\begin_inset LatexCommand \label{manual} + +\end_inset + +MANUEL DE L'UTILISATEUR DE LINPHONE +\layout Author + +Simon Morlat (simon.morlat@linphone.org) +\layout Date + +11-13-2001 +\layout Section + +Introduction +\layout Standard + +Linphone est un simple logiciel de téléphonie sur le web. + Il permet d'effectuer des conversations comprenants deux participants en + utilisant un réseau IP comme Internet. + Ainsi, voici l'équipement nécessaire pour utiliser Linphone : +\layout Itemize + +Linux ( Peut fonctionner dans d'autres environnements tels que BSD ou d'autres + UNIX, mais personne ne l'a encore testé.) +\layout Itemize + +Gnome 1.2 ou supérieur, installé mais pas nécessairement utilisé. +\layout Itemize + +Une carte son configuré correctement. +\layout Itemize + +Des écouteurs ou haut-parleurs. +\layout Itemize + +Un micro. +\layout Itemize + +Une connection réseau (Internet par exemple), par modem, carte réseau Ethernet + ... +\layout Standard + +Il est préférable de fermer toutes les applications utilisant la carte son + avant d'utiliser Linphone. + Linphone est un logiciel libre, il est distribué sous la license publique + GNU. +\layout Standard + + +\emph on +ATTENTION : Ce logiciel est distribué SANS GARANTIE. + Lisez le fichier COPYING pour plus de détails. + Ceci signifie entre autre que vous ne devez pas utiliser Linphone pour + des conversations confidentielles : il y a AUCUN CRYPTAGE, de ce fait, + il est peut-être facile pour quelqu'un de mal intentionné de pirater les + flux audios. + Notez toutefois, qu'il n'est pas recommandé d'utiliser Linphone en tant + qu'utilisateur root. +\layout Section + +Utilisation +\layout Standard + +Linphone peut être utilisé suivant 3 modes différents : +\layout Itemize + +En tant qu'application (normale) : Dans le menu de Gnome, Linphone devrait + apparaître dans la section Réseau ( "Network" ). + Si vous n'utilisez pas Gnome, vous pouvez démarrer Linphone dans une fenêtre + terminal par exemple. + Quand Linphone n'est pas en cours d'éxecution, vous ne pouvez pas recevoir + d'appel(s). +\layout Itemize + +En tant qu'applet Gnome : en cliquant sur le panneau Gnome du bouton droit, + ajoutez l'applet. + Linphone apparait dans la section Réseau. + En tournant en tâche de fond dans le panneau Gnome, Linphone est capable + de recevoir des appel(s) même si sa fenêtre n'est pas visible. + Si vous voulez voir la fenêtre principale, cliquez sur l'applet. + Quand un appel arrive, la fenêtre principale passe en premier plan,et vous + entendrez normalement la sonnerie retentir. +\layout Itemize + +En tant que démon : Ceci est intéressant pour les non-utilisateurs de Gnome. + Par exemple pour KDE, vous avez un repertoire /home/user/.kde2/AutoStart/ + où vous pouvez rajouter les applications que vous voulez voir démarrer + à votre début de session. + Ainsi, dans le repertoire cité, à l'aide du gestionnaire de fichiers, ajouter + un lien en cliquant du bouton droit. + La commande à rentrer est "linphone -daemon". + Vous ne verrez pas l'interface de Linphone, donc, pour la faire apparaitre, + démarrez Linphone normalement, par exemple à travers une fenêtre terminal. +\layout Section + +Comment appeler +\layout Subsection + +Principes de base +\layout Standard + +Linphone utilise le protocole SIP (Session Initiation Protocol) pour établir + les appels avec vos correspondants. + Le protocole spécifie que chaque personne doit être identifié par une URL + sip de la forme: sip:user_name@host_name. + Cette manière d'adresser les personnes est très proche de celle utilisée + pour le courrier électronique. +\layout Standard + +User_name est un nom d'utilisateurs sur une machine, comme un nom de login + sur une machine linux, par exemple. + Host_name est le nom d'une machine, soit sous forme d'adresse IP, ou plus + simplement sous forme de nom de domaine (ex: linphone.org) +\layout Standard + +Notez que SIP est un nouveau protocole de télécommunication fait pour être + simple et efficace sur l'internet, et qu'il est totalement différent et + incompatible avec H.323. + H.323 est le protocole actuellement utilisé par NetMeeting ou GnomeMeeting. +\layout Subsection + +Application: deux personnes (Bob et Tom) se connectent à internet par un + modem analogique classique. +\layout Standard + +Voici la manière la plus simple de procéder : +\layout Standard + +Pré-requis : +\layout Itemize + +Un modem 28.8 Baud ou plus. + +\layout Standard + +Déroulement : +\layout Itemize + +Il est convenu que Bob doit appeler Tom à 21h00. + A 21h00, Tom se connecte à Internet en utilisant kppp, gppp ou wvdial (ou + un autre). + Dès qu'il est connecté sur l'Internet, il peut lancer Linphone.En ouvrant + la fenêtre de statistiques de kppp ou gppp, il peut voir son adresse IP + (sinon, il peut taper /sbin/ifconfig pour l'obtenir). + Le nom de l'interface modem doit être ppp0. +\layout Itemize + +Ensuite, il envoit un email à Bob disant : "Mon adresse IP estxxx.xxx.xxx.xxx". +\layout Itemize + +Bob recoit l'email et tape dans la fenêtre de Linphone le nom est l'adresse + IP de la personne à contacter : Tom@xxx.xxx.xxx.xxx(L'adresse IP de Tom) et + pour finir, il appuit sur le bouton Appeler. + +\layout Itemize + +Linphone sonne à la maison de Tom ...Tom a juste à répondre à l'appel en cliquant + sur le bouton "répondre" et ainsi devrait pouvoir commencer la discussion. + +\layout Standard + +Si vous rencontrez des problèmes dans une de ces étapes, allez à la section + 4-Problèmes. +\layout Subsection + +Essai en local: vous n'avez personne à appeler pour l'instant, mais vous + souhaiteriez voir si linphone marche vraiment. +\layout Standard + + +\begin_inset LatexCommand \label{sipomatic} + +\end_inset + +Depuis la version 0.3.0, Linphone est livré avec un programme de test appelé + "sipomatic". + Sipomatic peut répondre automatiquement aux appels provenant de Linphone. + A vous d'essayer : +\layout Itemize + +Demarrez linphone. +\layout Itemize + +Démarrez sipomatic dans une fenêtre terminal. + Ne soyez pas supris, sipomatic ne possède aucune interface graphique, mais + vous n'avez pas besoin de modifier quoi-que-ce-soit. + +\layout Itemize + +Dans Linphone, allez dans les propriétés, section réseau, et choisissez + "lo" comme interface par défaut. + Appliquez les changements en cliquant sur OK. + Tapez l'adresse S.I.P suivante dans la fenêtre principale : sip:robot@127.0.0.1:5064. + 127.0.0.1 est l'adresse locale de votre ordinateur, et robot est le nom à + utiliser pour appeler sipomatic. + 5064 est le port par lequel sipomatic peut-être contacté. + Normalement, vous devez toujours utiliser 5060 pour appeler quelqu'un, + mais sipomatic est une exception : il fonctionne sur le port 5064. + La raison est que Linphone fonctionne déjà sur le port 5060, et il est + impossible d'avoir deux applications utilisant le même port au même instant, + sur la même machine. + +\layout Itemize + +Appuyez sur le bouton "Appeler". + Après quelques secondes, sipomatic devrait répondre à votre appel et vous + devez entendre une courte annonce. +\layout Section + + +\begin_inset LatexCommand \label{params} + +\end_inset + +Paramètres des appels +\layout Subsection + + +\begin_inset LatexCommand \label{paramnetwork} + +\end_inset + +Réseau +\layout Itemize + +Liste des interfaces réseau: vous devez choisir une interface réseau à utiliser + avec Linphone. + Si vous voulez contacter quelqu'un sur l'Internet, vous devez choisir l'interfa +ce réseau connectée à l'Internet. + Par exemple, si vous utilisez un modem, celle-ci devrait être ppp0. + Si vous n'êtes connecté à aucun réseau, seulement l'interface réseau locale + appelé lo apparaitra dans la liste. + La seule chose que vous pouvez faire dans ce cas la est d'appeler +\begin_inset LatexCommand \ref[sipomatic]{sipomatic} + +\end_inset + +. +\layout Itemize + +Type de connection: choisissez le type de connection que vous utilisez pour + vous connecter au réseau que vous désirez utiliser. + Ceci aidera Linphone à s'auto-configurer en fonction de la bande passante + de votre type de connection. +\layout Subsection + + +\begin_inset LatexCommand \label{paramrtp} + +\end_inset + +RTP +\layout Standard + +RTP signifie Real Time Protocol, il permet d'envoyer des flux de données + multimedia. +\layout Itemize + +port RTP: Linphone utilise le port 7072 par défaut pour envoyer et recevoir + des signaux audios. + Si vous pensez que le port 7072 est utilisé par une autre application, + changez le comme vous voulez. +\layout Itemize + +Jitter compensation: ce nombre représente le nombre de paquets audios que + Linphone attend avant de vous les faire entendre. + Augmentez ce nombre si vous entendez une voix hachée de manière à améliorer + la qualité de la transmission, mais attention, ceci augmente le delai (vous + entendrez la voix de l'utilisateur distant quelques millisecondes plus + tard).D'un autre côté, si vous utilisez un réseau parfait, et que vous disposez + de bon drivers audios, vous pouvez descendre ces paramètres très bas jusqu'à + 3 paquets, ainsi vous aurez un délai très faible. +\layout Subsection + + +\begin_inset LatexCommand \label{paramsip} + +\end_inset + +SIP +\layout Standard + +SIP (Session Initiation Protocol) est un protocole qui permet d'établir + des sessions de téléphonie par l'intermédiaire d'un réseau IP. + En simplifiant, c'est la chose qui permet de faire sonner chez l'autre + utilisateur, démarrer ou terminer l'appel quand l'un des deux correspondants + raccroche. +\layout Itemize + +port SIP: Linphone utilise par défaut le port 5060 pour envoyer / recevoir + des paquets SIP. + Il est hautement recommandé par la RFC du protocole SIP d'utiliser celui-ci. + Donc, ne le changez pas à moins que vous n'ayez vraiment pas le choix. +\layout Itemize + +Votre adresse SIP: modifiez ici votre nom d'utilisateur et votre nom de + machine à votre gré. + Bien entendu donner un nom de machine ici ne signifie pas que ce nom soit + connue des autres machines du réseau. + Néammoins linphone utilisera peu ce nom de machine et préfèrera utiliser + votre adresse IP pour communiquer avec d'autres machines. +\layout Itemize + +Utiliser un serveur sip registrar: Cochez ce choix, si vous voulez vous + enregistrer sur un serveur SIP (registrar) pour obtenir différents services. + Quand vous n'avez pas d'adresse IP fixe, cela peut-être très intéressant + pour permettre à vos amis de vous appeler. + Regardez la section intitulée " +\begin_inset LatexCommand \ref[enregistrement sur un serveur sip]{registering} + +\end_inset + +". +\layout Subsection + + +\begin_inset LatexCommand \label{paramcodec} + +\end_inset + +Codecs +\layout Standard + +Les codecs sont des algorithmes utilisés pour compresser la voix. + Par exemple, une voix digitalisée en 16bit/8000Hz représente un flux de + données de 128kbits/seconde. + En utilisant le vocodeur GSM, ce flux est réduit à 13kbits/seconde, sans + perte significative de qualité. +\layout Itemize + +Choix de codecs: Linphone peut utiliser plusieurs codecs. + Utilisez les boutons situés en dessous de la liste des codecs de manière + à les placer dans un order de préférence. + Notez bien, qu'en fonction de votre type de connection réseau, certains + codecs sont inutilisables.Ils apparaitront en rouge et ne seront pas sélectionna +ble. + Vous pouvez décider d'utiliser ou non un codec "utilisable" (en bleu) en + changeant son état à l'aide du bouton activer/désactiver en dessous de + la liste. +\layout Subsection + + +\begin_inset LatexCommand \label{paramaudio} + +\end_inset + +Audio parameters +\layout Itemize + +Mode de pilotage: si vous avez installé des drivers ALSA avec une librairie + ALSA <0.9, choisissez ALSA pour avoir de meilleires performances. + Sinon, ou si vous n'en savez rien, choisissez OSS, cela marche suffisemment + bien. +\layout Itemize + +Choix de la source d'enregistrement: vous pouvez choisir votre source d'enregist +rement pour la voix. + Dans la plupart des cas, celle-ci sera le microphone. +\layout Itemize + +Auto-kill option: en choissant cette option, Linphone essaiera de stopper + les processus sonores (esd & artsd) qui peuvent bloquer votre périphérique + sonore et ainsi provoquer des problèmes d'ouverture des périphériques par + Linphone quand il en a besoin. + Il est recommandé d'activer cette option. +\layout Section + +Carnet d'adresses +\layout Standard + +Depuis la version 0.4.1 linphone dispose d'un carnet d'adresses (menu connexion, + carnet d'addresses), avec lequel vous pouvez memoriser des adresses, et + les rappeler facilement lorsque vous souhaitez appeler. +\layout Section + + +\begin_inset LatexCommand \label{registering} + +\end_inset + +Enregistrement sur un serveur sip +\layout Standard + +Vous pouvez souscrire des services sur des serveurs sip distants appelés + registrar, proxy ou redirect server. + Ces services peuvent être: +\layout Standard + +You can suscribe for services on remote SIP servers. + These services can be: +\layout Itemize + +redirection: linphone va demander au serveur la création d' un compte . + Cette adresse pourra alors être utilisée par vos correspondants pour vous + joindre. + Un petit example concret pour bien comprendre: vous n'êtes qu'un pauvre + internaute connecté temporairement grace à un modem 56k. + Votre machine n'a pas de nom de domaine connu et votre adresse IP change + à chaque nouvelle connexion. + Il est impossible pour vos amis de vous joindre car il ne peuvent deviner + votre adresse IP, à moins que vous ne leur donniez en envoyant un courriel, + par exemple. + Pour palier à ce problème, vous pouvez demander à avoir un compte sur un + serveur sip connu de vos amis, qui lui est fixe et tout le temps connecté. + Pour cela, spécifiez l'adresse du serveur dans la boite de propriété, section + sip. + Cette adresse est par exemple et votre nom d'utilisate +ur est +\begin_inset Quotes fld +\end_inset + +Bob +\begin_inset Quotes frd +\end_inset + +. + Linphone va alors envoyer au serveur un message pour l'informer de la correspon +dance entre l'adresse et votre adresse IP actuelle. + Desormais vos amis peuvent vous appeler en utilisant cette nouvelle adresse, + leurs appels seront alors automatiquement redirigés vers votre machine. + Il n'ont plus besoin de connaitre votre adresse IP qui change tout le temps + pour vous joindre. + Bien sur, est supposée être bien connue de tout + vos amis. + +\layout Itemize + +proxy: c'est exactement le meme principe, excepté que la redirection se + fait de manière transparente et invisible le linphone de l'appelant. +\layout Standard + +Le registrar que vous avez spécifié peut aussi être utilisé comme proxy + sortant. + Dans ce cas tous les appels émanant de votre linphone seront dirigé vers + ce serveur, et il sera supposé les faire suivre vers les bonnes personnes. + Ceci est très utile et même indispensable lorsque vous utilisez linphone + dans un réseau privé abrité par un firewall, si bien sur un proxy sip est + actif sur le firewall. + +\layout Standard + +Pour utiliser solliciter un serveur sip, vous devez aller à la boîte de + propriété, rubrique SIP, et cocher le bouton qui se trouve en face de "use + registrar". + Tapez l'adresse du registrar, et choisissez un nom d'utilisateur qui n'est + pas trop fréquent de manière à éviter les conflits de noms. + Donnez une indication du service que le serveur doit effectuer pour vous + en cochant les boutons +\begin_inset Quotes fld +\end_inset + +redirection +\begin_inset Quotes frd +\end_inset + + ou +\begin_inset Quotes fld +\end_inset + +proxy +\begin_inset Quotes frd +\end_inset + +. + Sélectionnez aussi l'option +\begin_inset Quotes fld +\end_inset + +le serveur est un proxy sortant +\begin_inset Quotes frd +\end_inset + + si vous êtes derrière un pare-feu. +\layout Standard + +Enfin en fermant la boite de propriétés linphone communiquera immédiatement + avec le serveur SIP pour y obtenir les services demandés. + De même lorsque vous fermez linphone, celui ci prendra quelques secondes + pour se désenregistrer auprès du serveur. +\layout Standard + +Une liste de serveurs sip peut être trouvée à cette addresse: +\begin_inset LatexCommand \url[http://www.cs.columbia.edu/~hgs/sip/servers.html]{http://www.cs.columbia.edu/~hgs/sip/servers.html} + +\end_inset + +. + Malheureusement, beaucoup de ces serveurs ne fonctionnent plus, peut-être + à cause de la crise et de ses faillites. + Certains ne sont pas utilisables car ils requierent des méthodes d'autentificat +ion qui ne sont pas encore implémentées dans linphone. + Afin donc de ne pas vous faire perdre votre temps, une liste des serveurs + sip publiques fonctionnant avec linphone est disponible sur +\begin_inset LatexCommand \url[http://simon.morlat.free.fr/english/servers.html]{http://simon.morlat.free.fr/english/servers.html} + +\end_inset + +. +\layout Section + +Utilisation derrière les pares-feux +\layout Standard + +Linphone est capable de fonctionner derrière les firewalls grâce à un serveur + proxy SIP fonctionnant sur la machine firewall. + Un tel serveur est en cours de développement sur +\begin_inset LatexCommand \url[http://osipproxy.sourceforge.net]{http://osipproxy.sourceforge.net} + +\end_inset + +. + Bien sûr il sera libre et basé sur la librairie LGPL oSIP. +\layout Standard + +Une fois le proxy serveur mis en place, il vous faut configurer linphone + pour qu'il l'utilise. + Pour cela rendez vous dans la boite de propriétés, section SIP et cochez + la case +\begin_inset Quotes fld +\end_inset + +Utiliser un registrar SIP +\begin_inset Quotes frd +\end_inset + +, indiquez son adresse, et cocher l'option +\begin_inset Quotes fld +\end_inset + +le serveur est un proxy sortant +\begin_inset Quotes frd +\end_inset + +. +\layout Standard + +Il y a un cas pour lequel le proxy n'est pas indispensable: c'est le cas + où les machines du réseau privé possèdent une adresse publique, le firewall + étant là pour filtrer les paquets entrants ou sortants. + Vous devez pour permettre a linphone de fonctionner avec des machines exterieur +es, autoriser le traffic UDP sur le port SIP (par defaut 5060, il est deconseill +é de le changer), et sur le port RTP de chaque linphone du sous réseau. + Le port RTP est paramètrable comme bon vous semble dans la boite de proprietés. +\layout Section + +Problèmes divers +\layout Subsection + +Problèmes de connexion +\layout Quotation + +J'essaye d'appeler mon pote , mais rien ne se passe, + pas de sonnerie. +\layout Standard + +Vous devez vérifier que linphone utilise l'interface réseau qui vous connecte + sur le réseau ou se trouve votre ami. + La liste des interface disponibles est donnée dans la boite de propriété, + section réseau. + Sélectionnez la bonne. + +\layout Standard + +Si le problème persiste, il y a fort à parier que votre ami ne soit pas + joignable actuellement. +\layout Subsection + +Problèmes audio +\layout Quotation + +Linphone semble correctement établir l'appel, il sonne, mais une fois que + le correspondant a décrocher, plus rien ne se passe et on ne s'entend pas. +\layout Itemize + +La plupart des gens ont ce genre de symptome car ils n'ont pas choisi la + bonne interface réseau. + Si vous êtes connectés par modem, ce doit être ppp0. + En aucun cas l'interface +\begin_inset Quotes fld +\end_inset + +lo +\begin_inset Quotes frd +\end_inset + + ne peut permettre d'avoir une communication via le réseau. + Elle ne sert que pour le test local avec sipomatic (voir plus haut). +\layout Itemize + +Augmentez le niveau sonore d'acquisition et de restitution, à l'aide des + potentiomètres situés en bas de la fenêtre principale. +\layout Itemize + +Si la voix de votre correspondant vous semble coupée ou hachée, vous pouvez + essayer d'augmenter le paramètre jitter compensation de l'onglet RTP de + la boite de propriété. + Mais attention, cela augmente la latence en contrepartie. +\layout Itemize + +Si linphone ne peut se servir de la carte son, vérifiez que celle ci n'est + pas utilisée au meme moment par d'autres programmes audio. + +\layout Itemize + +Enfin utilisez les drivers sons alsa (voir +\begin_inset LatexCommand \url[http://www.alsa-project.org]{http://www.alsa-project.org} + +\end_inset + +) , plutôt que les oss fournit avec le kernel linux. + Malheureusement la plupart des distributions utilsent encore ces vieux + pilotes alors qu'ils presentent de nombreux bugs et problèmes de latence. + Les drivers ALSA sont beaucoup plus performants. + Notez que si vous changer vos drivers, vous n'avez nul besoin de recompiler + linphone ou de changer quoi que ce soit a sa configuration. + +\layout Section + +Rapports de bogues et suggestions +\layout Standard + +En premier lieu, allez sur le site de Linphone +\begin_inset LatexCommand \url[http://www.linphone.org]{http://www.linphone.org} + +\end_inset + + afin de vérifier que vous ayez bien la dernière version de Linphone. + +\layout Standard + +Si linphone plante, envoyez moi directement un message à bugs@linphone.org. + Si Linphone ne fonctionne pas, mais ne se plante pas, vérifiez bien que + vous avez bien lu ce manuel entièrement avant de m'envoyer un compte rendu + à l'adresse précédente. + Dans tous les cas veillez à m'envoyer le plus d'information possible relatifs + à votre problème, notamment la sortie de debug que linphone écrit lorsque + vous l'executez depuis un terminal. + Si vous désirez autre chose, n'hésitez pas à m'envoyer un email à l'adresse + help@linphone.org. + Prenez note que l'ajout de la vidéo et du mode conférence sont planifiés. + +\layout Standard + +Si quelqu'un est interessé pour faire des traductions de Linphone, envoyez + moi un fichier xx.po basé sur celui se trouvant dans po/linphone.pot de la + distribution. + Vous pouvez aussi traduire ce manuel utilisateur dans d'autres langues. + Dans tous les cas, contactez moi si vous voulez plus de détails. +\layout Section + +Auteurs +\layout Standard + +Simon MORLAT (simon.morlat@linphone.org) a ecrit: +\layout Itemize + +Programme principal (src) +\layout Itemize + +librairie RTP (lprtplib) +\layout Itemize + +osipua : la librarie sip User Agent au dessus d'osip. +\layout Itemize + +interface pour les drivers audio (audio) +\layout Itemize + +les wrappers pour les codecs lpc10-1.5, gsm et g711. + +\layout Standard + +Aymeric Moizard (jack@atosc.org) a ecrit la pile SIP oSIP utilisé par linphone. + +\layout Standard + +La librairie GSM a été écrite par: Jutta Degener and Carsten Bormann,Technische + Universitaet Berlin. +\layout Standard + +La librairie LPC10-1.5 par: Andy Fingerhut Applied Research Laboratory <-- + this line is optional if Washington University, Campus Box 1045/Bryan 509 + you have limited space One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wu +stl.edu http://www.arl.wustl.edu/~jaf/ Lisez les fichiers textes README dans + les repertoire gsmlib et lpc10-1.5 pour plus d'informations. +\layout Standard + +Les icones sont de Pablo Marcelo Moia et le logo de Philippe Beau. +\layout Section + +Remerciements +\layout Standard + +Merci à Daemon Chaplin pour avoir fait Glade, le constructeur d'interface + graphique GTK+. +\layout Standard + +Merci aux auteurs du code des LPC10-1.5 et GSM. +\layout Standard + +Merci à Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) pour ses RPMS. +\layout Standard + +Merci à Pablo Marcelo Moia pour les icones. +\layout Standard + +Merci à Philippe Beau pour la traduction de ce manuel en Francais, pour + le logo, et pour le nouveau site web qu'il a fait pour linphone. +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\the_end diff --git a/linphone/share/fr/manual.sgml b/linphone/share/fr/manual.sgml new file mode 100644 index 000000000..e800f0595 --- /dev/null +++ b/linphone/share/fr/manual.sgml @@ -0,0 +1,488 @@ + + +
+ + + + MANUEL DE L'UTILISATEUR DE LINPHONE + + + Simon Morlat (simon.morlat@linphone.org) + + + 11-13-2001 + + + + + Introduction + + + Linphone est un simple logiciel de téléphonie sur le web. Il permet d'effectuer des conversations comprenants deux participants en utilisant un réseau IP comme Internet. Ainsi, voici l'équipement nécessaire pour utiliser Linphone : + + + + + Linux ( Peut fonctionner dans d'autres environnements tels que BSD ou d'autres UNIX, mais personne ne l'a encore testé.) + + + + + Gnome 1.2 ou supérieur, installé mais pas nécessairement utilisé. + + + + + Une carte son configuré correctement. + + + + + Des écouteurs ou haut-parleurs. + + + + + Un micro. + + + + + Une connection réseau (Internet par exemple), par modem, carte réseau Ethernet ... + + + + + Il est préférable de fermer toutes les applications utilisant la carte son avant d'utiliser Linphone. Linphone est un logiciel libre, il est distribué sous la license publique GNU. + + + ATTENTION : Ce logiciel est distribué SANS GARANTIE. Lisez le fichier COPYING pour plus de détails. Ceci signifie entre autre que vous ne devez pas utiliser Linphone pour des conversations confidentielles : il y a AUCUN CRYPTAGE, de ce fait, il est peut-être facile pour quelqu'un de mal intentionné de pirater les flux audios. Notez toutefois, qu'il n'est pas recommandé d'utiliser Linphone en tant qu'utilisateur root. + + + + + Utilisation + + + Linphone peut être utilisé suivant 3 modes différents : + + + + + En tant qu'application (normale) : Dans le menu de Gnome, Linphone devrait apparaître dans la section Réseau ( "Network" ). Si vous n'utilisez pas Gnome, vous pouvez démarrer Linphone dans une fenêtre terminal par exemple. Quand Linphone n'est pas en cours d'éxecution, vous ne pouvez pas recevoir d'appel(s). + + + + + En tant qu'applet Gnome : en cliquant sur le panneau Gnome du bouton droit, ajoutez l'applet. Linphone apparait dans la section Réseau. En tournant en tâche de fond dans le panneau Gnome, Linphone est capable de recevoir des appel(s) même si sa fenêtre n'est pas visible. Si vous voulez voir la fenêtre principale, cliquez sur l'applet. Quand un appel arrive, la fenêtre principale passe en premier plan,et vous entendrez normalement la sonnerie retentir. + + + + + En tant que démon : Ceci est intéressant pour les non-utilisateurs de Gnome. Par exemple pour KDE, vous avez un repertoire /home/user/.kde2/AutoStart/ où vous pouvez rajouter les applications que vous voulez voir démarrer à votre début de session. Ainsi, dans le repertoire cité, à l'aide du gestionnaire de fichiers, ajouter un lien en cliquant du bouton droit. La commande à rentrer est "linphone -daemon". Vous ne verrez pas l'interface de Linphone, donc, pour la faire apparaitre, démarrez Linphone normalement, par exemple à travers une fenêtre terminal. + + + + + + + Comment appeler + + + + Principes de base + + + Linphone utilise le protocole SIP (Session Initiation Protocol) pour établir les appels avec vos correspondants. Le protocole spécifie que chaque personne doit être identifié par une URL sip de la forme: sip:user_name@host_name. Cette manière d'adresser les personnes est très proche de celle utilisée pour le courrier électronique. + + + User_name est un nom d'utilisateurs sur une machine, comme un nom de login sur une machine linux, par exemple. Host_name est le nom d'une machine, soit sous forme d'adresse IP, ou plus simplement sous forme de nom de domaine (ex: linphone.org) + + + Notez que SIP est un nouveau protocole de télécommunication fait pour être simple et efficace sur l'internet, et qu'il est totalement différent et incompatible avec H.323. H.323 est le protocole actuellement utilisé par NetMeeting ou GnomeMeeting. + + + + + Application: deux personnes (Bob et Tom) se connectent à internet par un modem analogique classique. + + + Voici la manière la plus simple de procéder : + + + Pré-requis : + + + + + Un modem 28.8 Baud ou plus. + + + + + Déroulement : + + + + + Il est convenu que Bob doit appeler Tom à 21h00. A 21h00, Tom se connecte à Internet en utilisant kppp, gppp ou wvdial (ou un autre). Dès qu'il est connecté sur l'Internet, il peut lancer Linphone.En ouvrant la fenêtre de statistiques de kppp ou gppp, il peut voir son adresse IP (sinon, il peut taper /sbin/ifconfig pour l'obtenir). Le nom de l'interface modem doit être ppp0. + + + + + Ensuite, il envoit un email à Bob disant : "Mon adresse IP estxxx.xxx.xxx.xxx". + + + + + Bob recoit l'email et tape dans la fenêtre de Linphone le nom est l'adresse IP de la personne à contacter : Tom@xxx.xxx.xxx.xxx(L'adresse IP de Tom) et pour finir, il appuit sur le bouton Appeler. + + + + + Linphone sonne à la maison de Tom ...Tom a juste à répondre à l'appel en cliquant sur le bouton "répondre" et ainsi devrait pouvoir commencer la discussion. + + + + + Si vous rencontrez des problèmes dans une de ces étapes, allez à la section 4-Problèmes. + + + + + Essai en local: vous n'avez personne à appeler pour l'instant, mais vous souhaiteriez voir si linphone marche vraiment. + + + Depuis la version 0.3.0, Linphone est livré avec un programme de test appelé "sipomatic". Sipomatic peut répondre automatiquement aux appels provenant de Linphone. A vous d'essayer : + + + + + Demarrez linphone. + + + + + Démarrez sipomatic dans une fenêtre terminal. Ne soyez pas supris, sipomatic ne possède aucune interface graphique, mais vous n'avez pas besoin de modifier quoi-que-ce-soit. + + + + + Dans Linphone, allez dans les propriétés, section réseau, et choisissez "lo" comme interface par défaut. Appliquez les changements en cliquant sur OK. Tapez l'adresse S.I.P suivante dans la fenêtre principale : sip:robot@127.0.0.1:5064. 127.0.0.1 est l'adresse locale de votre ordinateur, et robot est le nom à utiliser pour appeler sipomatic. 5064 est le port par lequel sipomatic peut-être contacté. Normalement, vous devez toujours utiliser 5060 pour appeler quelqu'un, mais sipomatic est une exception : il fonctionne sur le port 5064. La raison est que Linphone fonctionne déjà sur le port 5060, et il est impossible d'avoir deux applications utilisant le même port au même instant, sur la même machine. + + + + + Appuyez sur le bouton "Appeler". Après quelques secondes, sipomatic devrait répondre à votre appel et vous devez entendre une courte annonce. + + + + + + + + Paramètres des appels + + + + Réseau + + + + + Liste des interfaces réseau: vous devez choisir une interface réseau à utiliser avec Linphone. Si vous voulez contacter quelqu'un sur l'Internet, vous devez choisir l'interface réseau connectée à l'Internet. Par exemple, si vous utilisez un modem, celle-ci devrait être ppp0. Si vous n'êtes connecté à aucun réseau, seulement l'interface réseau locale appelé lo apparaitra dans la liste. La seule chose que vous pouvez faire dans ce cas la est d'appeler sipomatic. + + + + + Type de connection: choisissez le type de connection que vous utilisez pour vous connecter au réseau que vous désirez utiliser. Ceci aidera Linphone à s'auto-configurer en fonction de la bande passante de votre type de connection. + + + + + + + RTP + + + RTP signifie Real Time Protocol, il permet d'envoyer des flux de données multimedia. + + + + + port RTP: Linphone utilise le port 7072 par défaut pour envoyer et recevoir des signaux audios. Si vous pensez que le port 7072 est utilisé par une autre application, changez le comme vous voulez. + + + + + Jitter compensation: ce nombre représente le nombre de paquets audios que Linphone attend avant de vous les faire entendre. Augmentez ce nombre si vous entendez une voix hachée de manière à améliorer la qualité de la transmission, mais attention, ceci augmente le delai (vous entendrez la voix de l'utilisateur distant quelques millisecondes plus tard).D'un autre côté, si vous utilisez un réseau parfait, et que vous disposez de bon drivers audios, vous pouvez descendre ces paramètres très bas jusqu'à 3 paquets, ainsi vous aurez un délai très faible. + + + + + + + SIP + + + SIP (Session Initiation Protocol) est un protocole qui permet d'établir des sessions de téléphonie par l'intermédiaire d'un réseau IP. En simplifiant, c'est la chose qui permet de faire sonner chez l'autre utilisateur, démarrer ou terminer l'appel quand l'un des deux correspondants raccroche. + + + + + port SIP: Linphone utilise par défaut le port 5060 pour envoyer / recevoir des paquets SIP. Il est hautement recommandé par la RFC du protocole SIP d'utiliser celui-ci. Donc, ne le changez pas à moins que vous n'ayez vraiment pas le choix. + + + + + Votre adresse SIP: modifiez ici votre nom d'utilisateur et votre nom de machine à votre gré. Bien entendu donner un nom de machine ici ne signifie pas que ce nom soit connue des autres machines du réseau. Néammoins linphone utilisera peu ce nom de machine et préfèrera utiliser votre adresse IP pour communiquer avec d'autres machines. + + + + + Utiliser un serveur sip registrar: Cochez ce choix, si vous voulez vous enregistrer sur un serveur SIP (registrar) pour obtenir différents services. Quand vous n'avez pas d'adresse IP fixe, cela peut-être très intéressant pour permettre à vos amis de vous appeler. Regardez la section intitulée "enregistrement sur un serveur sip". + + + + + + + Codecs + + + Les codecs sont des algorithmes utilisés pour compresser la voix. Par exemple, une voix digitalisée en 16bit/8000Hz représente un flux de données de 128kbits/seconde. En utilisant le vocodeur GSM, ce flux est réduit à 13kbits/seconde, sans perte significative de qualité. + + + + + Choix de codecs: Linphone peut utiliser plusieurs codecs. Utilisez les boutons situés en dessous de la liste des codecs de manière à les placer dans un order de préférence. Notez bien, qu'en fonction de votre type de connection réseau, certains codecs sont inutilisables.Ils apparaitront en rouge et ne seront pas sélectionnable. Vous pouvez décider d'utiliser ou non un codec "utilisable" (en bleu) en changeant son état à l'aide du bouton activer/désactiver en dessous de la liste. + + + + + + + Audio parameters + + + + + Mode de pilotage: si vous avez installé des drivers ALSA avec une librairie ALSA <0.9, choisissez ALSA pour avoir de meilleires performances. Sinon, ou si vous n'en savez rien, choisissez OSS, cela marche suffisemment bien. + + + + + Choix de la source d'enregistrement: vous pouvez choisir votre source d'enregistrement pour la voix. Dans la plupart des cas, celle-ci sera le microphone. + + + + + Auto-kill option: en choissant cette option, Linphone essaiera de stopper les processus sonores (esd & artsd) qui peuvent bloquer votre périphérique sonore et ainsi provoquer des problèmes d'ouverture des périphériques par Linphone quand il en a besoin. Il est recommandé d'activer cette option. + + + + + + + + Carnet d'adresses + + + Depuis la version 0.4.1 linphone dispose d'un carnet d'adresses (menu connexion, carnet d'addresses), avec lequel vous pouvez memoriser des adresses, et les rappeler facilement lorsque vous souhaitez appeler. + + + + + Enregistrement sur un serveur sip + + + Vous pouvez souscrire des services sur des serveurs sip distants appelés registrar, proxy ou redirect server. Ces services peuvent être: + + + You can suscribe for services on remote SIP servers. These services can be: + + + + + redirection: linphone va demander au serveur la création d' un compte <sip:votre_nom@le_serveur_sip>. Cette adresse pourra alors être utilisée par vos correspondants pour vous joindre. Un petit example concret pour bien comprendre: vous n'êtes qu'un pauvre internaute connecté temporairement grace à un modem 56k. Votre machine n'a pas de nom de domaine connu et votre adresse IP change à chaque nouvelle connexion. Il est impossible pour vos amis de vous joindre car il ne peuvent deviner votre adresse IP, à moins que vous ne leur donniez en envoyant un courriel, par exemple. Pour palier à ce problème, vous pouvez demander à avoir un compte sur un serveur sip connu de vos amis, qui lui est fixe et tout le temps connecté. Pour cela, spécifiez l'adresse du serveur dans la boite de propriété, section sip. Cette adresse est par exemple <sip:serveur_exemple.com> et votre nom d'utilisateur est “Bob”. Linphone va alors envoyer au serveur un message pour l'informer de la correspondance entre l'adresse <sip:bob@serveur_exemple.com> et votre adresse IP actuelle. Desormais vos amis peuvent vous appeler en utilisant cette nouvelle adresse, leurs appels seront alors automatiquement redirigés vers votre machine. Il n'ont plus besoin de connaitre votre adresse IP qui change tout le temps pour vous joindre. Bien sur, <sip:serveur_exemple.com> est supposée être bien connue de tout vos amis. + + + + + proxy: c'est exactement le meme principe, excepté que la redirection se fait de manière transparente et invisible le linphone de l'appelant. + + + + + Le registrar que vous avez spécifié peut aussi être utilisé comme proxy sortant. Dans ce cas tous les appels émanant de votre linphone seront dirigé vers ce serveur, et il sera supposé les faire suivre vers les bonnes personnes. Ceci est très utile et même indispensable lorsque vous utilisez linphone dans un réseau privé abrité par un firewall, si bien sur un proxy sip est actif sur le firewall. + + + Pour utiliser solliciter un serveur sip, vous devez aller à la boîte de propriété, rubrique SIP, et cocher le bouton qui se trouve en face de "use registrar". Tapez l'adresse du registrar, et choisissez un nom d'utilisateur qui n'est pas trop fréquent de manière à éviter les conflits de noms. Donnez une indication du service que le serveur doit effectuer pour vous en cochant les boutons “redirection” ou “proxy”. Sélectionnez aussi l'option “le serveur est un proxy sortant” si vous êtes derrière un pare-feu. + + + Enfin en fermant la boite de propriétés linphone communiquera immédiatement avec le serveur SIP pour y obtenir les services demandés. De même lorsque vous fermez linphone, celui ci prendra quelques secondes pour se désenregistrer auprès du serveur. + + + Une liste de serveurs sip peut être trouvée à cette addresse: http://www.cs.columbia.edu/~hgs/sip/servers.html. Malheureusement, beaucoup de ces serveurs ne fonctionnent plus, peut-être à cause de la crise et de ses faillites. Certains ne sont pas utilisables car ils requierent des méthodes d'autentification qui ne sont pas encore implémentées dans linphone. Afin donc de ne pas vous faire perdre votre temps, une liste des serveurs sip publiques fonctionnant avec linphone est disponible sur http://simon.morlat.free.fr/english/servers.html. + + + + + Utilisation derrière les pares-feux + + + Linphone est capable de fonctionner derrière les firewalls grâce à un serveur proxy SIP fonctionnant sur la machine firewall. Un tel serveur est en cours de développement sur http://osipproxy.sourceforge.net. Bien sûr il sera libre et basé sur la librairie LGPL oSIP. + + + Une fois le proxy serveur mis en place, il vous faut configurer linphone pour qu'il l'utilise. Pour cela rendez vous dans la boite de propriétés, section SIP et cochez la case “Utiliser un registrar SIP”, indiquez son adresse, et cocher l'option “le serveur est un proxy sortant”. + + + Il y a un cas pour lequel le proxy n'est pas indispensable: c'est le cas où les machines du réseau privé possèdent une adresse publique, le firewall étant là pour filtrer les paquets entrants ou sortants. Vous devez pour permettre a linphone de fonctionner avec des machines exterieures, autoriser le traffic UDP sur le port SIP (par defaut 5060, il est deconseillé de le changer), et sur le port RTP de chaque linphone du sous réseau. Le port RTP est paramètrable comme bon vous semble dans la boite de proprietés. + + + + + Problèmes divers + + + + Problèmes de connexion + +
+ + J'essaye d'appeler mon pote <sip:toto@example.com>, mais rien ne se passe, pas de sonnerie. + +
+ + Vous devez vérifier que linphone utilise l'interface réseau qui vous connecte sur le réseau ou se trouve votre ami. La liste des interface disponibles est donnée dans la boite de propriété, section réseau. Sélectionnez la bonne. + + + Si le problème persiste, il y a fort à parier que votre ami ne soit pas joignable actuellement. + +
+ + + Problèmes audio + +
+ + Linphone semble correctement établir l'appel, il sonne, mais une fois que le correspondant a décrocher, plus rien ne se passe et on ne s'entend pas. + +
+ + + + La plupart des gens ont ce genre de symptome car ils n'ont pas choisi la bonne interface réseau. Si vous êtes connectés par modem, ce doit être ppp0. En aucun cas l'interface “lo” ne peut permettre d'avoir une communication via le réseau. Elle ne sert que pour le test local avec sipomatic (voir plus haut). + + + + + Augemtez le niveau sonore d'acquisition et de restitution, à l'aide des potentiomètres situés en bas de la fenêtre principale. + + + + + Si la voix de votre correspondant vous semble coupée ou hachée, vous pouvez essayer d'augmenter le paramètre jitter compensation de l'onglet RTP de la boite de propriété. Mais attention, cela augmente la latence en contrepartie. + + + + + Si linphone ne peut se servir de la carte son, vérifiez que celle ci n'est pas utilisée au meme moment par d'autres programmes audio. + + + + + Enfin utilisez les drivers sons alsa (voir http://www.alsa-project.org) , plutôt que les oss fournit avec le kernel linux. Malheureusement la plupart des distributions utilsent encore ces vieux pilotes alors qu'ils presentent de nombreux bugs et problèmes de latence. Les drviers ALSA sont beaucoup plus performants. Notez que si vous changer vos drivers, vous n'avez nul besoin de recompiler linphone ou de changer quoi que ce soit a sa configuration. + + + +
+
+ + + Rapports de bogues et suggestions + + + En premier lieu, allez sur le site de Linphone http://www.linphone.org afin de vérifier que vous ayez bien la dernière version de Linphone. + + + Si linphone plante, envoyez moi durectement un message à bugs@linphone.org. Si Linphone ne fonctionne pas, mais ne se plante pas, vérifiez bien que vous avez bien lu ce manuel entièrement avant de m'envoyer un compte rendu à l'adresse précédente. Dans tous les cas veillez à m'envoyer le plus d'information possible relatifs à votre problème, notamment la sortie de debug que linphone ecrit lorsque vous l'executez depuis un terminal. Si vous désirez autre chose, n'hésitez pas à m'envoyer un email à l'adresse help@linphone.org. Prenez note que l'ajout de la vidéo et du mode conférence sont planifiés. + + + Si quelqu'un est interessé pour faire des traductions de Linphone, envoyez moi un fichier xx.po basé sur celui se trouvant dans po/linphone.pot de la distribution. Vous pouvez aussi traduire ce manuel utiisateur dans d'autres langues. Dans tous les cas, contactez moi si vous voulez plus de détails. + + + + + Auteurs + + + Simon MORLAT (simon.morlat@linphone.org) a ecrit: + + + + + Programme principal (src) + + + + + librairie RTP (lprtplib) + + + + + osipua : la librarie sip User Agent au dessus d'osip. + + + + + interface pour les drivers audio (audio) + + + + + les wrappers pour les codecs lpc10-1.5, gsm et g711. + + + + + Aymeric Moizard (jack@atosc.org) a ecrit la pile SIP oSIP utilisé par linphone. + + + La librairie GSM a été écrite par: Jutta Degener and Carsten Bormann,Technische Universitaet Berlin. + + + La librairie LPC10-1.5 par: Andy Fingerhut Applied Research Laboratory <-- this line is optional if Washington University, Campus Box 1045/Bryan 509 you have limited space One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wustl.edu http://www.arl.wustl.edu/˜jaf/ Lisez les fichiers textes README dans les repertoire gsmlib et lpc10-1.5 pour plus d'informations. + + + Les icones sont de Pablo Marcelo Moia et le logo de Philippe Beau. + + + + + Remerciements + + + Merci à Daemon Chaplin pour avoir fait Glade, le constructeur d'interface graphique GTK+. + + + Merci aux auteurs du code des LPC10-1.5 et GSM. + + + Merci à Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) pour ses RPMS. + + + Merci à Pablo Marcelo Moia pour les icones. + + + Merci à Philippe Beau pour la traduction de ce manuel en Francais, pour le logo, et pour le nouveau site web qu'il a fait pour linphone. + + + + + + + +
diff --git a/linphone/share/fr/manual/.cvsignore b/linphone/share/fr/manual/.cvsignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/linphone/share/fr/manual/.cvsignore @@ -0,0 +1 @@ +*.html diff --git a/linphone/share/hello16000.wav b/linphone/share/hello16000.wav new file mode 100644 index 0000000000000000000000000000000000000000..92d44b175952054db105a225110b11da001908a1 GIT binary patch literal 340012 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

-1dqJo41`yzn076UEE$#{ClKqwbKc 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

Cw~ob5Od8INr&4$(Jx+>%SSvAiz9*f*x5Ru& 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 Kt13DP9RCkEe*vlh literal 0 HcmV?d00001 diff --git a/linphone/share/hello8000.wav b/linphone/share/hello8000.wav new file mode 100644 index 0000000000000000000000000000000000000000..b787b202eef3cad48a4635a2006dd65f3f137383 GIT binary patch literal 180268 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%0D3RI3!Nk#}GqF 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

hSTNb?Yi~Gy^op3Enq+6$7mk?k3g9@>li;*-K?Q zrdBqc^smzIWhh2oYp-$BtY>fa?ACkwa|YJvcb#SCut;m;JF5*f_9N`f*kl_l+j;Ei zrTpf?iD#UFL8F|}+L#jA7`m3xHls`MM!1@Jka>E?9_|#OUwxN8&DWJ)n2Uim@dGoZ zW{%JPT8_-g6}(^CR&Z*@q2O2}yPe;hVW{R$R;pWC|HxO#d%)AzE^5{`&RY}R8~BiA zoq1Mw>ks>or>;8DZDMtcsG)_S?vVoEhW-%ohZ?^}_T5Ig@ z7Iz%>qLPVgGhNIa%JxC_DoK@m_1#I~ry1))?agOcQ^(-;i=&VHg?i4r&bvkPD&y&! z|J;uEJX4a?u;-3b4lC*-cLL}l-#h=A)g$ME(?V+_$BZL}5t$z<8|)IS7oKju>*k_M z^ftJW^VFK&Zh;yJy)&&y%APzR^VBTi%()Zx`Fg2q%_8C5;oeB|P2(z3(bY)vm0A|&Hj;|;f9f|ks^^Jk(QB`;dbGv zk$;VmcDlPuxv1^~TV$BGvwusRl2|HfS#qnCx>+71?Fmfq7E+g54UC>he2=O1c&Z_&}txtAQN%*ytIq z7#VGBq8nPL2DhgB4ZJ=s-hUm|lR2K-SmzH|D|be*Uh26`oGn&c>s#jbXOXv!EAWEl zHHsRoB2ywOj5+4}_E+vy<)E5MFaMX`g}%Ij-{O`gOwKed`RmMaNqOVm^(AXX=)b9K zwJ>jliy^!3M}7=XG}nMCam&3$FJ5z2#(}I)>sc{MD^JOSwsvo0od)f4U&{YHd8YTm^hh{nG=D;(H}7PfAT5oK!9Tfp3>q z#N7c_%p|jYjGx)5n$&9|$%-&3z!SP>?=iFnGNfKyXc+2h&k{tebnNoNpP z4~I>~92!{;7V7LszsRS?5+m7IY3wlfffPK*^M*Q0Tdp_o-lE$4iN8Qxo`g}EdL@6C zyfN{gzzXjsWuU!-K9;S94vJ{8$kNc7P%~p5HRm%u3#rZh1JAHG|G1V;j0;ooFnrCcHpB@~_c?XU0AlMWGi)*M&f4*mo8n0i_ z7wR8?J~zVmb|5`|VbcDTU$W%PJSm~L|B<@d830qzRr8I=f59&^B58BdDx17we zi!5iSI!`^ns(ZATpj`i;b@dhvv`VOxJUr{J>_f6%&$Kp>RnO%f#yYBJ4hlETn4UKG z)sa_AGd3EQJ58&=DtgDa)3?vpK5#PbYM_YkHEpQd)w~-1KHMPEFw!=3H~nJTH)*-k zn}pVyH^43f&ChOQCQ_UKqhov8f{OJz=yM0PmA*sqX-Q?WrswFHvwN073Hf}zmHXBn z_?0Gy|4IKQb>+)oYL<-uB193rTlmkv{i_1k1N-8h#y^fL>1zyH!GDo^up4y`H;yz2 z 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. + Questo indirizzo potrà allora essere utilizzato dai tuoi interlocutori + per connetterti. + Un piccolo esempio concreto può essere utile: tu non sei altro che un internaut +a poverino, connesso temporaneamente grazie ad un modem 56k. + La tua macchina non ha un nome di dominio conosciuto ed il tuo indirizzo + IP cambia ad ogni connessione. + E' impossibile per gli amici chiamare in mancanza dell'indirizzo IP, a + meno che non lo si comunichi via posta elettronica, per esempio. + Per risolvere questo problema, si può chiedere di avere un indirizzo su + un server sip conosciuto dagli amici, fisso e sempre connesso. + Per far ciò, specificare l'indirizzo del server nel menu parametri, sezione + sip. + Questo indirizzo è, per esempio, ed il nome utente + è +\begin_inset Quotes fld +\end_inset + +Bob +\begin_inset Quotes frd +\end_inset + +. + Linphone invia allora al server un messaggio per informare della corrispondenza + tra l'indirizzo e l'indirizzo IP attuale. + D'ora in poi gli amici potranno chiamare usando questo nuovo indirizzo: + le chiamate saranno ridirette automaticamente verso la tua macchina. + Non ci sarà più bisogno di conoscere l'indirizzo IP, che cambia ogni volta, + per contattarti. + Ovviamente, si suppone che sia conosciuto da tutti + gli amici. +\layout Itemize + +Proxy: è esattamente lo stesso principio, tranne che la ridirezione viene + fatta in maniera trasparente ed invisibile dal Linphone del chiamante. +\layout Standard + +Il segretario specificato può essere utilizzato come proxy in uscita. + In questo caso tutte le chiamate in uscita dal tuo Linphone saranno dirette + verso tale server, che si suppone sia gestito da brave persone. + E' quindi molto utile, per non dire indispensabile, che si usi Linphone + su una rete privata, gestita da un firewall, anche se su un proxy sip è + sicuramente attivo un firewall. + +\layout Standard + +Per usare fin da subito un server sip, bisogna aprire il menu Parametri, + SIP, e cliccare sul pulsante in fianco a "Usa il segretario sip". + Digitare l'indirizzo del segretario, e scegliere un nome utente non troppo + comune, in modo da evitare conflitti di nomi. + Dare un'indicazione del servizio che il server deve effettuare per te e + cliccare sui pulsanti +\begin_inset Quotes fld +\end_inset + +ridirezione +\begin_inset Quotes frd +\end_inset + + o +\begin_inset Quotes fld +\end_inset + +proxy +\begin_inset Quotes frd +\end_inset + +. + Selezionare anche l'opzione +\begin_inset Quotes fld +\end_inset + +il server è un proxy in uscita +\begin_inset Quotes frd +\end_inset + + \SpecialChar ~ +se sei dietro ad un firewall. +\layout Standard + +Infine, confermando la scelta, Linphone comunicherà immediatamente con il\SpecialChar ~ + + server SIP per ottenere i servizi richiesti. + Allo stesso modo, in fase di uscita da Linphone, ci vorrà qualche secondo + per togliere la registrazione dal server. +\layout Standard + +Una lista di server sip può essere trovata a questo indirizzo: +\begin_inset LatexCommand \url[http://www.cs.columbia.edu/~hgs/sip/servers.html]{http://www.cs.columbia.edu/~hgs/sip/servers.html} + +\end_inset + +. +\layout Standard + +Sfortunatamente, poiché alcuni di questi server non funzionano più, forse + a causa della crisi e di fallimenti di società. + Alcuni non sono utilizzabili poiché richiedono metodi di autentificazione + non ancora implementati in Linphone. + Per non perdere tempo, una lista di server sip pubblici funzionanti con + Linphone è reperibile su +\begin_inset LatexCommand \url[http://simon.morlat.free.fr/english/servers.html]{http://simon.morlat.free.fr/english/servers.html} + +\end_inset + +. +\layout Section + +Uso dietro i firewall +\layout Standard + +Linphone è in grado di funzionare dietro i firewall grazie ad un server + proxy SIP in funzione sulla macchina firewall. + Un tale server è in corso di sviluppo su +\begin_inset LatexCommand \url[http://osipproxy.sourceforge.net]{http://osipproxy.sourceforge.net} + +\end_inset + +. + Ovviamente sarà libero e basato sulla libreria LGPL oSIP. +\layout Standard + +Una volta che il server proxy sarà attivo, si potrà configurare Linphone + per utilizzarlo. + Per far ciò, andare in Parametri, sezione SIP e attivare la casella +\begin_inset Quotes fld +\end_inset + +Usa il segretario SIP +\begin_inset Quotes frd +\end_inset + +, indicare il suo indirizzo, ed attivare l'opzione +\begin_inset Quotes fld +\end_inset + +il server è un proxy in uscita +\begin_inset Quotes frd +\end_inset + +. +\layout Standard + +C'è un caso in cui il\SpecialChar ~ + proxy non è indispensabile: quello in cui le macchine + di reti private possiedano un indirizzo pubblico: il firewall filtra i + pacchetti in entrata o uscita. + Bisogna permettere a Linphone di funzionare con le macchine esterne, autorizzar +e il traffico UDP sulla porta SIP (di default 5060, è possibile cambiarla), + e sulla porta RTP di ciascun Linphone nelle sottoreti. + La porta RTP è parametrizzabile, come si è visto, nel menu Parametri. +\layout Section + +Problemi vari +\layout Subsection + +Problemi di connessione +\layout Quotation + +Tento di chiamare il mio amico , ma niente da fare, + nessuno squillo. +\layout Standard + +Bisogna verificare che Linphone usi l'interfaccia di rete a cui sei connesso + con la rete su cui si trova il tuo amico. + La lista delle interfacce disponibili si trova in Parametri, sezione Rete. + Selezionarla. + +\layout Standard + +Se il problema persistesse, potrebbe essere che il tuo amico non sia al + momento raggiungibile. +\layout Subsection + +Problemi audio +\layout Quotation + +Linphone sembra connettersi correttamente, si sentono gli squilli, ma appena + l'interlocutore risponde, non si sente o si capisce più nulla. +\layout Itemize + +La maggior parte degli utenti ha di questi problemi poiché non è stata scelta + l'interfaccia di rete corretta. + Se si usa il modem, dev'essere ppp0. + In ogni caso, l'interfaccia +\begin_inset Quotes fld +\end_inset + +lo +\begin_inset Quotes frd +\end_inset + + non permette di avere una comunicazione via rete. + Serve solo per il test locale con sipomatic (vedere più avanti). +\layout Itemize + +Aumentare il livello sonoro di acquisizione ed emissione, usando i potenziometri + posti nella finestra principale. +\layout Itemize + +Se la voce dell'interlocutore sembra vibrare o echeggiare, si può tentaredi + aumentare il parametro comensazione jitter (Parametri, RTP). + Ma attenzione, questo aumenta il ritardo nella controparte. +\layout Itemize + +Se Linphone nonriesce ad usare la scheda sonora, verificare che non sia + utilizzata da qualche altro programma audio. + +\layout Itemize + +Infine, utilizzare il driver sonoro ALSA (vedere +\begin_inset LatexCommand \url[http://www.alsa-project.org]{http://www.alsa-project.org} + +\end_inset + +) , piuttosto che OSS, fornito con il kernel linux. + Sfortunatamente la maggior parte delle distribuzioni usano ancora vecchi + driver che hanno vari errori e problemi di ritardo. + I driver ALSA danno risultati migliori. + Si noti che se si cambiano driver, non c'è bisogno di ricompilare Linphone + o di cambiare una qualsiasi configurazione. + +\layout Section + +Errori e suggerimenti +\layout Standard + +In primo luogo, andare sul sito di Linphone +\begin_inset LatexCommand \url[http://www.linphone.org]{http://www.linphone.org} + +\end_inset + + e verificare di avere la versione più recente di Linphone. + +\layout Standard + +Se Linphone si bloccassse, inviami direttamente un messaggio a bugs@linphone.org. + Qualora Linphone non funzionasse, ma non si bloccasse, verificare bene + di aver letto tutto il manuale prima di mandare un resoconto all'indirizzo + indicato. + In ogni caso invia più informazioni possibili relativamente al problema, + in particolar modo i messaggi che compaiono quando lo si lancia da un terminale. + Se desideri qualche altra cosa, non esitare ad inviarmi un messaggio a + help@linphone.org.Tieni presente che l'aggiunta della modalità video e conferenza + sono in programma. + +\layout Standard + +Se qualcuno fosse interessato a fare traduzioni di Linphone, mi invii un + file xx.po basato su quello in po/linphone.pot della distribuzione. + Si può anche tradurre il manuale utente in altre lingue. + In ogni caso, contattami qualora volessi maggiori dettagli. +\layout Section + +Autori +\layout Standard + +Simon MORLAT (simon.morlat@linphone.org) ha scritto: +\layout Itemize + +Programma principale (src) +\layout Itemize + +Libreria RTP (lprtplib) +\layout Itemize + +osipua : la libreria Agente utente sip . +\layout Itemize + +Interfaccia per i driver audio (audio) +\layout Itemize + +Wrappers per i codecs lpc10-1.5, gsm e g711. + +\layout Standard + +Aymeric Moizard (jack@atosc.org) ha scritto la pila SIP oSIP usata da linphone. + +\layout Standard + +La libreria GSM è stata scritta da: Jutta Degener and Carsten Bormann,Technische + Universitaet Berlin. +\layout Standard + +La librairie LPC10-1.5 par: Andy Fingerhut Applied Research Laboratory Washington + University, Campus Box 1045/Bryan 509 One Brookings Drive Saint Louis, + MO 63130-4899 jaf@arl.wustl.edu http://www.arl.wustl.edu/~jaf/ +\layout Standard + +Leggere i file di testo README nella directory gsmlib e lpc10-1.5 per maggiori + informazioni. +\layout Standard + +Le icone sono di Pablo Marcelo Moia ed il logo di Philippe Beau. +\layout Section + +Ringraziamenti +\layout Standard + +Grazie a Daemon Chaplin per aver scritto Glade, il costruttore d'interfaccia + grafica GTK+. +\layout Standard + +Grazie agli autori del codice di LPC10-1.5 e GSM. +\layout Standard + +Grazie a Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) per i suoi + RPMS. +\layout Standard + +Grazie a Pablo Marcelo Moiaper le icone. +\layout Standard + +Grazie a Philippe Beau per la traduzione di questo manuale in francese, + per il logo, e per il nuovo sito web che ha creato per Linphone. +\layout Standard + +Grazie a Alberto Zanoni per + la traduzione di linphone e questo manuale in Italiano. +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\the_end diff --git a/linphone/share/it/manual.sgml b/linphone/share/it/manual.sgml new file mode 100644 index 000000000..3465759e2 --- /dev/null +++ b/linphone/share/it/manual.sgml @@ -0,0 +1,494 @@ + + +

+ + + + MANUALE UTENTE LINPHONE + + + Simon Morlat (simon.morlat@linphone.org) + + + 11-13-2001 + + + + + Introduzione + + + Linphone è un semplice strumento di telefonia su rete. Permette di effettuare conversazioni tra due utenti utilizzando una modalità IP come Internet. Ecco l'equipaggiamento necessario per usare Linphone : + + + + + Linux ( Può funzionare anche in altri ambienti come BSD, o altri UNIX, ma non l'ho ancora testato personalmente.) + + + + + Gnome 1.2 o superiore, installato ma non necessariamente usato. + + + + + Una scheda sonora correttamente configurata. + + + + + Cuffie o altoparlanti. + + + + + Un microfono. + + + + + Una connessione rete (Internet ad esempio), modem, scheda Ethernet ... + + + + + E' consigliabile chiudere tutte le applicazioni che fanno uso della scheda sonora prima di usare Linphone. Linphone è un programma libero, distribuito sotto la licenza pubblica GNU. + + + ATTENZIONE : Questo strumento è distribuito SENZA GARANZIA. Leggere il file COPYING per maggiori dettagli. Questo significa tra l'altro che non dovete usare Linphone per chiamate confidenziali: non ha ALCUNA CODIFICA DI PROTEZIONE, e quindi può essere molto facile per qualche malintenzionato captare i flussi audio. Si noti inoltre che si raccomanda di non usare Linphone come utente root. + + + + + Uso + + + Linphone può essere usato in 3 modi diversi : + + + + + Come applicazione (normale) : nel menu Gnome, Linphone dovrebbe apparire nella sezione Rete. Se non utilizzi Gnome, puoi lanciare Linphone da una finestra terminale, per esempio. Quando Linphone non è in esecuzione, non è possibile ricevere chiamate. + + + + + Come applet Gnome : cliccando sul pannello Gnome col pulsante destro, aggiungere l'applet. Linphone apparirà nella sezione Rete. Apparendo nel pannello Gnome, Linphone è capace di ricevere chiamate anche se la sua finestra non è visibile. Se si vuol vedere la finestra principale, cliccare sull'applet. Quando c'è una chiamata, la finestra principale passa in primo piano, e sentirai gli squilli della chiamata. + + + + + Come demone : questo è interessante per coloro che non utilizzano Gnome. Per esempio, per KDE, c'é una directory /home/user/.kde2/AutoStart/ dove si possono inserire le applicazioni che si vogliono lanciare ad inizio sessione. Nella directory citata, con l'aiuto di un gestore di file, aggiungere un collegamento cliccando col pulsante destro. Il comando da inserire è "linphone -daemon". L'interfaccia prinicipale di Linphone non sarà visibile, e dunque, per farla apparire, si lanci Linphone normalmente, per esempio da una finestra terminale. + + + + + + + Come lanciarlo + + + + Principi di base + + + Linphone utilizza il protocollo SIP (Session Initiation Protocol) per effettuare chiamate con altri interlocutori. Il protocollo specifica che ciascuna persona dev'essere identificata da un URL sip della forma: sip:nome_utente@nome_host. Questo modo di chiamare le persone è molto simile a quello utilizzato per la posta elettronica. + + + Nome_utente è il nome di un utente su una macchina, come il login su una macchina linux, per esempio. Nome_host è il nome di una macchina sotto forma di indirizzo IP, o più semplicemente sotto forma di dominio (es: linphone.org). + + + Si noti che SIP è un nuovo protocollo di telecomunicazione fatto per essere semplice ed efficace su internet, che è totalmente diverso ed incompatibile con H.323. H.323 è il protocollo attualmente usato da NetMeeting e GnomeMeeting. + + + + + Applicazione: due persone (Bob e Tom) si connettono ad internet con un modem analogico classico. + + + Ecco il modo più semplice di procedere : + + + Prerequisito : + + + + + Un modem da 28.8 Baud o più. + + + + + Procedimento: + + + + + Si è convenuto che Bob debba chiamare Tom alle 21.00. Alle 21.00, Tom si connette ad Internet utilizzando kppp, gppp o wvdial (o un altro). Una volta connesso ad internet, può lanciare Linphone. Aprendo la finestra delle statistiche di kppp o gppp, può vedere il suo indirizzo IP (altrimenti può digitare /sbin/ifconfig per vederlo). Il nome dell'interfaccia modem dev'essere ppp0. + + + + + Di seguito, manda un messaggio a Bob dicendo : "Il mio indirizzo IP è xxx.xxx.xxx.xxx". + + + + + Bob legge l'email e riporta nella finestra di Linphone il nome e l'indirizzo IP della personne da contattare : Tom@xxx.xxx.xxx.xxx(L'indirizzo IP di Tom) e per finire, clicca sul pulsante Chiamare. + + + + + Linphone suona a casa di Tom ...Tom risponde alla chiamata cliccando sul pulsante "Rispondere" ed a questo punto la conversazione può iniziare. + + + + + Se si incontrassero problemi in uno di questi punti, si vada alla sezione 4 - Problemi. + + + + + Test in locale: non hai nessuno da chiamare per il momento, ma vuoi controllare se Linphone funzioni davvero. + + + A partire dalla versione 0.3.0, Linphone è dotato di un programma di test chiamato "sipomatic". Sipomatic può rispondere automaticamente alle chiamate provenienti da Linphone. A voi la scelta : + + + + + Lanciare linphone. + + + + + Lanciare sipomatic in una finestra terminale. Non siate sorpresi, sipomatic non possiede alcuna interfaccia grafica, ma non c'è bisogno di modificare quello che sta sotto. + + + + + In Linphone, menu Parametri, sezione Rete, scegliere "lo" come interfaccia di default. Applicare il cambiamento cliccando su OK. Digitare l'indirizzo S.I.P seguente nella finestra principale : sip:robot@127.0.0.1:5064. 127.0.0.1 è l'indirizzo locale del tuo computer, e robot è il nome da usare per chiamare sipomatic. 5064 è la porta con cui sipomatic può essere contattato. Normalmente si deve utilizzare 5060 per chiamare qualcuno, ma sipomatic fa eccezione : funziona con la porta 5064. Il motivo è che Linphone funziona già sulla porta 5060, ed è impossibile avere due applicazioni che utilizzino la stessa porta nello stesso momento, sulla stessa macchina. + + + + + Cliccare sul pulsante "Chiamare". Dopo qualche secondo, sipomatic dovrebbe rispondere alla chiamata e vi dovrebbe dire un breve messaggio. + + + + + + + + Parametri di chiamata + + + + Rete + + + + + Lista delle interfacce di rete: bisogna scegliere un'interfaccia di rete da usare con Linphone. Se si vuole contattare qualcuno su Internet, bisogna scegliere l'interfaccia di rete connessa ad Internet. Per esempio, se si utilizza un modem, dovrà essere ppp0. Se non si è connessi ad alcuna rete, solo l'interfaccia di rete locale, chiamata lo, apparirà nella lista. L'unica scelta che si può fare in questo caso è chiamare sipomatic. + + + + + Tipo di connessione: scegliere il tipo di connessione utilizzata per connettervi alla rete che si desidera utilizzare. Questo aiuterà Linphone ad autoconfigurarsi in funzione della banda passante del tipo di connessione. + + + + + + + RTP + + + RTP + + + + + porta RTP: Linphone utilizza la porta 7072 di default per inviare e ricevere segnali audio. Se la porta 7072 è usata da un'altra applicazione, la si cambi a piacere. + + + + + Compensazione Jitter: questo numero rappresenta il numero di pacchetti audio che Linphone aspetta prima di farli sentire. Si aumenti questo numero se si sente male la voce, in modo da migliorare la qualità di trasmissione, ma attenzione: questo aumenta il ritardo (Si sentirà la voce dell'interlocutore qualche millisecondo più tardi). D'altro canto, se si utilizza un server perfetto, e si dispone di buoni driver audio, si può scegliere un valore basso fino a 3 pacchetti, sentendo così un ritardo trascurabile. + + + + + + + SIP + + + SIP (Session Initiation Protocol) è un protocollo che permette di stabilire sessioni telefoniche grazie ad un server IP. Semplificando, è ciò che permette di far suonare il telefono all'altro interlocutore, sospendere o terminare una chiamata quando uno dei due riattacca. + + + + + porta SIP: Linphone utilizza di default la porta 5060 per inviare / ricevere pacchetti SIP. Si raccomanda caldamente per la RFC del protocollo SIP di utilizzare questo valore. Non lo si cambi a meno che non si sappia davvero cosa si stia facendo. + + + + + Indirizzo SIP: modifica nome utente e macchina a piacere. Beninteso, dare un nome di macchina quinon significa che questo nome sia conosciuto da altre macchine del server. Nemmeno Linphone userà il nome della macchina e preferirà usare l'indirizzo IP per comunicare con altre macchine. + + + + + Usare un server segretario sip: si faccia questa scelta, se ci si vuole registrare su un server SIP (segretario) per ottenere servizi vari. Quando non si ha un indirizzo IP fisso, questo può essere interessante per permettere agli amici di chiamare. Vedere la sezione "enregistrement sur un serveur sip". + + + + + + + Codec + + + I codecs sono algoritmi per comprimere la voce. Per esempio, una voce digitalizzata a 16bit/8000Hz rappresenta un flusso di dati di 128kbits/secondo. Usando il codificatore vocale GSM, questo flusso è ridotto a 13kbits/secondo, senza perdita significativa di qualità. + + + + + Scelta dei codecs: Linphone può usare diversi codec. Usare i pulsanti posti a lato della lista dei codec in modo da porli nell'ordine preferito. Si badi bene, che in funzione del tipo di connessione alla rete, alcuni codec sono inutilizzabili. Questi appariranno in rosso e non saranno selezionabili. Si può decidere di usare o no un codec "utilizzabile" (in blu) cambiando il suo stato con l'aiuto del pulsante Attiva / Disattiva in fianco alla lista. + + + + + + + Parametri audio + + + + + Modo d'uso: se si ha installato il driver ALSA con una libreria ALSA <0.9, si scelga ALSA per avere risultati migliori. Altrimenti, o se non si sa, usare OSS, che funziona sufficientemente bene. + + + + + Scelta della fonte di registrazione: si può scegliere la fonte di registrazione per la voce. Nella maggior parte dei casi, sarà il microfono. + + + + + Opzione auto-kill: scegliendo questa opzione, Linphone fermerà i server sonori (esd &#38; artsd) che possono bloccare la periferica sonora e provocare così problemi problemi d'apertura delle periferiche da parte di Linphone in caso di bisogno. Si raccomanda di attivare questa opzione. + + + + + + + + Rubrica + + + A partire dalla versione 0.4.1 Linphone dispone di una rubrica (menu connessione, rubrica), con la quale memorizzare indirizzi, e richiamarli facilmente quando si vuol chiamare. + + + + + Registrazione su un server sip + + + E' possibile sottoscrivere alcuni servizi sui server sip remoti chiamati segretari, proxy o server ridiretti. Questi servizi possono essere: + + + + + ridirezione: Linphone chiede al server la creazione di un account <sip:votre_nom@le_serveur_sip>. Questo indirizzo potrà allora essere utilizzato dai tuoi interlocutori per connetterti. Un piccolo esempio concreto può essere utile: tu non sei altro che un internauta poverino, connesso temporaneamente grazie ad un modem 56k. La tua macchina non ha un nome di dominio conosciuto ed il tuo indirizzo IP cambia ad ogni connessione. E' impossibile per gli amici chiamare in mancanza dell'indirizzo IP, a meno che non lo si comunichi via posta elettronica, per esempio. Per risolvere questo problema, si può chiedere di avere un indirizzo su un server sip conosciuto dagli amici, fisso e sempre connesso. Per far ciò, specificare l'indirizzo del server nel menu parametri, sezione sip. Questo indirizzo è, per esempio, <sip:server_esempio.com> ed il nome utente è “Bob”. Linphone invia allora al server un messaggio per informare della corrispondenza tra l'indirizzo <sip:bob@server_esempio.com> e l'indirizzo IP attuale. D'ora in poi gli amici potranno chiamare usando questo nuovo indirizzo: le chiamate saranno ridirette automaticamente verso la tua macchina. Non ci sarà più bisogno di conoscere l'indirizzo IP, che cambia ogni volta, per contattarti. Ovviamente, si suppone che <sip:server_esempio.com> sia conosciuto da tutti gli amici. + + + + + Proxy: è esattamente lo stesso principio, tranne che la ridirezione viene fatta in maniera trasparente ed invisibile dal Linphone del chiamante. + + + + + Il segretario specificato può essere utilizzato come proxy in uscita. In questo caso tutte le chiamate in uscita dal tuo Linphone saranno dirette verso tale server, che si suppone sia gestito da brave persone. E' quindi molto utile, per non dire indispensabile, che si usi Linphone su una rete privata, gestita da un firewall, anche se su un proxy sip è sicuramente attivo un firewall. + + + Per usare fin da subito un server sip, bisogna aprire il menu Parametri, SIP, e cliccare sul pulsante in fianco a "Usa il segretario sip". Digitare l'indirizzo del segretario, e scegliere un nome utente non troppo comune, in modo da evitare conflitti di nomi. Dare un'indicazione del servizio che il server deve effettuare per te e cliccare sui pulsanti “ridirezione” o “proxy”. Selezionare anche l'opzione “il server è un proxy in uscita” se sei dietro ad un firewall. + + + Infine, confermando la scelta, Linphone comunicherà immediatamente con il server SIP per ottenere i servizi richiesti. Allo stesso modo, in fase di uscita da Linphone, ci vorrà qualche secondo per togliere la registrazione dal server. + + + Una lista di server sip può essere trovata a questo indirizzo: http://www.cs.columbia.edu/~hgs/sip/servers.html. + + + Sfortunatamente, poiché alcuni di questi server non funzionano più, forse a causa della crisi e di fallimenti di società. Alcuni non sono utilizzabili poiché richiedono metodi di autentificazione non ancora implementati in Linphone. Per non perdere tempo, una lista di server sip pubblici funzionanti con Linphone è reperibile su http://simon.morlat.free.fr/english/servers.html. + + + + + Uso dietro i firewall + + + Linphone è in grado di funzionare dietro i firewall grazie ad un server proxy SIP in funzione sulla macchina firewall. Un tale server è in corso di sviluppo su http://osipproxy.sourceforge.net. Ovviamente sarà libero e basato sulla libreria LGPL oSIP. + + + Una volta che il server proxy sarà attivo, si potrà configurare Linphone per utilizzarlo. Per far ciò, andare in Parametri, sezione SIP e attivare la casella “Usa il segretario SIP”, indicare il suo indirizzo, ed attivare l'opzione “il server è un proxy in uscita”. + + + C'è un caso in cui il proxy non è indispensabile: quello in cui le macchine di reti private possiedano un indirizzo pubblico: il firewall filtra i pacchetti in entrata o uscita. Bisogna permettere a Linphone di funzionare con le macchine esterne, autorizzare il traffico UDP sulla porta SIP (di default 5060, è possibile cambiarla), e sulla porta RTP di ciascun Linphone nelle sottoreti. La porta RTP è parametrizzabile, come si è visto, nel menu Parametri. + + + + + Problemi vari + + + + Problemi di connessione + +
+ + Tento di chiamare il mio amico <sip:toto@esempio.com>, ma niente da fare, nessuno squillo. + +
+ + Bisogna verificare che Linphone usi l'interfaccia di rete a cui sei connesso con la rete su cui si trova il tuo amico. La lista delle interfacce disponibili si trova in Parametri, sezione Rete. Selezionarla. + + + Se il problema persistesse, potrebbe essere che il tuo amico non sia al momento raggiungibile. + +
+ + + Problemi audio + +
+ + Linphone sembra connettersi correttamente, si sentono gli squilli, ma appena l'interlocutore risponde, non si sente o si capisce più nulla. + +
+ + + + La maggior parte degli utenti ha di questi problemi poiché non è stata scelta l'interfaccia di rete corretta. Se si usa il modem, dev'essere ppp0. In ogni caso, l'interfaccia “lo” non permette di avere una comunicazione via rete. Serve solo per il test locale con sipomatic (vedere più avanti). + + + + + Aumentare il livello sonoro di acquisizione ed emissione, usando i potenziometri posti nella finestra principale. + + + + + Se la voce dell'interlocutore sembra vibrare o echeggiare, si può tentaredi aumentare il parametro comensazione jitter (Parametri, RTP). Ma attenzione, questo aumenta il ritardo nella controparte. + + + + + Se Linphone nonriesce ad usare la scheda sonora, verificare che non sia utilizzata da qualche altro programma audio. + + + + + Infine, utilizzare il driver sonoro ALSA (vedere http://www.alsa-project.org) , piuttosto che OSS, fornito con il kernel linux. Sfortunatamente la maggior parte delle distribuzioni usano ancora vecchi driver che hanno vari errori e problemi di ritardo. I driver ALSA danno risultati migliori. Si noti che se si cambiano driver, non c'è bisogno di ricompilare Linphone o di cambiare una qualsiasi configurazione. + + + +
+
+ + + Errori e suggerimenti + + + In primo luogo, andare sul sito di Linphone http://www.linphone.org e verificare di avere la versione più recente di Linphone. + + + Se Linphone si bloccassse, inviami direttamente un messaggio a bugs@linphone.org. Qualora Linphone non funzionasse, ma non si bloccasse, verificare bene di aver letto tutto il manuale prima di mandare un resoconto all'indirizzo indicato. In ogni caso invia più informazioni possibili relativamente al problema, in particolar modo i messaggi che compaiono quando lo si lancia da un terminale. Se desideri qualche altra cosa, non esitare ad inviarmi un messaggio a help@linphone.org.Tieni presente che l'aggiunta della modalità video e conferenza sono in programma. + + + Se qualcuno fosse interessato a fare traduzioni di Linphone, mi invii un file xx.po basato su quello in po/linphone.pot della distribuzione. Si può anche tradurre il manuale utente in altre lingue. In ogni caso, contattami qualora volessi maggiori dettagli. + + + + + Autori + + + Simon MORLAT (simon.morlat@linphone.org) ha scritto: + + + + + Programma principale (src) + + + + + Libreria RTP (lprtplib) + + + + + osipua : la libreria Agente utente sip . + + + + + Interfaccia per i driver audio (audio) + + + + + Wrappers per i codecs lpc10-1.5, gsm e g711. + + + + + Aymeric Moizard (jack@atosc.org) ha scritto la pila SIP oSIP usata da linphone. + + + La libreria GSM è stata scritta da: Jutta Degener and Carsten Bormann,Technische Universitaet Berlin. + + + La librairie LPC10-1.5 par: Andy Fingerhut Applied Research Laboratory Washington University, Campus Box 1045/Bryan 509 One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wustl.edu http://www.arl.wustl.edu/˜jaf/ + + + Leggere i file di testo README nella directory gsmlib e lpc10-1.5 per maggiori informazioni. + + + Le icone sono di Pablo Marcelo Moia ed il logo di Philippe Beau. + + + + + Ringraziamenti + + + Grazie a Daemon Chaplin per aver scritto Glade, il costruttore d'interfaccia grafica GTK+. + + + Grazie agli autori del codice di LPC10-1.5 e GSM. + + + Grazie a Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com ) per i suoi RPMS. + + + Grazie a Pablo Marcelo Moiaper le icone. + + + Grazie a Philippe Beau per la traduzione di questo manuale in francese, per il logo, e per il nuovo sito web che ha creato per Linphone. + + + Grazie a Alberto Zanoni <alberto.zanoni@-NO-SPAM-PLEASE!-tiscalinet.it> per la traduzione di linphone e questo manuale in Italiano. + + + + + + + +
diff --git a/linphone/share/it/manual/.cvsignore b/linphone/share/it/manual/.cvsignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/linphone/share/it/manual/.cvsignore @@ -0,0 +1 @@ +*.html diff --git a/linphone/share/ja/.cvsignore b/linphone/share/ja/.cvsignore new file mode 100644 index 000000000..e1d20773b --- /dev/null +++ b/linphone/share/ja/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +manual +manual.junk +manual.html diff --git a/linphone/share/ja/Makefile.am b/linphone/share/ja/Makefile.am new file mode 100644 index 000000000..1d3028c6e --- /dev/null +++ b/linphone/share/ja/Makefile.am @@ -0,0 +1,3 @@ +HELPLANG=ja + +include ../Makefile.inc diff --git a/linphone/share/ja/manual.lyx b/linphone/share/ja/manual.lyx new file mode 100644 index 000000000..c1777bd96 --- /dev/null +++ b/linphone/share/ja/manual.lyx @@ -0,0 +1,505 @@ +#LyX 1.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 218 +\textclass docbook +\language english +\inputencoding default +\fontscheme default +\graphics default +\paperfontsize default +\spacing single +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +LINPHONE¥æ¡¼¥¶¡¼¥Þ¥Ë¥å¥¢¥ë +\layout Author + +Simon Morlat (simon.morlat@linphone.org) +\layout Author + +Ìõ¡§»³¸ýÁ±Ìé(yushiya@anet.ne.jp) +\layout Date + +11-13-2001 +\layout Section + +¤Ï¤¸¤á¤Ë +\layout Standard + +Linphone¤Ï¡¢¥·¥ó¥×¥ë¤Ê¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÅÅÏäǤ¢¤ê¡¢Æó¼Ô´Ö¤ÎÄÌÏäò¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ê¤É¤ÎIPÌÖ¤òÄ̤¸¤Æ²Äǽ¤Ë¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£Linphone¤òµ¯Æ°¤¹¤ë¤Ë¤Ï°Ê²¼ +¤Î¤â¤Î¤¬É¬ÍפȤʤ롣 +\layout Itemize + +Linux(BSD¤Î¤è¤¦¤Ê¾¤ÎUNIX¤Ç¤âµ¯Æ°¤¹¤ë¤À¤í¤¦¤¬¡¢Linux´Ä¶­¤Û¤É¾¤Î´Ä¶­¤Ï¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¡£) +\layout Itemize + +gnome1.2°Ê¾å¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤ë¤³¤È¡£É¬¤º¤·¤âµ¯Æ°¤·¤Æ¤¤¤ëɬÍפϤʤ¤¡£ +\layout Itemize + +¥Ø¥Ã¥É¥Û¥ó¤«¥¹¥Ô¡¼¥«¡¼¡£ +\layout Itemize + +¥µ¥¦¥ó¥É¥«¡¼¥É¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤Æ¤¤¤ë¤³¤È¡£ +\layout Itemize + +¥Þ¥¤¥¯¥í¥Õ¥©¥ó +\layout Itemize + +¥â¥Ç¥à¤ä¥¤¡¼¥µ¥Í¥Ã¥ÈÅù¤òÍѤ¤¤¿¡¢¥Í¥Ã¥È¥ï¡¼¥¯(¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÅù)¤Ø¤ÎÀܳ¡£ +\layout Standard + +¤Ê¤ª¡¢Linphone¤òµ¯Æ°¤¹¤ëÁ°¤Ë¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò»ÈÍѤ¹¤ë¤¹¤Ù¤Æ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò½ªÎ»¤·¤Æ¤ª¤¯¤Î¤¬¤è¤¤¤À¤í¤¦¡£ +\layout Standard + +Linphone¤Ï¥Õ¥ê¡¼¥¦¥§¥¢¤Ç¤¢¤ê¡¢GNU Public Licence¤Ë½¾¤Ã¤ÆÇÛÉÛ¤µ¤ì¤ë¡£ +\layout Standard + +·Ù¹ð - Åö¥½¥Õ¥È¥¦¥§¥¢¤ÏÊݾڤʤ·¤ËÄ󶡤µ¤ì¤ë¤â¤Î¤Ç¤¢¤ë¡£¾Ü¤·¤¯¤ÏCOPYING¥Õ¥¡¥¤¥ë¤ò»²¾È¤µ¤ì¤¿¤¤¡£¤Ê¤ª¡¢Linphone¤Ï°Å¹æ²½¤òÍѤ¤¤Ê¤¤¤¿¤á¡¢°­°Õ¤¢¤ë¿Í +ʪ¤¬Íưפ˲»À¼¾ðÊó¤ò½¦¤¦¤³¤È¤¬¤Ç¤­¤ë¡£¤Ä¤Þ¤ê¡¢Linphone¤ÏÈëÌ©¤Î²ñÏäËÍѤ¤¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤¡£¤Þ¤¿¡¢Linphone¤Ï¥ë¡¼¥È¸¢¸Â¤Çµ¯Æ°¤·¤Ê¤¤¿ä¾©¤¹¤ë¡£ +\layout Section + +Linphone¤Îµ¯Æ° +\layout Standard + +Linphone¤Ï»°¤Ä¤ÎÊýË¡¤Çµ¯Æ°¤Ç¤­¤ë¡£ +\layout Itemize + +Ä̾ï¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È¤·¤Æ - Linphone¤Ï¡¢gnome¥á¥Ë¥å¡¼¤ÎÃæ¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥µ¥Ö¥á¥Ë¥å¡¼¤Ë¸½¤ì¤ë¡£¤â¤·¡¢gnome¤òµ¯Æ°¤·¤Æ¤Ê¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢Î㤨¤Ð +¥¿¡¼¥ß¥Ê¥ë¤Ë +\begin_inset Quotes eld +\end_inset + +linphone +\begin_inset Quotes erd +\end_inset + +¤È¥¿¥¤¥×¤¹¤ë¤³¤È¤Ç¼Â¹Ô¤Ç¤­¤ë¡£Linphone¤¬µ¯Æ°¤·¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ÅÅÏäò¼õ¤±¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡£ +\layout Itemize + +gnome¥¢¥×¥ì¥Ã¥È¤È¤·¤Æ - gnome¥Ñ¥Í¥ë¤ò±¦¥¯¥ê¥Ã¥¯¤¹¤ë¤È¡¢¥Ñ¥Í¥ë¤ËLinphone¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤ë¡£Linphone¤Ï¥Í¥Ã¥È¡¼¥ï¡¼¥¯¥á¥Ë¥å¡¼¤ÎÃæ +¤Ë¤¢¤ë¡£¤Ò¤Ã¤½¤ê¤È¥Ñ¥Í¥ë¤ÎÃæ¤Çµ¯Æ°¤¹¤ë¤³¤È¤Ç¡¢Linphone¤Ï¡¢¤¿¤È¤¨¥¦¥¤¥ó¥É¥¦¤¬¸½¤ì¤Æ¤¤¤Ê¤¯¤Æ¤âÅÅÏäò¼õ¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤Ëɽ¼¨¤µ¤»¤¿¤¤¤È¤­ +¤Ë¤Ï¡¢¥¢¥×¥ì¥Ã¥È¤ò¥¯¥ê¥Ã¥¯¤¹¤ì¤Ð¤è¤¤¡£ÅÅÏ䬤«¤«¤Ã¤Æ¤­¤¿¤È¤­¤Ë¤Ï¡¢¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤¬É½¤ì¤Æ¡¢Ä̾ïÄ̤ê¤Ë¥Ù¥ë¤¬ÌĤäƤ¤¤ë¤Î¤¬Ê¹¤³¤¨¤ë¤À¤í¤¦¡£ +\layout Itemize + +¤Ò¤Ã¤½¤ê¤È¥Ç¡¼¥â¥ó¤È¤·¤Æ - ¤³¤ì¤Ï¡¢Èógnome¥æ¡¼¥¶¡¼¤Î¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£Î㤨¤Ðkde¤Ç¤Ï¡¢/home/user/.kde2/AutoStart¥Ç¥£¥ì¥¯¥È¥ê¤Ë +¡¢¥í¥°¥¤¥ó»þ¤Ëµ¯Æ°¤·¤¿¤¤¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥ê¥ó¥¯¤òŽ¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢¾å½Ò¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Õ¥¡¥¤¥ë¥Þ¥Í¡¼¥¸¥ã¡¼¤Ç°Üư¤·¡¢±¦¥¯¥ê¥Ã¥¯¤Ç¸½¤ì¤ë¥¢¥×¥ì¥Ã¥È¤«¤é¡¢¡Ö¥ê¥ó¥¯ +¤ÎÄɲáפò¼Â¹Ô¤¹¤ì¤Ð¤è¤¤¡£¤Ê¤ª¡¢µ¯Æ°¤¹¤ë¥³¥Þ¥ó¥É¤Ï¡¢ +\begin_inset Quotes eld +\end_inset + + linphone -deamon +\begin_inset Quotes erd +\end_inset + +¤Ç¤¢¤ë¡£¤³¤Î¾ì¹ç¡¢Linphone¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò¸«¤ë¤³¤È¤Ï¤Ê¤¤¤¬¡¢É½¼¨¤µ¤»¤¿¤¤¤È¤­¤Ë¤Ï¥¿¡¼¥ß¥Ê¥ëÅù¤«¤éLinphone¤òµ¯Æ°¤µ¤»¤ë¤Î¤ÈƱÍͤ˥¿¥¤¥×¤¹¤ì¤Ð¤è +¤¤¡£ +\layout Section + +ÅÅÏäò¤«¤±¤ë +\layout Subsection + +´ðËÜŪ¤Ê¸¶Â§ +\layout Standard + +¡Ösip:¥æ¡¼¥¶¡¼Ì¾@¥Û¥¹¥È̾¡×¤Î¤è¤¦¤ÊSIP URL¤Ë¤è¤Ã¤Æ¶èÊ̤µ¤ì¤ë¡£SIP URL¤Ï¡¢Æ¬¤Î¡Ösip:¡×¤ò½ü¤±¤ÐÈó¾ï¤Ëe-mail¥¢¥É¥ì¥¹¤È»÷¤Æ¤¤¤ë¡£ +\layout Standard + +¥æ¡¼¥¶¡¼Ì¾¤Ï¡¢UNIX¥Þ¥·¥ó¤Î¥í¥°¥¤¥ó¥Í¡¼¥à¤Î¤è¤¦¤Ê¤â¤Î¤Ç¡¢¥Û¥¹¥È̾¤Ï¥æ¡¼¥¶¡¼¤¬Àܳ¤¹¤ë¥Þ¥·¥ó¤Î̾Á°¤äIP¥¢¥É¥ì¥¹¤Ç¤¢¤ë¡£ +\layout Standard + +¤Ê¤ª¡¢SIP¤Ï¥·¥ó¥×¥ë¤ËÀ߷פµ¤ì¤¿¿·¤·¤¤ÄÌ¿®¤Î¥×¥í¥È¥³¥ë¤Ç¤¢¤ê¡¢H323¤È¤Ï¤Þ¤Ã¤¿¤¯¸ß´¹À­¤¬¤Ê¤¤¤³¤È¤ËÃí°Õ¤µ¤ì¤¿¤¤¡£ +\layout Subsection + +»ÈÍÑÎã:Æó¿Í¤Î¥æ¡¼¥¶¡¼¤¬¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ë¥â¥Ç¥à¤ÇÀܳ¤·¤Æ¤¤¤ë¤È¤­ +\layout Standard + +¤³¤ì¤Ï¡¢Ã±½ã¤Ê¼ê³¤­¤Ç¤¢¤ë¡£É¬ÍפȤµ¤ì¤ë¥Í¥Ã¥È¥ï¡¼¥¯¤Ï¡¢ +\layout Itemize + +28k°Ê¾å¤Î¥â¥Ç¥à +\layout Standard + +¤Ç¤¢¤ë¡£ +\layout Standard + +¥·¥Ê¥ê¥ª¤Ï¡¢°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£ +\layout Itemize + +¥Ü¥Ö¤Ï¥È¥à¤Ë21:00¤ËÅÅÏ乤뤳¤È¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¥È¥à¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ëkppp¤ägppp¤äwmdial¤Ê¤É¤ÇÀܳ¤·¤Æ¤¤¤ë¡£ +\layout Itemize + +¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤¿¤é¡¢¥Ü¥Ö¤ÏLinphone¤òµ¯Æ°¤Ç¤­¤ë¡£kppp¤ägppp¤Ê¤É¤ÎÅý·×¥Ü¥Ã¥¯¥¹¤ò³«¤¤¤Æ¡¢¥Ü¥Ö¤Ï¼«Ê¬¤ÎIP¥¢¥É¥ì¥¹¤òÃΤ뤳¤È¤¬¤Ç¤­¤ë¡£(/s +bin/ifconfig¤ò»È¤ï¤Ê¤¯¤Æ¤â³Îǧ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë)¡£ +\layout Itemize + +¼¡¤Ë¡¢¥È¥à¤Ï¥Ü¥Ö¤Ë¡ÖËͤÎIP¥¢¥É¥ì¥¹¤Ï¡¢xxx.xxx.xxx.xxx¤À¤è¡£¡×¤È¤¤¤¦ÆâÍÆ ¤Îe¥á¡¼¥ë¤òÁ÷¤ë¡£ +\layout Itemize + +¤½¤Î¤¹¤°¤¢¤È¤Ç¡¢¥È¥à¤Î²È¤ÎLinphone¤Î¥Ù¥ë¤¬ÌĤ롣¤½¤Î¤È¤­¡¢¥Ü¥Ö¤Ë¤â¸þ¤³¤¦¤Ç¥Ù¥ë¤¬ÌĤäƤ¤¤ë¤Î¤¬Ê¬¤«¤ë¤è¤¦¤Ë¥Ù¥ë¤Î²»¤¬Ê¹¤³¤¨¤ë¡£¤½¤³¤Ç¡¢¥È¥à¤¬ÅÅÏä˽Ф뤿 +¤á¤Ë¡ÖÅÅÏäò¤È¤ë¡×¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë¤À¤±¤Ç¤è¤¤¡£¤½¤¦¤¹¤ì¤Ð¡¢¸ß¤¤¤Ë²ñÏ䬤Ǥ­¤ë¤Ï¤º¤Ç¤¢¤ë¡£ +\layout Standard + +ÌäÂ꤬¤¢¤Ã¤¿¤é¡¢Âè4Àá¤ÎÌäÂê¤ò»²¾È¤·¤ÆÍߤ·¤¤¡£ +\layout Subsection + +¥Æ¥¹¥È¤Î»î¹Ô - ¸½ºß(Î㤨¤Ð¿¼Ìë¤Ê¤É¤Ç)ÅÅÏäò¤«¤±¤ëͧ¿Í¤¬¤¤¤Ê¤¤¤¬¡¢Linphone¤¬ËÜÅö¤Ëư¤¤¤Æ¤¤¤ë¤«¤É¤¦¤«ÃΤꤿ¤¤¤È¤­ +\layout Standard + + +\begin_inset LatexCommand \label{sipomatic} + +\end_inset + +¥Ð¡¼¥¸¥ç¥ó3.0¤«¤é¤Ï¡¢Linphone¤Ë¤Ï¡Ösiptomatic¡×¤È¤¤¤¦¥×¥í¥°¥é¥à¤¬ÉÕ°¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï¡¢°Ê²¼¤Î¼ê½ç¤Ç»ÈÍѤǤ­¤ë¡£ +\layout Itemize + +siptomatic¤ò¥¿¡¼¥ß¥Ê¥ë¤«¤éµ¯Æ°¤¹¤ë¡£siptomatic¤Ï¥°¥é¥Õ¥£¥«¥ë¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹¤òÈ÷¤¨¤Æ¤¤¤Ê¤¤¤¬¡¢¶Ã¤«¤Ê¤¤¤ÇÍߤ·¤¤¡£Áê¸ßŪ¤Ê¤ä¤ê¤È¤ê¤ò¤¹¤ëɬÍפ¬ +¤Ê¤¤¤«¤é¤Ç¤¢¤ë¡£ +\layout Itemize + +Linphone¤Î¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Î¥¿¥Ö¤«¤é¡¢¡Ölo¡×¤ò¥Ç¥Õ¥©¥ë¥È¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ë·èÄꤷ¡¢Êѹ¹¤òOK¤ò¥¯¥ê¥Ã¥¯¤·¤ÆÅ¬ÍѤ¹¤ë¡£ + +\layout Itemize + +¡Ösip:robot@127.0.0.1:5064¡×¤È¤¤¤¦SIP URL¤ò¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤ËÆþÎϤ¹¤ë¡£127.0.0.1¤Ï¡¢¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤Î ¥í¡¼¥«¥ë¥¢¥É¥ì¥¹¤Ç¡¢r +obot¤Ïsipomatic¤ËÅÅÏäò¤«¤±¤ëºÝ¤Î̾Á°¤Ç¤¢¤ë¡£5064¥Ý¡¼¥È¤¬¡¢sipomatic¤ËÀܳ²Äǽ¤Ê¥Ý¡¼¥È¤Ç¤¢¤ë¡£Ä̾ï¤ÏÅÅÏäò¤«¤±¤ë¤Î¤Ë5060È֥ݡ¼¥È¤ò +ÍѤ¤¤ë¤¬¡¢sipomatic¤ÏÎã³°¤Ç5064È֥ݡ¼¥È¤Çµ¯Æ°¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï¡¢Linphone¤¬¤¹¤Ç¤Ë5060È֥ݡ¼¥È(¤¹¤Ê¤ï¤Á¡¢¥Ý¡¼¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¥Ç¥Õ +¥©¥ë¥È¤Î¥Ý¡¼¥È¤È¤·¤Æ)¤Çµ¯Æ°¤·¤Æ¤¤¤ë¤«¤é¤Ç¤¢¤ê¡¢Æ±¤¸¥Ý¡¼¥È¤ò»È¤¦2¤Ä¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òƱ»þ¤ËƱ¤¸¥³¥ó¥Ô¥å¡¼¥¿¡¼¤Çµ¯Æ°¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤«¤é¤Ç¤¢¤ë¡£ +\layout Itemize + +¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë¤È¡¢¿ôÉøå¤Ësiptomatic¤¬¤¢¤Ê¤¿¤ÎÅÅÏäËÊÖÅú¤·¡¢Ã»¤¤¥¢¥Ê¥¦¥ó¥¹¤¬Ê¹¤³¤¨¤ë¤À¤í¤¦¡£ +\layout Section + + +\begin_inset LatexCommand \label{params} + +\end_inset + +ÅÅÏäΥѥé¥á¡¼¥¿¡¼ +\layout Subsection + + +\begin_inset LatexCommand \label{paramnetwork} + +\end_inset + +¥Í¥Ã¥È¥ï¡¼¥¯ +\layout Itemize + +¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î¥ê¥¹¥È - ¤¢¤Ê¤¿¤Ï¡¢Linphone¤Ë»È¤¦¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ÖɬÍפ¬¤¢¤ë¡£¤â¤·¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥È¾å¤Î狼¤ËÏ¢Íí¤ò¤·¤¿ +¤¤¤Î¤Ê¤é¡¢¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤¬¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤Ö¤Ù¤­¤Ç¤¢¤ë¡£²¿¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤â¤Ä¤Ê¤¬¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¡Ölo +¡×¤È¸Æ¤Ð¤ì¤ë¥í¡¼¥«¥ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤À¤±¤¬¥ê¥¹¥È¤Ë¸½¤ì¤ë¤À¤í¤¦¡£¤½¤ì¤Ï¡¢siptomatic¤ËÅÅÏäò¤¹¤ë¤³¤È¤À¤±¤¬¤Ç¤­¤ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ç¤¢¤ë¡£ + +\layout Itemize + +Àܳ¤Î¥¿¥¤¥× - »È¤¤¤¿¤¤¥Í¥Ã¥È¥ï¡¼¥¯¤Ø¤ÎÀܳ¤ÎÊýË¡¤òÁªÂò¤¹¤ë(ÂçÄñ¤Î¾ì¹ç¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ç¤¢¤ë)¡£¤³¤ì¤Ï¡¢Linphone¤¬¤¢¤Ê¤¿¤ÎÂÓ°è¤òÀßÄꤹ¤ë¤Î¤òÊä½õ¤¹¤ë +¤¿¤á¤Ç¤¢¤ë¡£ +\layout Subsection + + +\begin_inset LatexCommand \label{paramrtp} + +\end_inset + +RTP +\layout Standard + +RTP(Real Time Protocol)¤Ï¡¢¥á¥Ç¥£¥¢¥¹¥È¥ê¡¼¥à¤ò¥Í¥Ã¥È¥ï¡¼¥¯±Û¤·¤ËÁ÷¿®¤¹¤ëºÝ¤ËÍѤ¤¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£ +\layout Itemize + +RTP¥Ý¡¼¥È - Linphone¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç²»À¼¥Ç¡¼¥¿¤ÎÁ÷¼õ¿®¤Ë7000È֥ݡ¼¥È¤òÍøÍѤ¹¤ë¡£7000È֥ݡ¼¥È¤¬Â¾¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë»È¤ï¤ì¤Æ¤¤¤ë¤È»×¤ï¤ì¤ë +¾ì¹ç¤Ë¤Ï¡¢Ç¤°Õ¤Î¥Ý¡¼¥È¤ËÊѹ¹¤¹¤ë¡£ +\layout Itemize + +¥Ð¥Ã¥Õ¥¡¤¹¤ë¥ß¥êÉà - ¤³¤Î¿ô»ú¤Ï¡¢Linphone¤¬ºÆÀ¸¤òÂÔµ¡¤¹¤ë²»À¼¥Ñ¥±¥Ã¥È¤Î¿ô¤òɽ¤·¤Æ¤¤¤ë¡£²»À¼¥Ñ¥±¥Ã¥È¤¬Á÷¤ì¤¬¤Á¤Ê¾ì¹ç¤Ë¡¢ºÆÀ¸¤µ¤ì¤º¤ËÇË´þ¤µ¤ì¤ë²»À¼¥Ñ¥± +¥Ã¥È¤ò¸º¤é¤¹¤³¤È¤¬¤Ç¤­¤ë¡£¡ÖÅÓÀÚ¤ìÅÓÀڤ첻¡×¤¬Ê¹¤³¤¨¤ë¾ì¹ç¡¢¤³¤ÎÃͤòÂ礭¤¯¤¹¤ë¤ÈÅÁÁ÷¤Î¸úΨ¤ò¾å¤²¤ë¤³¤È¤¬¤Ç¤­¤ë¤¬¡¢²»À¼¤ÎÃٱ䤬Â礭¤¯¤Ê¤ë(Áê¼ê¤ÎÀ¼¤¬¾¯¤·ÃÙ¤ì¤ÆÊ¹ +¤³¤¨¤ë)¡£¤æ¤¨¤Ë¡¢¥Í¥Ã¥È¥ï¡¼¥¯¤¬´°Á´¤Ç¹âÉʼÁ¤Î¥ª¡¼¥Ç¥£¥ª¥É¥é¥¤¥Ð¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤ÎÃͤò3¥Ñ¥±¥Ã¥È¤Ë²¼¤²¤ì¤Ðû¤¤ÃÙ±ä»þ´Ö¤ÇÏ令ë¤è¤¦¤Ë¤Ê¤ë¡£ +\layout Subsection + + +\begin_inset LatexCommand \label{paramsip} + +\end_inset + +SIP +\layout Standard + +SIP(Session Initiation Protocol)¤Ï¡¢¥Í¥Ã¥È¥ï¡¼¥¯±Û¤·¤Ë¥á¥Ç¥£¥¢¤Î¥»¥Ã¥·¥ç¥ó¤ò³ÎΩ¤¹¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£¤Ä¤Þ¤ê¤Ï¡¢¥ê¥â¡¼¥È¥æ¡¼¥¶¡¼ +´Ö¤Î²ñÏäò³«»Ï¤·¤¿¤ê¡¢ÊÒÊý¤¬ÅÅÏäòÀڤ俤Ȥ­¤Ë²ñÏäò½ªÎ»¤·¤¿¤ê¤¹¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£ +\layout Itemize + +SIP¥Ý¡¼¥È - Linphone¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ÇSIP¥Ñ¥±¥Ã¥È¤ÎÁ÷¼õ¿®¤Ë5060È֥ݡ¼¥È¤òÍѤ¤¤ë¡£SIP¤Î¥Ý¡¼¥È¤Ï¡¢RFC¤Ë5060ÈÖ¤òÍѤ¤¤ë¤³¤È¤¬¶¯¤¯¿ä¾©¤µ +¤ì¤Æ¤¤¤ë¡£¤è¤Ã¤Æ¡¢²¿¤ò¤·¤¿¤¤¤Î¤«¤òÌÀ³Î¤ËÍý²ò¤·¤Æ¤¤¤ë¤È¤­¤ò½ü¤¤¤Æ¤Ï¡¢¤³¤ì¤òÊѹ¹¤¹¤Ù¤­¤Ç¤Ï¤Ê¤¤¡£ +\layout Itemize + +SIP¤ÎÅÐÏ¿¤Ë¤¹¤ë - ¥ê¥â¡¼¥È¤ÎSIP¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤·¤¿¤¤¤È¤­¤Ë¤Ï¡¢¤³¤Î¥Ü¥¿¥ó¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£SIP¥µ¡¼¥Ð¡¼¤Î¥µ¡¼¥Ó¥¹¤Ë¤Ï¡¢Å¾Á÷¤ä¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤¬¤¢ +¤ë¡£¾Ü¤·¤¯¤Ï¡¢¡Ö¥ê¥â¡¼¥È¤Î¥µ¡¼¥Ð¡¼¤ËÀܳ¤¹¤ë¡×¤ÎÀá¤ò»²¾È¤µ¤ì¤¿¤¤¡£ +\layout Subsection + + +\begin_inset LatexCommand \label{paramcodec} + +\end_inset + +¥³¡¼¥Ç¥Ã¥¯ +\layout Standard + +¥³¡¼¥Ç¥Ã¥¯¤È¤Ï¡¢ÆÃ¤Ë²»À¼¥Ç¡¼¥¿¤Î°µ½Ì¤Î¤¿¤á¤ËÀ߷פµ¤ì¤¿¥¢¥ë¥´¥ê¥º¥à¤Î¤³¤È¤ò¸À¤¦¡£Î㤨¤Ð¡¢16bit/8000Hz¤Î¥Ç¥¸¥¿¥ë²½¤µ¤ì¤¿²»À¼¤È¸À¤¨¤Ð¡¢128kbit/ +ÉäΥǡ¼¥¿¤Îή¤ì¤òɽ¤·¤Æ¤¤¤ë¡£GSM¥Ü¥³¡¼¥À¡¼¤ò»ÈÍѤ¹¤ë¤È¡¢¤³¤ì¤Ï13bit kbit/Éä˽̾®¤µ¤ì¤ë¡£ +\layout Itemize + +¥³¡¼¥Ç¥Ã¥¯¤ÎÁªÂò - Linphone¤Ï¿ô¼ïÎà¤Î¥³¡¼¥Ç¥Ã¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£ ¥³¡¼¥Ç¥Ã¥¯¤Î¥ê¥¹¥È¤Î²¼Éô¤Ë¤¢¤ë¥Ü¥¿¥ó¤ò»È¤¦¤È¡¢»È¤¤¤¿¤¤½çÈÖ¤Ëʤ٤뤳¤È¤¬¤Ç¤­¤ë¡£ +¤À¤¬¡¢¥Í¥Ã¥È¥ï¡¼¥¯Àܳ¤Î¥¿¥¤¥×¤Ë¤è¤Ã¤Æ¤Ï(¥Í¥Ã¥È¥ï¡¼¥¯¤ÎÀá¤ò»²¾È)¡¢»È¤¨¤Ê¤¤¥³¡¼¥Ç¥Ã¥¯¤Î¼ïÎà¤â¡¢»ÈÍѤ¹¤ë¤«¤É¤¦¤«¤ò·èÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ +\layout Subsection + + +\begin_inset LatexCommand \label{paramaudio} + +\end_inset + +¥ª¡¼¥Ç¥£¥ª¥Ñ¥é¥á¡¼¥¿¡¼ +\layout Standard + +¤³¤ÎÀá¤Ç¤Ï¡¢²»À¼µ»½Ñ¤Ë´Ø¤¹¤ë¥Ñ¥é¥á¡¼¥¿¡¼¤ò²òÀ⤹¤ë¡£ +\layout Itemize + +¥É¥é¥¤¥Ð¤ÎÁªÂò - Linux¤Ç¤Ï¡¢OSS(¥«¡¼¥Í¥ë¥É¥é¥¤¥Ð¡¼¤È¤â¸Æ¤Ð¤ì¤ë)¤ÈALSA¤È¡¢°Û¤Ê¤ë2¼ïÎà¤Î¥µ¥¦¥ó¥É¥«¡¼¥É¥é¥¤¥Ð¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤¬¡¢ALSA¥É +¥é¥¤¥Ð¤ÏALSA¥é¥¤¥Ö¥é¥ê¤òÄ̤¹¤³¤È¤Ç¡¢¤µ¤é¤Ê ¤ë¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤òȯ´ø¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢ALSA¥É¥é¥¤¥Ð¡¼(snd_*¤Ç»Ï¤Þ¤ë̾Á°¤Ç¤¢¤ë)¤ò»ÈÍѤ·¤Æ +¤¤¤ë¾ì¹ç¤Ï¡¢ALSA¥â¡¼¥É¤òÁªÂò¤¹¤ë¤Î¤¬¤è¤¤¡£Ê¬¤«¤é¤Ê¤±¤ì¤Ð¡¢OSS¤òÁªÂò¤¹¤ë¡£ +\layout Itemize + +Auto-kill¥ª¥×¥·¥ç¥ó - ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¦¤È¡¢linphone¤Ï¥µ¥¦¥ó¥É¥Ç¡¼¥â¥ó(esd¤Èartsd)¤òÄä»ß¤·¤è¤¦¤È¤¹¤ë¡£¤³¤ì¤Ï¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹ +¤Ë¹±µ×Ū¤Ê¼è¤ê³°¤»¤Ê¤¤¥í¥Ã¥¯¤ò¤«¤±¤Æ¤·¤Þ¤¤¡¢Linphone¤¬É¬ÍפȤ·¤Æ¤¤¤ë¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò¥ª¡¼¥×¥ó¤µ¤»¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥ª¥ó¤Ë¤· +¤Æ¤ª¤¯¤³¤È¤ò¿ä¾©¤¹¤ë¡£ +\layout Section + +ÅÅÏÃÄ¢ +\layout Standard + +ÅÅÏÃÄ¢(conection¤Î¥á¥Ë¥å¡¼¤ÎÃæ¤Ë¤¢¤ë)¤ò»È¤¦¤È¡¢SIP¥¢¥É¥ì¥¹¤òµ­²±¤È¸Æ½Ð¤·¤¬¤Ç¤­¤ë¡£SIP¥¢¥É¥ì¥¹¤Ï¡¢sip:¥æ¡¼¥¶¡¼Ì¾@¥É¥á¥¤¥ó̾¤Î·Á¼°¤Ç¤¢¤ë¡£¤Þ +¤¿¡¢¼«Ê¬¤¬Ê¬¤«¤ê¤ä¤¹¤¯¤¹¤ë¤¿¤á¤Ë¡¢É½¼¨¤µ¤ì¤ë̾Á°¤òÄɲ乤뤳¤È¤â¤Ç¤­¤ë¡£SIP¥¢¥É¥ì¥¹¤ò¸Æ¤Ó½Ð¤¹¤Ë¤Ï¡¢¥¢¥É¥ì¥¹¤Î¥ê¥¹¥È¤«¤éÁªÂò¤·¡¢¡ÖOK¡×¤Î¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë +¡£¤¹¤ë¤È¡¢ÁªÂò¤·¤¿¥¢¥É¥ì¥¹¤¬¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤Ë¸½¤ì¤ë¤Î¤¬³Îǧ¤Ç¤­¤ë¤À¤í¤¦¡£¸å¤Ï¡¢ÅÅÏäò¤«¤±¤ë¤¿¤á¤Ë¡ÖÅÅÏäò¤«¤±¤ë¡×¤Î¥Ü¥¿¥ó¤ò²¡¤»¤Ð¤è¤¤¤À¤±¤Ç¤¢¤ë¡£ +\layout Section + +SIP¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤ë +\layout Standard + +¥ê¥â¡¼¥È¤ÎSIP¥µ¡¼¥Ð¡¼¤Î¥µ¡¼¥Ó¥¹¤ËÅÐÏ¿¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¢¤ë¡£¤³¤Î¤è¤¦¤Ê¥µ¡¼¥Ó¥¹¤Ë¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤¬¤¢¤ë¡£ +\layout Itemize + +žÁ÷ - Linphon¤Ï¡¢¥µ¡¼¥Ð¡¼¤Ë¤Î¤è¤¦¤ÊSIP¥¢¥«¥¦¥ó¥È¤òºîÀ®¤¹¤ë¤è¤¦Í×ÀÁ¤¹¤ë¡£Î㤨¤Ð¡¢56k¤Î¥â¥Ç¥à +¤ò»È¤Ã¤ÆÃ±½ã¤Ë¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤Æ¤¤¤ë¾ì¹ç¡¢¤¢¤Ê¤¿¤ÎIP¥¢¥É¥ì¥¹¤ÏÀÅŪ¤Ç¤Ï¤Ê¤¯¡¢¥Í¡¼¥à¥µ¡¼¥Ð¡¼¤ËÃΤé¤ì¤Æ¤¤¤ë¥Û¥¹¥È̾¤â»ý¤Ã¤Æ¤¤¤Ê¤¤¡£¤³¤ì¤Ç¤Ï¡¢Í§Ã£¤Ï¤¢¤Ê¤¿¤¬ +IP¥¢¥É¥ì¥¹¤òÄÌÃΤ¹¤ë¥á¡¼¥ë¤òÁ÷¤é¤Ê¤¤¸Â¤ê¡¢¤¢¤Ê¤¿¤ËÏ¢Íí¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¡£Îã¤È¤·¤Æ¡¢¤ËÅÐÏ¿¤ò¹Ô¤¦¤Î¤Ï´Êñ +¤Ç¤¢¤ë¡£¤¢¤Ê¤¿¤Î¥æ¡¼¥¶¡¼Ì¾¤Ï¡Öbob¡×¤À¤È¤¹¤ë¡£¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤ëºÝ¤Ë¡¢Linphone¤Ï¤¢¤Ê¤¿¤ÎIP¥¢¥É¥ì¥¹¤ò¥µ¡¼¥Ð¡¼¤ËÁ÷¿®¤·¡¢¥¢¥«¥¦¥ó¥È¡Ösip:bob@e +xample_registrar.com¡×¤¬ºîÀ®¤µ¤ì¤ë¡£¤½¤¦¤¹¤ë¤È¡¢¤¢¤Ê¤¿¤Îͧã¤Î¥¸¥à¤Ï¡¢¤È¤¤¤¦¥¢¥É¥ì +¥¹¤ËÅÅÏäò¤«¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ÅöÁ³¤Î¤³¤È¤Ê¤¬¤é¡¢ +\begin_inset Quotes eld +\end_inset + +example_registar.com +\begin_inset Quotes erd +\end_inset + +¤Ï¡¢¥¦¥§¥ë¥Î¥ó¡¦¥É¥á¥¤¥ó¥Í¡¼¥à¤Ç¤¢¤ë¡£¼¡¤Ë¡¢¥¸¥à¤ÎLinphone¤Ï¥Ü¥Ö¤Î³Î¼Â¤Ê¥í¥±¡¼¥·¥ç¥ó¤ò¼¨¤¹Å¾Á÷¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤ë¡£¤½¤¦¤·¤Æ¡¢¥Ü¥Ö¤Î²È¤Ç¥Ù¥ë¤¬ÌĤë¤Î¤Ç¤¢ +¤ë¡£ +\layout Itemize + +¥×¥í¥¯¥· - ¤³¤ì¤â¡¢Å¾Á÷¥á¥Ã¥»¡¼¥¸¤¬¥¸¥à¤ÎÅÅÏäËÁ÷¿®¤µ¤ì¤Ê¤¤¤³¤È¤ò¤Î¤¾¤±¤Ð¡¢Æ±Íͤθ¶Íý¤Ç¤¢¤ë¡£¤½¤ÎÂå¤ï¤ê¤Ë¡¢¥×¥í¥¯¥·¤Ï¥Ü¥Ö¤ÎLinphone¤Þ¤Ç¥À¥¤¥ì¥¯¥È¤Êž +Á÷¤ò¹Ô¤¦¡£ +\layout Standard + +¤³¤Î¤è¤¦¤ÊÅÐÏ¿¤Ï¡¢¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤Ë¤ª¤¤¤Æ¤âƱÍͤ˹Ԥï¤ì¤ë¡£¤³¤ì¤Ï¡¢Linphone¤ò¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÃæ¤Ç»È¤¦¤È¤­¤ËÍ­¸ú¤Ç¤¢¤ë¡£¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥· +¤Ï¡¢¥×¥é¥¤¥Ù¡¼¥È¥µ¥Ö¥Í¥Ã¥È¤Ë¤¢¤ëHTTP¥×¥í¥¯¥·¤ÈƱÍͤÎÌò³ä¤ò²Ì¤¿¤¹¡£³°Éô¤Ø¤Î²ñÏäϥ¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤¬°·¤¤¡¢¥Í¥Ã¥È¥ï¡¼¥¯³°¤Ë¤¤¤ë¤È»×¤ï¤ì¤ë¿Í¤Ø¤Î²ñÏäΞÁ÷ +¤ÎǤ¤òÉ餦¡£ +\layout Standard + +ÅÐÏ¿¥µ¡¼¥Ð¡¼¤òLinphone¤Ç»È¤¦¤Ë¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤éSIP¤Î¥¿¥Ö¤òÁªÂò¤·¡¢¡ÖSIP¥¢¥É¥ì¥¹¤òÅÐÏ¿¤¹¤ë¡×¤Î¥Ü¥Ã¥¯¥¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ÅÐÏ¿¤¹¤ë¥¢¥É¥ì¥¹¤ò +ŬÀڤʥե£¡¼¥ë¥É¤ËÆþÎϤ·¤¿¤é¡¢¼¡¤Ë¡¢Å¾Á÷¤«¥×¥í¥¯¥·¤«¡¢Âбþ¤¹¤ë¥Ü¥Ã¥¯¥¹¤ò¥Á¥§¥Ã¥¯¤·¡¢ÅÐÏ¿¤òÍ׵᤹¤ë¥µ¡¼¥Ó¥¹¤Î¥¿¥¤¥×¤òÁªÂò¤¹¤ë¡£¤Þ¤¿¡¢³°Éô¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ø²ñÏäòÆ© +²á¤µ¤»¤ë¤¿¤á¤ÎÅÐÏ¿¥µ¡¼¥Ð¡¼¤¬É¬ÍפʤȤ­¤Ë¤Ï¡¢¡Ö¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤È¤·¤Æ»È¤¦¡×¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ +\layout Standard + +ºÇ¸å¤Ë¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎOK¥Ü¥¿¥ó¤ò²¡¤¹¤È¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÏÊĤ¸¤é¤ì¡¢¤¿¤À¤Á¤ËÅÐÏ¿¥µ¡¼¥Ð¡¼¤Ë¤¢¤Ê¤¿¤ÎÀµ³Î¤Ê¾ì½ê¤òÃΤ餻¤ë¤¿¤á¤Î¸ò¾Ä¤¬»Ï¤Þ¤ë¡£Linph +one¤ò¥·¥ã¥Ã¥È¥À¥¦¥ó¤¹¤ë¤È¤­¤Ë¤Ï¡¢ÅÐÏ¿¥µ¡¼¥Ð¡¼¤«¤é¤¢¤Ê¤¿¤Î¾ì½ê¤ÎÅÐÏ¿¤ò²ò½ü¤¹¤ë¤¿¤á¡¢¿ôÉô֤«¤«¤ë¡£ +\layout Standard + +¥Ñ¥Ö¥ê¥Ã¥¯¤ÊÅÐÏ¿¥µ¡¼¥Ð¡¼¤Î¥ê¥¹¥È¤Ï¡¢°Ê²¼¤Ë·ÇºÜ¤µ¤ì¤Æ¤¤¤ë¡£ +\begin_inset LatexCommand \url[http://www.cs.columbia.edu/~hgs/sip/servers.html]{http://www.cs.columbia.edu/~hgs/sip/servers.html} + +\end_inset + + +\layout Standard + +¤À¤¬¡¢»Äǰ¤Ê¤³¤È¤Ë¡¢¤³¤ì¤é¤Î¥µ¡¼¥Ð¡¼¤Î¿¤¯¤Ï¤â¤¦Æ°¤¤¤Æ¤¤¤Ê¤¤¡£¤ª¤½¤é¤¯¡¢¶áº¢¤ÎÅŵ¤ÄÌ¿®¶È³¦¤Î´íµ¡¤Ë¤è¤ë¤â¤Î¤Ç¤¢¤í¤¦¡£Â¾¤ÎɬÍפȤµ¤ì¤ëǧ¾ÚÊýË¡¤Ï¡¢¸½ºßLinpho +ne¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¡£ +\layout Standard + +̵ÍѤʼê´Ö¤òÈò¤±¤¿¤¤¤È¤­¤Ë¤Ï¡¢»ÈÍѲÄǽ¤Êưºî¤·¤Æ¤¤¤ë¥Ñ¥Ö¥ê¥Ã¥¯¤ÊSIP¥µ¡¼¥Ð¡¼¤Î¥ê¥¹¥È¤¬¡¢Linphoe¤Î°ÊÁ°¤ÎWEB¥µ¥¤¥È¤Î¥ê¥¹¥È¤¬ +\begin_inset LatexCommand \url[http://simon.morlat.free.fr/english/servers.html]{http://simon.morlat.free.fr/english/servers.html} + +\end_inset + +¤Ç»²¾È¤Ç¤­¤ë¡£ +\layout Section + +¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÆâ¦¤Ç +\layout Standard + +¸½ºß¤Ç¤Ï¡¢SIP¥×¥í¥¯¥·¤òÍѤ¤¤ë¤³¤È¤Ç¡¢Linphone¤Ï¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÆâ¦¤ÇÍøÍѲÄǽ¤Ç¤¢¤ë¡£SIP¥µ¡¼¥Ð¡¼¤Ï¡¢¥×¥é¥¤¥Ù¡¼¥È¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î²ñÏäò³°Éô¤Î +¥Í¥Ã¥È¥ï¡¼¥¯¤ØÅ¾Á÷¤¹¤ëǤ¤òÉ餦¡£oSIP¥é¥¤¥Ö¥é¥ê¤òÍøÍѤ·¤¿SIP¥×¥í¥¯¥·¤Ï¡¢ +\begin_inset LatexCommand \url[http://osipproxy.sourceforge.net]{http://osipproxy.sourceforge.net} + +\end_inset + +¤Ç³«È¯¤µ¤ì¤Æ¤¤¤ë¡£ +\layout Standard + +SIP¤ÎÀá¤Î¡¢¡ÖSIP¤ËÅÐÏ¿¤¹¤ë¡×¤Î¹àÌܤò»²¹Í¤Ë¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÇÍѤ¤¤ëSIP¥×¥í¥¯¥·¤ò»ØÄꤷ¤ÆÍߤ·¤¤¡£ÀßÄꤹ¤ë¤Ë¤Ï¡¢SIP¥×¥í¥¯¥·¤Î¥¢¥É¥ì¥¹¤òÆþÎϤ·¡¢¡Ö +¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤È¤·¤ÆÅÐÏ¿¤¹¤ë¡×¤Î¥Ü¥¿¥ó¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ +\layout Standard + +¤Ê¤ª¡¢SIP¥×¥í¥¯¥·¤¬É¬Íפʤ¤¾ì¹ç¤â¤¢¤ë¡£¥Ñ¥Ö¥ê¥Ã¥¯¥¢¥É¥ì¥¹¤ò»ý¤Ã¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯²¼¤Ë¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤¬¤¢¤ê¡¢¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤Ï³°Éô¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î +¥Ñ¥±¥Ã¥È¤ÎÁ÷¼õ¿®¤ò¥Õ¥£¥ë¥¿¡¼¤¹¤ë¤À¤±¤Î¾ì¹ç¤Ç¤¢¤ë¡£¤³¤Î¾ì¹ç¤Ë¤Ï¡¢¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤Î¥Þ¥·¥ó¤ÎSIP¤ÈRTP¤Î¥Ý¡¼¥È¤ò¥ª¡¼¥×¥ó¤¹¤ë¤À¤±¤Ç¤è¤¤¡£SIP¥Ý¡¼¥È¤Ï¥×¥í¥Ñ +¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎSIP¤Î¥¿¥Ö¤Ë¡¢RTP¥Ý¡¼¥È¤Ï¡¢RTP¥Ý¡¼¥È¤ÏRTP¤Î¥¿¥Ö¤Ë¤¢¤ë¡£Î¾¼Ô¤È¤â¤ËÊѹ¹²Äǽ¤Ç¤¢¤ë¤¬¡¢SIP¥Ý¡¼¥È(5060ÈÖ)¤Ï¡¢Êѹ¹¤·¤Ê¤¤¤Ç¤ª¤¯¤³¤È +¤¬¶¯¤¯¿ä¾©¤µ¤ì¤ë¡£ +\layout Section + +º¤¤Ã¤¿¤È¤­¤Ë¤Ï +\layout Subsection + +Àܳ¾å¤Ë¤ª¤±¤ëÌäÂê +\layout Quotation + +»ä¤Ï¡¢Í§¿Í¤ËÅÅÏäò¤«¤±¤è¤¦¤È¤·¤¿¤À¤¬¡¢¤Ê¤Ë¤âµ¯¤­¤Ê¤¤¡£¥Ù¥ë¤âÌĤé¤Ê¤¤¡¢¤Þ¤Ã¤¿¤¯²¿¤âµ¯¤³¤é¤Ê¤¤¡£ +\layout Standard + +Linphone¤¬»ÈÍѤ·¤Æ¤¤¤ë¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ØÀܳ¤·¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹(¤Þ¤¿¤Ï¡¢²ñÏ䬽ФƤ¤¤¯¤Ù¤­¥Í¥Ã¥È¥ï¡¼¥¯)¤ò¸¡¾Ú¤·¤Æ¤ß¤ë¤Ù¤­¤Ç¤¢¤í¤¦¡£¥×¥í +¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤Î¡¢¥Í¥Ã¥È¥ï¡¼¥¯¥¿¥Ö¤«¤é¡¢Àµ¤·¤¤¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ó¤Ç¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ +\layout Standard + +¤¢¤ë¤¤¤Ï¡¢¤¢¤Ê¤¿¤¬Àܳ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¿Í¤¬¡¢¸½ºß·ÐÏ©¤¬Àܳ¤Ç¤­¤Ê¤¤¾õ¶·¤Ë¤¢¤ë¤Î¤«¤âÃΤì¤Ê¤¤¡Ä¡Ä¡£ +\layout Subsection + +²»À¼¤Ë¤ª¤±¤ëÌäÂê +\layout Quotation + +Linphone¤Ï¡¢¥ê¥â¡¼¥È¤ÎSIP URL¤ËÀܳ¤·¤Æ¤¤¤ë¤è¤¦¤Ç¡¢¥Ù¥ë¤ÏÌĤäƤ¤¤ë¤è¤¦¤À¡£¤±¤ì¤É¤â¡¢Áê¼ê¤¬ÅÅÏä˽Ф¿¤È¤­¤Ë¤Ï²¿¤âµ¯¤³¤é¤º¡¢¤ª¸ß¤¤¤ÎÀ¼¤¬Ê¹¤³¤¨¤Ê¤¤ +¡£ +\layout Itemize + +ÂçÄñ¤Î¿Í¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤é¡¢Àµ¤·¤¤¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ó¤Ç¤¤¤Ê¤¤¤¿¤á¤Ë¡¢ÌäÂê¤òÀ¸¤¸¤µ¤»¤Æ¤·¤Þ¤¦¡£¥À¥¤¥ä¥ë¥¢¥Ã¥×Àܳ¤Ç¤Ï¡¢¡Öppp0¡×¤Ë¤Ê¤ë +¤Ï¤º¤Ç¤¢¤ë¡£¡Ö\i \"{} +lo¡×¤Ï¡¢¥Æ¥¹¥ÈÍѤˡ¢sipomatic¤À¤±¤Ë»ÈÍѤµ¤ì¤ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤µ¤ì¤¿¤¤¡£¤½¤Î¾¤Î¾ì¹ç¤Ç¤Ï µ¡Ç½¤·¤Ê¤¤¡£ +\layout Itemize + +¤Þ¤º¤Ï¡¢Á÷Ïò»Î̤ȼõÏò»Î̤ò¾å¤²¤Æ¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ +\layout Itemize + +²»À¼¤¬¤È¤®¤ì¤È¤®¤ì¤Ë¤Ê¤ë¾ì¹ç¤Ï¡¢¤³¤ì¤ò²óÈò¤¹¤ë¤¿¤á¤Ë¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎRTP¥¿¥Ö¤Î¡Ö¥Ð¥Ã¥Õ¥¡¤¹¤ë¥ß¥êÉáפÎÃͤòÂ礭¤¯¤·¤Æ¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£¤·¤«¤·¡¢¤³¤ì¤Ï +ÄÌ¿®¤ÎÃÙ±ä¤òÁýÂ礵¤»¤ë¡£ +\layout Itemize + +Linphone¤¬¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Ê¤¤¤È¤­¤Ë¤Ï¡¢/dev/dsp¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ò³Îǧ¤·¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò»ÈÍѤ¹¤ë¤¹¤Ù¤Æ¤Î¥×¥í¥°¥é¥à(xm +ms kaimanÅù)¤òÄä»ß¤¹¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ +\layout Itemize + +ALSA¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ¹¤ë( +\begin_inset LatexCommand \url[http://www.alsa-project.org]{http://www.alsa-project.org} + +\end_inset + +¤ò»²¾È¤µ¤ì¤¿¤¤)¡£ÂçÄñ¤Î¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥¸¥ç¥ó¤Ï¡¢¤Þ¤À¸Å¤¤¥«¡¼¥Í¥ë¸øÇ§¤Î¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ·¤Æ¤¤¤ë¤¬¡¢¤³¤ì¤ÏÂ礭¤ÊÃÙ±ä¤È¿¤¯¤Î¥Ð¥°¤ò´Þ¤ó¤Ç¤¤¤ë¡£Linphone¤Ï +¡¢ALSA¥É¥é¥¤¥Ð¡¼¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤¿¸å¤Î¥ê¥³¥ó¥Ñ¥¤¥ë¤òɬÍפȤ·¤Ê¤¤¤³¤È¡¢¤Þ¤¿¡¢¥ª¡¼¥Ç¥£¥ª¤ÎÀá¤Î¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤é¤ÎALSA¥â¡¼¥É¤Ø¤ÎÊѹ¹¤Ïɬ¿Ü¤Ç¤Ï¤Ê¤¤¤³ +¤È¤â½Ò¤Ù¤Æ¤ª¤³¤¦¡£ +\layout Section + +¥Ð¥°Êó¹ð¤ÈÄó°Æ +\layout Standard + +¤Þ¤º¤Ï¡¢Linphone¤Î¥Û¡¼¥à¥Ú¡¼¥¸ +\begin_inset LatexCommand \url[http://www.linphone.org]{http://www.linphone.org} + +\end_inset + +¤«¤é¡¢ºÇ¿·¤ÎLinphone¤ò»ÈÍѤ·¤Æ¤¤¤ë¤«¤ò³Îǧ¤·¤ÆÍߤ·¤¤¡£ +\layout Standard + +¤â¤·¡¢Linphone¤¬¥¯¥é¥Ã¥·¥å¤·¤¿¤È¤­¤Ë¤Ï¡¢¥Ð¥°¥ì¥Ý¡¼¥È¤òľÀÜbugs@linphone.org¤Þ¤ÇÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤â¤·¡¢¥¯¥é¥Ã¥·¥å¤Ï¤·¤Ê¤¤¤¬Linphone¤¬ +ưºî¤·¤Ê¤¤¤È¤­¤Ë¤Ï¡¢¾å¤Î¥¢¥É¥ì¥¹¤Ë¥Ð¥°¥ì¥Ý¡¼¥È¤òÁ÷¤ëÁ°¤Ë¡¢¥Þ¥Ë¥å¥¢¥ë¤ò ¤â¤¦°ìÅÙÆÉ¤ß¤«¤¨¤·¤ÆÍߤ·¤¤¡£¤â¤·¡¢²¿¤«¤òÄ󰯤·¤¿¤¤¤È¤­¤Ë¤Ï¡¢±ó褻¤º¤Ë¡¢help@lin +phone.org¤Þ¤Ç¥á¡¼¥ë¤òÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤Ê¤ª¡¢¥Ó¥Ç¥ª¥µ¥Ý¡¼¥È¤È²ñµÄ¤Ï¡¢¾­Íè¤Î·×²è¤Ë¤¢¤ë¤³¤È¤ò½Ò¤Ù¤Æ¤ª¤³¤¦¡£¤Þ¤¿¡¢Linphonr¤ÎËÝÌõ¤Ë¶½Ì£¤ò»ý¤Ã¤¿¿Í¤Ï¡¢ÇÛÉÛ +¤µ¤ì¤Æ¤¤¤ëpo/linpyhone.pot¤Ë´ð¤Å¤¤¤¿xx.po¥Õ¥¡¥¤¥ë¤ò»ä¤ËÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤Þ¤¿¡¢¤³¤Î¥Þ¥Ë¥å¥¢¥ë¤ò¾¤Î¸À¸ì¤ËËÝÌõ¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¢¤ë¡£¤¤¤º¤ì¤Ë¤·¤Æ¤â¡¢ +¾Ü¤·¤¤¤³¤È¤¬ÃΤꤿ¤¤¤È¤­¤Ï»ä¤ËÏ¢Íí¤·¤ÆÍߤ·¤¤¡£ +\layout Section + +ºî¼Ô +\layout Standard + +Simon MORLAT (simon.morlat@free.fr) ¤¬À½ºî¤·¤¿Éôʬ¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£ +\layout Itemize + +¥á¥¤¥ó¥×¥í¥°¥é¥à(src) +\layout Itemize + +RTP ¥é¥¤¥Ö¥é¥ê (lprtplib) +\layout Itemize + +osipua -- osip¥¹¥¿¥Ã¥¯¤Ë´ð¤Å¤¤¤¿¥æ¡¼¥¶¡¼¥¨¡¼¥¸¥§¥ó¥È¤ÎAPI¡£oss¤ÈALSA¥É¥é¥¤¥Ð¡¼¤Î²»À¼¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¡£ +\layout Itemize + +(²»À¼) lpc10-1.5ÍѤÎwrappers, gsm and g711 ¥³¡¼¥Ç¥Ã¥¯ +\layout Standard + +Aymeric Moizard (jack@atosc.org)¤Ï¡¢ Linphone¤¬ÍøÍѤ·¤Æ¤¤¤ëosip¥¹¥¿¥Ã¥¯¤òÀ½ºî¤·¤¿¡£ +\layout Standard + +GSM¥é¥¤¥Ö¥é¥ê¤Ï¡¢Jutta Degener¤ÈCarsten Bormann(Technische Universitaet Berlin)¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿¡£ +\layout Standard + +The LPC10-1.5 ¥é¥¤¥Ö¥é¥ê¤Ï¡¢Andy Fingerhut(Applied Research Laboratory)¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿¡£ + <-- ¤³¤ÎÉôʬ¤Ï¥¹¥Ú¡¼¥¹¤ÎÅÔ¹ç¤Ë¤è¤ê¾Êά²Äǽ¤Ç¤¢¤ë¡£ Washington University, Campus Box 1045/Bryan + 509 ¥¹¥Ú¡¼¥¹¤Ë¸Â¤ê¤¬¤¢¤ë¾ì¹ç¤Ï¡¢¤³¤³¤«¤é¡£One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wu +stl.edu http://www.arl.wustl.edu/~jaf/¤µ¤é¤Ê¤ë¾ðÊó¤Ï¡¢gsmlib¤Èlpc10-1.5¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò»²¾È¤µ¤ì¤¿¤¤ +¡£ +\layout Standard + +Pablo Marcelo Moia -- ¥¢¥¤¥³¥óÀ½ºî +\layout Section + +¼Õ¼­ +\layout Standard + +GTK¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¥Ó¥ë¥À¡¼¤ÎDaemon Chaplin¤Ë´¶¼Õ¤ò¡£ +\layout Standard + +ÃøÌÀ¤ÊoSIP¥é¥¤¥Ö¥é¥ê¡¼¤ÎAymeric Moizard¤Ë´¶¼Õ¤ò¡£ +\layout Standard + +LPC10-1.5¤ÈGSM¥³¡¼¥É¤Îºî¼Ô¤Ë´¶¼Õ¤ò¡£ +\layout Standard + +RPM¤òÄ󶡤·¤Æ¤¯¤ì¤¿¡¢Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com )¤Ë´¶¼Õ¤ò¡£ +\layout Standard + +Linphone¤ËÁÇŨ¤Ê¥¢¥¤¥³¥ó¤òÄ󶡤·¤Æ¤¯¤ì¤¿¡¢Pablo Marcelo Moia¤Ë´¶¼Õ¤ò¡£ +\layout Standard + + +\begin_inset LatexCommand \tableofcontents{} + +\end_inset + + +\the_end diff --git a/linphone/share/ja/manual.sgml b/linphone/share/ja/manual.sgml new file mode 100644 index 000000000..f36f0ebb6 --- /dev/null +++ b/linphone/share/ja/manual.sgml @@ -0,0 +1,480 @@ + + +
+ + + + LINPHONE¥æ¡¼¥¶¡¼¥Þ¥Ë¥å¥¢¥ë + + + Simon Morlat (simon.morlat@linphone.org) + Ìõ¡§»³¸ýÁ±Ìé(yushiya@anet.ne.jp) + + + 11-13-2001 + + + + + ¤Ï¤¸¤á¤Ë + + + Linphone¤Ï¡¢¥·¥ó¥×¥ë¤Ê¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÅÅÏäǤ¢¤ê¡¢Æó¼Ô´Ö¤ÎÄÌÏäò¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ê¤É¤ÎIPÌÖ¤òÄ̤¸¤Æ²Äǽ¤Ë¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡£Linphone¤òµ¯Æ°¤¹¤ë¤Ë¤Ï°Ê²¼¤Î¤â¤Î¤¬É¬ÍפȤʤ롣 + + + + + Linux(BSD¤Î¤è¤¦¤Ê¾¤ÎUNIX¤Ç¤âµ¯Æ°¤¹¤ë¤À¤í¤¦¤¬¡¢Linux´Ä¶­¤Û¤É¾¤Î´Ä¶­¤Ï¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¡£) + + + + + gnome1.2°Ê¾å¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤ë¤³¤È¡£É¬¤º¤·¤âµ¯Æ°¤·¤Æ¤¤¤ëɬÍפϤʤ¤¡£ + + + + + ¥Ø¥Ã¥É¥Û¥ó¤«¥¹¥Ô¡¼¥«¡¼¡£ + + + + + ¥µ¥¦¥ó¥É¥«¡¼¥É¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤Æ¤¤¤ë¤³¤È¡£ + + + + + ¥Þ¥¤¥¯¥í¥Õ¥©¥ó + + + + + ¥â¥Ç¥à¤ä¥¤¡¼¥µ¥Í¥Ã¥ÈÅù¤òÍѤ¤¤¿¡¢¥Í¥Ã¥È¥ï¡¼¥¯(¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÅù)¤Ø¤ÎÀܳ¡£ + + + + + ¤Ê¤ª¡¢Linphone¤òµ¯Æ°¤¹¤ëÁ°¤Ë¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò»ÈÍѤ¹¤ë¤¹¤Ù¤Æ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò½ªÎ»¤·¤Æ¤ª¤¯¤Î¤¬¤è¤¤¤À¤í¤¦¡£ + + + Linphone¤Ï¥Õ¥ê¡¼¥¦¥§¥¢¤Ç¤¢¤ê¡¢GNU Public Licence¤Ë½¾¤Ã¤ÆÇÛÉÛ¤µ¤ì¤ë¡£ + + + ·Ù¹ð - Åö¥½¥Õ¥È¥¦¥§¥¢¤ÏÊݾڤʤ·¤ËÄ󶡤µ¤ì¤ë¤â¤Î¤Ç¤¢¤ë¡£¾Ü¤·¤¯¤ÏCOPYING¥Õ¥¡¥¤¥ë¤ò»²¾È¤µ¤ì¤¿¤¤¡£¤Ê¤ª¡¢Linphone¤Ï°Å¹æ²½¤òÍѤ¤¤Ê¤¤¤¿¤á¡¢°­°Õ¤¢¤ë¿Íʪ¤¬Íưפ˲»À¼¾ðÊó¤ò½¦¤¦¤³¤È¤¬¤Ç¤­¤ë¡£¤Ä¤Þ¤ê¡¢Linphone¤ÏÈëÌ©¤Î²ñÏäËÍѤ¤¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤¡£¤Þ¤¿¡¢Linphone¤Ï¥ë¡¼¥È¸¢¸Â¤Çµ¯Æ°¤·¤Ê¤¤¿ä¾©¤¹¤ë¡£ + + + + + Linphone¤Îµ¯Æ° + + + Linphone¤Ï»°¤Ä¤ÎÊýË¡¤Çµ¯Æ°¤Ç¤­¤ë¡£ + + + + + Ä̾ï¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È¤·¤Æ - Linphone¤Ï¡¢gnome¥á¥Ë¥å¡¼¤ÎÃæ¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥µ¥Ö¥á¥Ë¥å¡¼¤Ë¸½¤ì¤ë¡£¤â¤·¡¢gnome¤òµ¯Æ°¤·¤Æ¤Ê¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢Î㤨¤Ð¥¿¡¼¥ß¥Ê¥ë¤Ë“linphone”¤È¥¿¥¤¥×¤¹¤ë¤³¤È¤Ç¼Â¹Ô¤Ç¤­¤ë¡£Linphone¤¬µ¯Æ°¤·¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ÅÅÏäò¼õ¤±¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡£ + + + + + gnome¥¢¥×¥ì¥Ã¥È¤È¤·¤Æ - gnome¥Ñ¥Í¥ë¤ò±¦¥¯¥ê¥Ã¥¯¤¹¤ë¤È¡¢¥Ñ¥Í¥ë¤ËLinphone¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤ë¡£Linphone¤Ï¥Í¥Ã¥È¡¼¥ï¡¼¥¯¥á¥Ë¥å¡¼¤ÎÃæ¤Ë¤¢¤ë¡£¤Ò¤Ã¤½¤ê¤È¥Ñ¥Í¥ë¤ÎÃæ¤Çµ¯Æ°¤¹¤ë¤³¤È¤Ç¡¢Linphone¤Ï¡¢¤¿¤È¤¨¥¦¥¤¥ó¥É¥¦¤¬¸½¤ì¤Æ¤¤¤Ê¤¯¤Æ¤âÅÅÏäò¼õ¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤Ëɽ¼¨¤µ¤»¤¿¤¤¤È¤­¤Ë¤Ï¡¢¥¢¥×¥ì¥Ã¥È¤ò¥¯¥ê¥Ã¥¯¤¹¤ì¤Ð¤è¤¤¡£ÅÅÏ䬤«¤«¤Ã¤Æ¤­¤¿¤È¤­¤Ë¤Ï¡¢¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤¬É½¤ì¤Æ¡¢Ä̾ïÄ̤ê¤Ë¥Ù¥ë¤¬ÌĤäƤ¤¤ë¤Î¤¬Ê¹¤³¤¨¤ë¤À¤í¤¦¡£ + + + + + ¤Ò¤Ã¤½¤ê¤È¥Ç¡¼¥â¥ó¤È¤·¤Æ - ¤³¤ì¤Ï¡¢Èógnome¥æ¡¼¥¶¡¼¤Î¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£Î㤨¤Ðkde¤Ç¤Ï¡¢/home/user/.kde2/AutoStart¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡¢¥í¥°¥¤¥ó»þ¤Ëµ¯Æ°¤·¤¿¤¤¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥ê¥ó¥¯¤òŽ¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢¾å½Ò¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Õ¥¡¥¤¥ë¥Þ¥Í¡¼¥¸¥ã¡¼¤Ç°Üư¤·¡¢±¦¥¯¥ê¥Ã¥¯¤Ç¸½¤ì¤ë¥¢¥×¥ì¥Ã¥È¤«¤é¡¢¡Ö¥ê¥ó¥¯¤ÎÄɲáפò¼Â¹Ô¤¹¤ì¤Ð¤è¤¤¡£¤Ê¤ª¡¢µ¯Æ°¤¹¤ë¥³¥Þ¥ó¥É¤Ï¡¢“ linphone -deamon”¤Ç¤¢¤ë¡£¤³¤Î¾ì¹ç¡¢Linphone¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò¸«¤ë¤³¤È¤Ï¤Ê¤¤¤¬¡¢É½¼¨¤µ¤»¤¿¤¤¤È¤­¤Ë¤Ï¥¿¡¼¥ß¥Ê¥ëÅù¤«¤éLinphone¤òµ¯Æ°¤µ¤»¤ë¤Î¤ÈƱÍͤ˥¿¥¤¥×¤¹¤ì¤Ð¤è¤¤¡£ + + + + + + + ÅÅÏäò¤«¤±¤ë + + + + ´ðËÜŪ¤Ê¸¶Â§ + + + ¡Ösip:¥æ¡¼¥¶¡¼Ì¾@¥Û¥¹¥È̾¡×¤Î¤è¤¦¤ÊSIP URL¤Ë¤è¤Ã¤Æ¶èÊ̤µ¤ì¤ë¡£SIP URL¤Ï¡¢Æ¬¤Î¡Ösip:¡×¤ò½ü¤±¤ÐÈó¾ï¤Ëe-mail¥¢¥É¥ì¥¹¤È»÷¤Æ¤¤¤ë¡£ + + + ¥æ¡¼¥¶¡¼Ì¾¤Ï¡¢UNIX¥Þ¥·¥ó¤Î¥í¥°¥¤¥ó¥Í¡¼¥à¤Î¤è¤¦¤Ê¤â¤Î¤Ç¡¢¥Û¥¹¥È̾¤Ï¥æ¡¼¥¶¡¼¤¬Àܳ¤¹¤ë¥Þ¥·¥ó¤Î̾Á°¤äIP¥¢¥É¥ì¥¹¤Ç¤¢¤ë¡£ + + + ¤Ê¤ª¡¢SIP¤Ï¥·¥ó¥×¥ë¤ËÀ߷פµ¤ì¤¿¿·¤·¤¤ÄÌ¿®¤Î¥×¥í¥È¥³¥ë¤Ç¤¢¤ê¡¢H323¤È¤Ï¤Þ¤Ã¤¿¤¯¸ß´¹À­¤¬¤Ê¤¤¤³¤È¤ËÃí°Õ¤µ¤ì¤¿¤¤¡£ + + + + + »ÈÍÑÎã:Æó¿Í¤Î¥æ¡¼¥¶¡¼¤¬¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ë¥â¥Ç¥à¤ÇÀܳ¤·¤Æ¤¤¤ë¤È¤­ + + + ¤³¤ì¤Ï¡¢Ã±½ã¤Ê¼ê³¤­¤Ç¤¢¤ë¡£É¬ÍפȤµ¤ì¤ë¥Í¥Ã¥È¥ï¡¼¥¯¤Ï¡¢ + + + + + 28k°Ê¾å¤Î¥â¥Ç¥à + + + + + ¤Ç¤¢¤ë¡£ + + + ¥·¥Ê¥ê¥ª¤Ï¡¢°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£ + + + + + ¥Ü¥Ö¤Ï¥È¥à¤Ë21:00¤ËÅÅÏ乤뤳¤È¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¥È¥à¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ëkppp¤ägppp¤äwmdial¤Ê¤É¤ÇÀܳ¤·¤Æ¤¤¤ë¡£ + + + + + ¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤¿¤é¡¢¥Ü¥Ö¤ÏLinphone¤òµ¯Æ°¤Ç¤­¤ë¡£kppp¤ägppp¤Ê¤É¤ÎÅý·×¥Ü¥Ã¥¯¥¹¤ò³«¤¤¤Æ¡¢¥Ü¥Ö¤Ï¼«Ê¬¤ÎIP¥¢¥É¥ì¥¹¤òÃΤ뤳¤È¤¬¤Ç¤­¤ë¡£(/sbin/ifconfig¤ò»È¤ï¤Ê¤¯¤Æ¤â³Îǧ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë)¡£ + + + + + ¼¡¤Ë¡¢¥È¥à¤Ï¥Ü¥Ö¤Ë¡ÖËͤÎIP¥¢¥É¥ì¥¹¤Ï¡¢xxx.xxx.xxx.xxx¤À¤è¡£¡×¤È¤¤¤¦ÆâÍÆ ¤Îe¥á¡¼¥ë¤òÁ÷¤ë¡£ + + + + + ¤½¤Î¤¹¤°¤¢¤È¤Ç¡¢¥È¥à¤Î²È¤ÎLinphone¤Î¥Ù¥ë¤¬ÌĤ롣¤½¤Î¤È¤­¡¢¥Ü¥Ö¤Ë¤â¸þ¤³¤¦¤Ç¥Ù¥ë¤¬ÌĤäƤ¤¤ë¤Î¤¬Ê¬¤«¤ë¤è¤¦¤Ë¥Ù¥ë¤Î²»¤¬Ê¹¤³¤¨¤ë¡£¤½¤³¤Ç¡¢¥È¥à¤¬ÅÅÏä˽Ф뤿¤á¤Ë¡ÖÅÅÏäò¤È¤ë¡×¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë¤À¤±¤Ç¤è¤¤¡£¤½¤¦¤¹¤ì¤Ð¡¢¸ß¤¤¤Ë²ñÏ䬤Ǥ­¤ë¤Ï¤º¤Ç¤¢¤ë¡£ + + + + + ÌäÂ꤬¤¢¤Ã¤¿¤é¡¢Âè4Àá¤ÎÌäÂê¤ò»²¾È¤·¤ÆÍߤ·¤¤¡£ + + + + + ¥Æ¥¹¥È¤Î»î¹Ô - ¸½ºß(Î㤨¤Ð¿¼Ìë¤Ê¤É¤Ç)ÅÅÏäò¤«¤±¤ëͧ¿Í¤¬¤¤¤Ê¤¤¤¬¡¢Linphone¤¬ËÜÅö¤Ëư¤¤¤Æ¤¤¤ë¤«¤É¤¦¤«ÃΤꤿ¤¤¤È¤­ + + + ¥Ð¡¼¥¸¥ç¥ó3.0¤«¤é¤Ï¡¢Linphone¤Ë¤Ï¡Ösiptomatic¡×¤È¤¤¤¦¥×¥í¥°¥é¥à¤¬ÉÕ°¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï¡¢°Ê²¼¤Î¼ê½ç¤Ç»ÈÍѤǤ­¤ë¡£ + + + + + siptomatic¤ò¥¿¡¼¥ß¥Ê¥ë¤«¤éµ¯Æ°¤¹¤ë¡£siptomatic¤Ï¥°¥é¥Õ¥£¥«¥ë¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹¤òÈ÷¤¨¤Æ¤¤¤Ê¤¤¤¬¡¢¶Ã¤«¤Ê¤¤¤ÇÍߤ·¤¤¡£Áê¸ßŪ¤Ê¤ä¤ê¤È¤ê¤ò¤¹¤ëɬÍפ¬¤Ê¤¤¤«¤é¤Ç¤¢¤ë¡£ + + + + + Linphone¤Î¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Î¥¿¥Ö¤«¤é¡¢¡Ölo¡×¤ò¥Ç¥Õ¥©¥ë¥È¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ë·èÄꤷ¡¢Êѹ¹¤òOK¤ò¥¯¥ê¥Ã¥¯¤·¤ÆÅ¬ÍѤ¹¤ë¡£ + + + + + ¡Ösip:robot@127.0.0.1:5064¡×¤È¤¤¤¦SIP URL¤ò¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤ËÆþÎϤ¹¤ë¡£127.0.0.1¤Ï¡¢¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤Î ¥í¡¼¥«¥ë¥¢¥É¥ì¥¹¤Ç¡¢robot¤Ïsipomatic¤ËÅÅÏäò¤«¤±¤ëºÝ¤Î̾Á°¤Ç¤¢¤ë¡£5064¥Ý¡¼¥È¤¬¡¢sipomatic¤ËÀܳ²Äǽ¤Ê¥Ý¡¼¥È¤Ç¤¢¤ë¡£Ä̾ï¤ÏÅÅÏäò¤«¤±¤ë¤Î¤Ë5060È֥ݡ¼¥È¤òÍѤ¤¤ë¤¬¡¢sipomatic¤ÏÎã³°¤Ç5064È֥ݡ¼¥È¤Çµ¯Æ°¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï¡¢Linphone¤¬¤¹¤Ç¤Ë5060È֥ݡ¼¥È(¤¹¤Ê¤ï¤Á¡¢¥Ý¡¼¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¥Ç¥Õ¥©¥ë¥È¤Î¥Ý¡¼¥È¤È¤·¤Æ)¤Çµ¯Æ°¤·¤Æ¤¤¤ë¤«¤é¤Ç¤¢¤ê¡¢Æ±¤¸¥Ý¡¼¥È¤ò»È¤¦2¤Ä¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òƱ»þ¤ËƱ¤¸¥³¥ó¥Ô¥å¡¼¥¿¡¼¤Çµ¯Æ°¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤«¤é¤Ç¤¢¤ë¡£ + + + + + ¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë¤È¡¢¿ôÉøå¤Ësiptomatic¤¬¤¢¤Ê¤¿¤ÎÅÅÏäËÊÖÅú¤·¡¢Ã»¤¤¥¢¥Ê¥¦¥ó¥¹¤¬Ê¹¤³¤¨¤ë¤À¤í¤¦¡£ + + + + + + + + ÅÅÏäΥѥé¥á¡¼¥¿¡¼ + + + + ¥Í¥Ã¥È¥ï¡¼¥¯ + + + + + ¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î¥ê¥¹¥È - ¤¢¤Ê¤¿¤Ï¡¢Linphone¤Ë»È¤¦¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ÖɬÍפ¬¤¢¤ë¡£¤â¤·¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥È¾å¤Î狼¤ËÏ¢Íí¤ò¤·¤¿¤¤¤Î¤Ê¤é¡¢¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤¬¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤Ö¤Ù¤­¤Ç¤¢¤ë¡£²¿¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤â¤Ä¤Ê¤¬¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¡Ölo¡×¤È¸Æ¤Ð¤ì¤ë¥í¡¼¥«¥ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤À¤±¤¬¥ê¥¹¥È¤Ë¸½¤ì¤ë¤À¤í¤¦¡£¤½¤ì¤Ï¡¢siptomatic¤ËÅÅÏäò¤¹¤ë¤³¤È¤À¤±¤¬¤Ç¤­¤ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ç¤¢¤ë¡£ + + + + + Àܳ¤Î¥¿¥¤¥× - »È¤¤¤¿¤¤¥Í¥Ã¥È¥ï¡¼¥¯¤Ø¤ÎÀܳ¤ÎÊýË¡¤òÁªÂò¤¹¤ë(ÂçÄñ¤Î¾ì¹ç¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ç¤¢¤ë)¡£¤³¤ì¤Ï¡¢Linphone¤¬¤¢¤Ê¤¿¤ÎÂÓ°è¤òÀßÄꤹ¤ë¤Î¤òÊä½õ¤¹¤ë¤¿¤á¤Ç¤¢¤ë¡£ + + + + + + + RTP + + + RTP(Real Time Protocol)¤Ï¡¢¥á¥Ç¥£¥¢¥¹¥È¥ê¡¼¥à¤ò¥Í¥Ã¥È¥ï¡¼¥¯±Û¤·¤ËÁ÷¿®¤¹¤ëºÝ¤ËÍѤ¤¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£ + + + + + RTP¥Ý¡¼¥È - Linphone¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç²»À¼¥Ç¡¼¥¿¤ÎÁ÷¼õ¿®¤Ë7000È֥ݡ¼¥È¤òÍøÍѤ¹¤ë¡£7000È֥ݡ¼¥È¤¬Â¾¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë»È¤ï¤ì¤Æ¤¤¤ë¤È»×¤ï¤ì¤ë¾ì¹ç¤Ë¤Ï¡¢Ç¤°Õ¤Î¥Ý¡¼¥È¤ËÊѹ¹¤¹¤ë¡£ + + + + + ¥Ð¥Ã¥Õ¥¡¤¹¤ë¥ß¥êÉà - ¤³¤Î¿ô»ú¤Ï¡¢Linphone¤¬ºÆÀ¸¤òÂÔµ¡¤¹¤ë²»À¼¥Ñ¥±¥Ã¥È¤Î¿ô¤òɽ¤·¤Æ¤¤¤ë¡£²»À¼¥Ñ¥±¥Ã¥È¤¬Á÷¤ì¤¬¤Á¤Ê¾ì¹ç¤Ë¡¢ºÆÀ¸¤µ¤ì¤º¤ËÇË´þ¤µ¤ì¤ë²»À¼¥Ñ¥±¥Ã¥È¤ò¸º¤é¤¹¤³¤È¤¬¤Ç¤­¤ë¡£¡ÖÅÓÀÚ¤ìÅÓÀڤ첻¡×¤¬Ê¹¤³¤¨¤ë¾ì¹ç¡¢¤³¤ÎÃͤòÂ礭¤¯¤¹¤ë¤ÈÅÁÁ÷¤Î¸úΨ¤ò¾å¤²¤ë¤³¤È¤¬¤Ç¤­¤ë¤¬¡¢²»À¼¤ÎÃٱ䤬Â礭¤¯¤Ê¤ë(Áê¼ê¤ÎÀ¼¤¬¾¯¤·ÃÙ¤ì¤ÆÊ¹¤³¤¨¤ë)¡£¤æ¤¨¤Ë¡¢¥Í¥Ã¥È¥ï¡¼¥¯¤¬´°Á´¤Ç¹âÉʼÁ¤Î¥ª¡¼¥Ç¥£¥ª¥É¥é¥¤¥Ð¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤ÎÃͤò3¥Ñ¥±¥Ã¥È¤Ë²¼¤²¤ì¤Ðû¤¤ÃÙ±ä»þ´Ö¤ÇÏ令ë¤è¤¦¤Ë¤Ê¤ë¡£ + + + + + + + SIP + + + SIP(Session Initiation Protocol)¤Ï¡¢¥Í¥Ã¥È¥ï¡¼¥¯±Û¤·¤Ë¥á¥Ç¥£¥¢¤Î¥»¥Ã¥·¥ç¥ó¤ò³ÎΩ¤¹¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£¤Ä¤Þ¤ê¤Ï¡¢¥ê¥â¡¼¥È¥æ¡¼¥¶¡¼´Ö¤Î²ñÏäò³«»Ï¤·¤¿¤ê¡¢ÊÒÊý¤¬ÅÅÏäòÀڤ俤Ȥ­¤Ë²ñÏäò½ªÎ»¤·¤¿¤ê¤¹¤ë¥×¥í¥È¥³¥ë¤Ç¤¢¤ë¡£ + + + + + SIP¥Ý¡¼¥È - Linphone¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ÇSIP¥Ñ¥±¥Ã¥È¤ÎÁ÷¼õ¿®¤Ë5060È֥ݡ¼¥È¤òÍѤ¤¤ë¡£SIP¤Î¥Ý¡¼¥È¤Ï¡¢RFC¤Ë5060ÈÖ¤òÍѤ¤¤ë¤³¤È¤¬¶¯¤¯¿ä¾©¤µ¤ì¤Æ¤¤¤ë¡£¤è¤Ã¤Æ¡¢²¿¤ò¤·¤¿¤¤¤Î¤«¤òÌÀ³Î¤ËÍý²ò¤·¤Æ¤¤¤ë¤È¤­¤ò½ü¤¤¤Æ¤Ï¡¢¤³¤ì¤òÊѹ¹¤¹¤Ù¤­¤Ç¤Ï¤Ê¤¤¡£ + + + + + SIP¤ÎÅÐÏ¿¤Ë¤¹¤ë - ¥ê¥â¡¼¥È¤ÎSIP¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤·¤¿¤¤¤È¤­¤Ë¤Ï¡¢¤³¤Î¥Ü¥¿¥ó¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£SIP¥µ¡¼¥Ð¡¼¤Î¥µ¡¼¥Ó¥¹¤Ë¤Ï¡¢Å¾Á÷¤ä¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤¬¤¢¤ë¡£¾Ü¤·¤¯¤Ï¡¢¡Ö¥ê¥â¡¼¥È¤Î¥µ¡¼¥Ð¡¼¤ËÀܳ¤¹¤ë¡×¤ÎÀá¤ò»²¾È¤µ¤ì¤¿¤¤¡£ + + + + + + + ¥³¡¼¥Ç¥Ã¥¯ + + + ¥³¡¼¥Ç¥Ã¥¯¤È¤Ï¡¢ÆÃ¤Ë²»À¼¥Ç¡¼¥¿¤Î°µ½Ì¤Î¤¿¤á¤ËÀ߷פµ¤ì¤¿¥¢¥ë¥´¥ê¥º¥à¤Î¤³¤È¤ò¸À¤¦¡£Î㤨¤Ð¡¢16bit/8000Hz¤Î¥Ç¥¸¥¿¥ë²½¤µ¤ì¤¿²»À¼¤È¸À¤¨¤Ð¡¢128kbit/ÉäΥǡ¼¥¿¤Îή¤ì¤òɽ¤·¤Æ¤¤¤ë¡£GSM¥Ü¥³¡¼¥À¡¼¤ò»ÈÍѤ¹¤ë¤È¡¢¤³¤ì¤Ï13bit kbit/Éä˽̾®¤µ¤ì¤ë¡£ + + + + + ¥³¡¼¥Ç¥Ã¥¯¤ÎÁªÂò - Linphone¤Ï¿ô¼ïÎà¤Î¥³¡¼¥Ç¥Ã¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£ ¥³¡¼¥Ç¥Ã¥¯¤Î¥ê¥¹¥È¤Î²¼Éô¤Ë¤¢¤ë¥Ü¥¿¥ó¤ò»È¤¦¤È¡¢»È¤¤¤¿¤¤½çÈÖ¤Ëʤ٤뤳¤È¤¬¤Ç¤­¤ë¡£¤À¤¬¡¢¥Í¥Ã¥È¥ï¡¼¥¯Àܳ¤Î¥¿¥¤¥×¤Ë¤è¤Ã¤Æ¤Ï(¥Í¥Ã¥È¥ï¡¼¥¯¤ÎÀá¤ò»²¾È)¡¢»È¤¨¤Ê¤¤¥³¡¼¥Ç¥Ã¥¯¤Î¼ïÎà¤â¡¢»ÈÍѤ¹¤ë¤«¤É¤¦¤«¤ò·èÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ + + + + + + + ¥ª¡¼¥Ç¥£¥ª¥Ñ¥é¥á¡¼¥¿¡¼ + + + ¤³¤ÎÀá¤Ç¤Ï¡¢²»À¼µ»½Ñ¤Ë´Ø¤¹¤ë¥Ñ¥é¥á¡¼¥¿¡¼¤ò²òÀ⤹¤ë¡£ + + + + + ¥É¥é¥¤¥Ð¤ÎÁªÂò - Linux¤Ç¤Ï¡¢OSS(¥«¡¼¥Í¥ë¥É¥é¥¤¥Ð¡¼¤È¤â¸Æ¤Ð¤ì¤ë)¤ÈALSA¤È¡¢°Û¤Ê¤ë2¼ïÎà¤Î¥µ¥¦¥ó¥É¥«¡¼¥É¥é¥¤¥Ð¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤¬¡¢ALSA¥É¥é¥¤¥Ð¤ÏALSA¥é¥¤¥Ö¥é¥ê¤òÄ̤¹¤³¤È¤Ç¡¢¤µ¤é¤Ê ¤ë¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤òȯ´ø¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢ALSA¥É¥é¥¤¥Ð¡¼(snd_*¤Ç»Ï¤Þ¤ë̾Á°¤Ç¤¢¤ë)¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ALSA¥â¡¼¥É¤òÁªÂò¤¹¤ë¤Î¤¬¤è¤¤¡£Ê¬¤«¤é¤Ê¤±¤ì¤Ð¡¢OSS¤òÁªÂò¤¹¤ë¡£ + + + + + Auto-kill¥ª¥×¥·¥ç¥ó - ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¦¤È¡¢linphone¤Ï¥µ¥¦¥ó¥É¥Ç¡¼¥â¥ó(esd¤Èartsd)¤òÄä»ß¤·¤è¤¦¤È¤¹¤ë¡£¤³¤ì¤Ï¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤Ë¹±µ×Ū¤Ê¼è¤ê³°¤»¤Ê¤¤¥í¥Ã¥¯¤ò¤«¤±¤Æ¤·¤Þ¤¤¡¢Linphone¤¬É¬ÍפȤ·¤Æ¤¤¤ë¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò¥ª¡¼¥×¥ó¤µ¤»¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥ª¥ó¤Ë¤·¤Æ¤ª¤¯¤³¤È¤ò¿ä¾©¤¹¤ë¡£ + + + + + + + + ÅÅÏÃÄ¢ + + + ÅÅÏÃÄ¢(conection¤Î¥á¥Ë¥å¡¼¤ÎÃæ¤Ë¤¢¤ë)¤ò»È¤¦¤È¡¢SIP¥¢¥É¥ì¥¹¤òµ­²±¤È¸Æ½Ð¤·¤¬¤Ç¤­¤ë¡£SIP¥¢¥É¥ì¥¹¤Ï¡¢sip:¥æ¡¼¥¶¡¼Ì¾@¥É¥á¥¤¥ó̾¤Î·Á¼°¤Ç¤¢¤ë¡£¤Þ¤¿¡¢¼«Ê¬¤¬Ê¬¤«¤ê¤ä¤¹¤¯¤¹¤ë¤¿¤á¤Ë¡¢É½¼¨¤µ¤ì¤ë̾Á°¤òÄɲ乤뤳¤È¤â¤Ç¤­¤ë¡£SIP¥¢¥É¥ì¥¹¤ò¸Æ¤Ó½Ð¤¹¤Ë¤Ï¡¢¥¢¥É¥ì¥¹¤Î¥ê¥¹¥È¤«¤éÁªÂò¤·¡¢¡ÖOK¡×¤Î¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤¹¤ë¡£¤¹¤ë¤È¡¢ÁªÂò¤·¤¿¥¢¥É¥ì¥¹¤¬¥á¥¤¥ó¥¦¥¤¥ó¥É¥¦¤Ë¸½¤ì¤ë¤Î¤¬³Îǧ¤Ç¤­¤ë¤À¤í¤¦¡£¸å¤Ï¡¢ÅÅÏäò¤«¤±¤ë¤¿¤á¤Ë¡ÖÅÅÏäò¤«¤±¤ë¡×¤Î¥Ü¥¿¥ó¤ò²¡¤»¤Ð¤è¤¤¤À¤±¤Ç¤¢¤ë¡£ + + + + + SIP¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤ë + + + ¥ê¥â¡¼¥È¤ÎSIP¥µ¡¼¥Ð¡¼¤Î¥µ¡¼¥Ó¥¹¤ËÅÐÏ¿¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¢¤ë¡£¤³¤Î¤è¤¦¤Ê¥µ¡¼¥Ó¥¹¤Ë¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤¬¤¢¤ë¡£ + + + + + žÁ÷ - Linphon¤Ï¡¢¥µ¡¼¥Ð¡¼¤Ë<sip:example_registrar.com>¤Î¤è¤¦¤ÊSIP¥¢¥«¥¦¥ó¥È¤òºîÀ®¤¹¤ë¤è¤¦Í×ÀÁ¤¹¤ë¡£Î㤨¤Ð¡¢56k¤Î¥â¥Ç¥à¤ò»È¤Ã¤ÆÃ±½ã¤Ë¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ËÀܳ¤·¤Æ¤¤¤ë¾ì¹ç¡¢¤¢¤Ê¤¿¤ÎIP¥¢¥É¥ì¥¹¤ÏÀÅŪ¤Ç¤Ï¤Ê¤¯¡¢¥Í¡¼¥à¥µ¡¼¥Ð¡¼¤ËÃΤé¤ì¤Æ¤¤¤ë¥Û¥¹¥È̾¤â»ý¤Ã¤Æ¤¤¤Ê¤¤¡£¤³¤ì¤Ç¤Ï¡¢Í§Ã£¤Ï¤¢¤Ê¤¿¤¬IP¥¢¥É¥ì¥¹¤òÄÌÃΤ¹¤ë¥á¡¼¥ë¤òÁ÷¤é¤Ê¤¤¸Â¤ê¡¢¤¢¤Ê¤¿¤ËÏ¢Íí¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¡£Îã¤È¤·¤Æ¡¢<sip:example_registrar.com>¤ËÅÐÏ¿¤ò¹Ô¤¦¤Î¤Ï´Êñ¤Ç¤¢¤ë¡£¤¢¤Ê¤¿¤Î¥æ¡¼¥¶¡¼Ì¾¤Ï¡Öbob¡×¤À¤È¤¹¤ë¡£¥µ¡¼¥Ð¡¼¤ËÅÐÏ¿¤¹¤ëºÝ¤Ë¡¢Linphone¤Ï¤¢¤Ê¤¿¤ÎIP¥¢¥É¥ì¥¹¤ò¥µ¡¼¥Ð¡¼¤ËÁ÷¿®¤·¡¢¥¢¥«¥¦¥ó¥È¡Ösip:bob@example_registrar.com¡×¤¬ºîÀ®¤µ¤ì¤ë¡£¤½¤¦¤¹¤ë¤È¡¢¤¢¤Ê¤¿¤Îͧã¤Î¥¸¥à¤Ï¡¢<sip:bob@example_registrar.com>¤È¤¤¤¦¥¢¥É¥ì¥¹¤ËÅÅÏäò¤«¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ÅöÁ³¤Î¤³¤È¤Ê¤¬¤é¡¢“example_registar.com”¤Ï¡¢¥¦¥§¥ë¥Î¥ó¡¦¥É¥á¥¤¥ó¥Í¡¼¥à¤Ç¤¢¤ë¡£¼¡¤Ë¡¢¥¸¥à¤ÎLinphone¤Ï¥Ü¥Ö¤Î³Î¼Â¤Ê¥í¥±¡¼¥·¥ç¥ó¤ò¼¨¤¹Å¾Á÷¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤ë¡£¤½¤¦¤·¤Æ¡¢¥Ü¥Ö¤Î²È¤Ç¥Ù¥ë¤¬ÌĤë¤Î¤Ç¤¢¤ë¡£ + + + + + ¥×¥í¥¯¥· - ¤³¤ì¤â¡¢Å¾Á÷¥á¥Ã¥»¡¼¥¸¤¬¥¸¥à¤ÎÅÅÏäËÁ÷¿®¤µ¤ì¤Ê¤¤¤³¤È¤ò¤Î¤¾¤±¤Ð¡¢Æ±Íͤθ¶Íý¤Ç¤¢¤ë¡£¤½¤ÎÂå¤ï¤ê¤Ë¡¢¥×¥í¥¯¥·¤Ï¥Ü¥Ö¤ÎLinphone¤Þ¤Ç¥À¥¤¥ì¥¯¥È¤ÊžÁ÷¤ò¹Ô¤¦¡£ + + + + + ¤³¤Î¤è¤¦¤ÊÅÐÏ¿¤Ï¡¢¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤Ë¤ª¤¤¤Æ¤âƱÍͤ˹Ԥï¤ì¤ë¡£¤³¤ì¤Ï¡¢Linphone¤ò¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÃæ¤Ç»È¤¦¤È¤­¤ËÍ­¸ú¤Ç¤¢¤ë¡£¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤Ï¡¢¥×¥é¥¤¥Ù¡¼¥È¥µ¥Ö¥Í¥Ã¥È¤Ë¤¢¤ëHTTP¥×¥í¥¯¥·¤ÈƱÍͤÎÌò³ä¤ò²Ì¤¿¤¹¡£³°Éô¤Ø¤Î²ñÏäϥ¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤¬°·¤¤¡¢¥Í¥Ã¥È¥ï¡¼¥¯³°¤Ë¤¤¤ë¤È»×¤ï¤ì¤ë¿Í¤Ø¤Î²ñÏäΞÁ÷¤ÎǤ¤òÉ餦¡£ + + + ÅÐÏ¿¥µ¡¼¥Ð¡¼¤òLinphone¤Ç»È¤¦¤Ë¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤éSIP¤Î¥¿¥Ö¤òÁªÂò¤·¡¢¡ÖSIP¥¢¥É¥ì¥¹¤òÅÐÏ¿¤¹¤ë¡×¤Î¥Ü¥Ã¥¯¥¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ÅÐÏ¿¤¹¤ë¥¢¥É¥ì¥¹¤òŬÀڤʥե£¡¼¥ë¥É¤ËÆþÎϤ·¤¿¤é¡¢¼¡¤Ë¡¢Å¾Á÷¤«¥×¥í¥¯¥·¤«¡¢Âбþ¤¹¤ë¥Ü¥Ã¥¯¥¹¤ò¥Á¥§¥Ã¥¯¤·¡¢ÅÐÏ¿¤òÍ׵᤹¤ë¥µ¡¼¥Ó¥¹¤Î¥¿¥¤¥×¤òÁªÂò¤¹¤ë¡£¤Þ¤¿¡¢³°Éô¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ø²ñÏäòÆ©²á¤µ¤»¤ë¤¿¤á¤ÎÅÐÏ¿¥µ¡¼¥Ð¡¼¤¬É¬ÍפʤȤ­¤Ë¤Ï¡¢¡Ö¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤È¤·¤Æ»È¤¦¡×¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ + + + ºÇ¸å¤Ë¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎOK¥Ü¥¿¥ó¤ò²¡¤¹¤È¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÏÊĤ¸¤é¤ì¡¢¤¿¤À¤Á¤ËÅÐÏ¿¥µ¡¼¥Ð¡¼¤Ë¤¢¤Ê¤¿¤ÎÀµ³Î¤Ê¾ì½ê¤òÃΤ餻¤ë¤¿¤á¤Î¸ò¾Ä¤¬»Ï¤Þ¤ë¡£Linphone¤ò¥·¥ã¥Ã¥È¥À¥¦¥ó¤¹¤ë¤È¤­¤Ë¤Ï¡¢ÅÐÏ¿¥µ¡¼¥Ð¡¼¤«¤é¤¢¤Ê¤¿¤Î¾ì½ê¤ÎÅÐÏ¿¤ò²ò½ü¤¹¤ë¤¿¤á¡¢¿ôÉô֤«¤«¤ë¡£ + + + ¥Ñ¥Ö¥ê¥Ã¥¯¤ÊÅÐÏ¿¥µ¡¼¥Ð¡¼¤Î¥ê¥¹¥È¤Ï¡¢°Ê²¼¤Ë·ÇºÜ¤µ¤ì¤Æ¤¤¤ë¡£http://www.cs.columbia.edu/~hgs/sip/servers.html + + + ¤À¤¬¡¢»Äǰ¤Ê¤³¤È¤Ë¡¢¤³¤ì¤é¤Î¥µ¡¼¥Ð¡¼¤Î¿¤¯¤Ï¤â¤¦Æ°¤¤¤Æ¤¤¤Ê¤¤¡£¤ª¤½¤é¤¯¡¢¶áº¢¤ÎÅŵ¤ÄÌ¿®¶È³¦¤Î´íµ¡¤Ë¤è¤ë¤â¤Î¤Ç¤¢¤í¤¦¡£Â¾¤ÎɬÍפȤµ¤ì¤ëǧ¾ÚÊýË¡¤Ï¡¢¸½ºßLinphone¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¡£ + + + ̵ÍѤʼê´Ö¤òÈò¤±¤¿¤¤¤È¤­¤Ë¤Ï¡¢»ÈÍѲÄǽ¤Êưºî¤·¤Æ¤¤¤ë¥Ñ¥Ö¥ê¥Ã¥¯¤ÊSIP¥µ¡¼¥Ð¡¼¤Î¥ê¥¹¥È¤¬¡¢Linphoe¤Î°ÊÁ°¤ÎWEB¥µ¥¤¥È¤Î¥ê¥¹¥È¤¬http://simon.morlat.free.fr/english/servers.html¤Ç»²¾È¤Ç¤­¤ë¡£ + + + + + ¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÆâ¦¤Ç + + + ¸½ºß¤Ç¤Ï¡¢SIP¥×¥í¥¯¥·¤òÍѤ¤¤ë¤³¤È¤Ç¡¢Linphone¤Ï¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤ÎÆâ¦¤ÇÍøÍѲÄǽ¤Ç¤¢¤ë¡£SIP¥µ¡¼¥Ð¡¼¤Ï¡¢¥×¥é¥¤¥Ù¡¼¥È¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î²ñÏäò³°Éô¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤ØÅ¾Á÷¤¹¤ëǤ¤òÉ餦¡£oSIP¥é¥¤¥Ö¥é¥ê¤òÍøÍѤ·¤¿SIP¥×¥í¥¯¥·¤Ï¡¢http://osipproxy.sourceforge.net¤Ç³«È¯¤µ¤ì¤Æ¤¤¤ë¡£ + + + SIP¤ÎÀá¤Î¡¢¡ÖSIP¤ËÅÐÏ¿¤¹¤ë¡×¤Î¹àÌܤò»²¹Í¤Ë¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÇÍѤ¤¤ëSIP¥×¥í¥¯¥·¤ò»ØÄꤷ¤ÆÍߤ·¤¤¡£ÀßÄꤹ¤ë¤Ë¤Ï¡¢SIP¥×¥í¥¯¥·¤Î¥¢¥É¥ì¥¹¤òÆþÎϤ·¡¢¡Ö¥¢¥¦¥È¥Ð¥¦¥ó¥É¥×¥í¥¯¥·¤È¤·¤ÆÅÐÏ¿¤¹¤ë¡×¤Î¥Ü¥¿¥ó¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£ + + + ¤Ê¤ª¡¢SIP¥×¥í¥¯¥·¤¬É¬Íפʤ¤¾ì¹ç¤â¤¢¤ë¡£¥Ñ¥Ö¥ê¥Ã¥¯¥¢¥É¥ì¥¹¤ò»ý¤Ã¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯²¼¤Ë¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¡¼¤¬¤¢¤ê¡¢¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤Ï³°Éô¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î¥Ñ¥±¥Ã¥È¤ÎÁ÷¼õ¿®¤ò¥Õ¥£¥ë¥¿¡¼¤¹¤ë¤À¤±¤Î¾ì¹ç¤Ç¤¢¤ë¡£¤³¤Î¾ì¹ç¤Ë¤Ï¡¢¥Õ¥¡¥¤¥ä¡¼¥¦¥©¡¼¥ë¤Î¥Þ¥·¥ó¤ÎSIP¤ÈRTP¤Î¥Ý¡¼¥È¤ò¥ª¡¼¥×¥ó¤¹¤ë¤À¤±¤Ç¤è¤¤¡£SIP¥Ý¡¼¥È¤Ï¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎSIP¤Î¥¿¥Ö¤Ë¡¢RTP¥Ý¡¼¥È¤Ï¡¢RTP¥Ý¡¼¥È¤ÏRTP¤Î¥¿¥Ö¤Ë¤¢¤ë¡£Î¾¼Ô¤È¤â¤ËÊѹ¹²Äǽ¤Ç¤¢¤ë¤¬¡¢SIP¥Ý¡¼¥È(5060ÈÖ)¤Ï¡¢Êѹ¹¤·¤Ê¤¤¤Ç¤ª¤¯¤³¤È¤¬¶¯¤¯¿ä¾©¤µ¤ì¤ë¡£ + + + + + º¤¤Ã¤¿¤È¤­¤Ë¤Ï + + + + Àܳ¾å¤Ë¤ª¤±¤ëÌäÂê + +
+ + »ä¤Ï¡¢Í§¿Í<sip:toto@example.com>¤ËÅÅÏäò¤«¤±¤è¤¦¤È¤·¤¿¤À¤¬¡¢¤Ê¤Ë¤âµ¯¤­¤Ê¤¤¡£¥Ù¥ë¤âÌĤé¤Ê¤¤¡¢¤Þ¤Ã¤¿¤¯²¿¤âµ¯¤³¤é¤Ê¤¤¡£ + +
+ + Linphone¤¬»ÈÍѤ·¤Æ¤¤¤ë¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ØÀܳ¤·¤Æ¤¤¤ë¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹(¤Þ¤¿¤Ï¡¢²ñÏ䬽ФƤ¤¤¯¤Ù¤­¥Í¥Ã¥È¥ï¡¼¥¯)¤ò¸¡¾Ú¤·¤Æ¤ß¤ë¤Ù¤­¤Ç¤¢¤í¤¦¡£¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤Î¡¢¥Í¥Ã¥È¥ï¡¼¥¯¥¿¥Ö¤«¤é¡¢Àµ¤·¤¤¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ó¤Ç¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ + + + ¤¢¤ë¤¤¤Ï¡¢¤¢¤Ê¤¿¤¬Àܳ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¿Í¤¬¡¢¸½ºß·ÐÏ©¤¬Àܳ¤Ç¤­¤Ê¤¤¾õ¶·¤Ë¤¢¤ë¤Î¤«¤âÃΤì¤Ê¤¤¡Ä¡Ä¡£ + +
+ + + ²»À¼¤Ë¤ª¤±¤ëÌäÂê + +
+ + Linphone¤Ï¡¢¥ê¥â¡¼¥È¤ÎSIP URL¤ËÀܳ¤·¤Æ¤¤¤ë¤è¤¦¤Ç¡¢¥Ù¥ë¤ÏÌĤäƤ¤¤ë¤è¤¦¤À¡£¤±¤ì¤É¤â¡¢Áê¼ê¤¬ÅÅÏä˽Ф¿¤È¤­¤Ë¤Ï²¿¤âµ¯¤³¤é¤º¡¢¤ª¸ß¤¤¤ÎÀ¼¤¬Ê¹¤³¤¨¤Ê¤¤¡£ + +
+ + + + ÂçÄñ¤Î¿Í¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤é¡¢Àµ¤·¤¤¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÁª¤ó¤Ç¤¤¤Ê¤¤¤¿¤á¤Ë¡¢ÌäÂê¤òÀ¸¤¸¤µ¤»¤Æ¤·¤Þ¤¦¡£¥À¥¤¥ä¥ë¥¢¥Ã¥×Àܳ¤Ç¤Ï¡¢¡Öppp0¡×¤Ë¤Ê¤ë¤Ï¤º¤Ç¤¢¤ë¡£¡Ö\"{}lo¡×¤Ï¡¢¥Æ¥¹¥ÈÍѤˡ¢sipomatic¤À¤±¤Ë»ÈÍѤµ¤ì¤ë¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤µ¤ì¤¿¤¤¡£¤½¤Î¾¤Î¾ì¹ç¤Ç¤Ï µ¡Ç½¤·¤Ê¤¤¡£ + + + + + ¤Þ¤º¤Ï¡¢Á÷Ïò»Î̤ȼõÏò»Î̤ò¾å¤²¤Æ¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ + + + + + ²»À¼¤¬¤È¤®¤ì¤È¤®¤ì¤Ë¤Ê¤ë¾ì¹ç¤Ï¡¢¤³¤ì¤ò²óÈò¤¹¤ë¤¿¤á¤Ë¡¢¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤ÎRTP¥¿¥Ö¤Î¡Ö¥Ð¥Ã¥Õ¥¡¤¹¤ë¥ß¥êÉáפÎÃͤòÂ礭¤¯¤·¤Æ¤ß¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£¤·¤«¤·¡¢¤³¤ì¤ÏÄÌ¿®¤ÎÃÙ±ä¤òÁýÂ礵¤»¤ë¡£ + + + + + Linphone¤¬¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Ê¤¤¤È¤­¤Ë¤Ï¡¢/dev/dsp¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ò³Îǧ¤·¡¢¥ª¡¼¥Ç¥£¥ª¥Ç¥Ð¥¤¥¹¤ò»ÈÍѤ¹¤ë¤¹¤Ù¤Æ¤Î¥×¥í¥°¥é¥à(xmms kaimanÅù)¤òÄä»ß¤¹¤ë¤Î¤¬¤è¤¤¤À¤í¤¦¡£ + + + + + ALSA¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ¹¤ë(http://www.alsa-project.org¤ò»²¾È¤µ¤ì¤¿¤¤)¡£ÂçÄñ¤Î¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥¸¥ç¥ó¤Ï¡¢¤Þ¤À¸Å¤¤¥«¡¼¥Í¥ë¸øÇ§¤Î¥É¥é¥¤¥Ð¡¼¤ò»ÈÍѤ·¤Æ¤¤¤ë¤¬¡¢¤³¤ì¤ÏÂ礭¤ÊÃÙ±ä¤È¿¤¯¤Î¥Ð¥°¤ò´Þ¤ó¤Ç¤¤¤ë¡£Linphone¤Ï¡¢ALSA¥É¥é¥¤¥Ð¡¼¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤¿¸å¤Î¥ê¥³¥ó¥Ñ¥¤¥ë¤òɬÍפȤ·¤Ê¤¤¤³¤È¡¢¤Þ¤¿¡¢¥ª¡¼¥Ç¥£¥ª¤ÎÀá¤Î¥×¥í¥Ñ¥Æ¥£¡¼¥Ü¥Ã¥¯¥¹¤«¤é¤ÎALSA¥â¡¼¥É¤Ø¤ÎÊѹ¹¤Ïɬ¿Ü¤Ç¤Ï¤Ê¤¤¤³¤È¤â½Ò¤Ù¤Æ¤ª¤³¤¦¡£ + + + +
+
+ + + ¥Ð¥°Êó¹ð¤ÈÄó°Æ + + + ¤Þ¤º¤Ï¡¢Linphone¤Î¥Û¡¼¥à¥Ú¡¼¥¸http://www.linphone.org¤«¤é¡¢ºÇ¿·¤ÎLinphone¤ò»ÈÍѤ·¤Æ¤¤¤ë¤«¤ò³Îǧ¤·¤ÆÍߤ·¤¤¡£ + + + ¤â¤·¡¢Linphone¤¬¥¯¥é¥Ã¥·¥å¤·¤¿¤È¤­¤Ë¤Ï¡¢¥Ð¥°¥ì¥Ý¡¼¥È¤òľÀÜbugs@linphone.org¤Þ¤ÇÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤â¤·¡¢¥¯¥é¥Ã¥·¥å¤Ï¤·¤Ê¤¤¤¬Linphone¤¬Æ°ºî¤·¤Ê¤¤¤È¤­¤Ë¤Ï¡¢¾å¤Î¥¢¥É¥ì¥¹¤Ë¥Ð¥°¥ì¥Ý¡¼¥È¤òÁ÷¤ëÁ°¤Ë¡¢¥Þ¥Ë¥å¥¢¥ë¤ò ¤â¤¦°ìÅÙÆÉ¤ß¤«¤¨¤·¤ÆÍߤ·¤¤¡£¤â¤·¡¢²¿¤«¤òÄ󰯤·¤¿¤¤¤È¤­¤Ë¤Ï¡¢±ó褻¤º¤Ë¡¢help@linphone.org¤Þ¤Ç¥á¡¼¥ë¤òÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤Ê¤ª¡¢¥Ó¥Ç¥ª¥µ¥Ý¡¼¥È¤È²ñµÄ¤Ï¡¢¾­Íè¤Î·×²è¤Ë¤¢¤ë¤³¤È¤ò½Ò¤Ù¤Æ¤ª¤³¤¦¡£¤Þ¤¿¡¢Linphonr¤ÎËÝÌõ¤Ë¶½Ì£¤ò»ý¤Ã¤¿¿Í¤Ï¡¢ÇÛÉÛ¤µ¤ì¤Æ¤¤¤ëpo/linpyhone.pot¤Ë´ð¤Å¤¤¤¿xx.po¥Õ¥¡¥¤¥ë¤ò»ä¤ËÁ÷¤Ã¤ÆÍߤ·¤¤¡£¤Þ¤¿¡¢¤³¤Î¥Þ¥Ë¥å¥¢¥ë¤ò¾¤Î¸À¸ì¤ËËÝÌõ¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¢¤ë¡£¤¤¤º¤ì¤Ë¤·¤Æ¤â¡¢¾Ü¤·¤¤¤³¤È¤¬ÃΤꤿ¤¤¤È¤­¤Ï»ä¤ËÏ¢Íí¤·¤ÆÍߤ·¤¤¡£ + + + + + ºî¼Ô + + + Simon MORLAT (simon.morlat@free.fr) ¤¬À½ºî¤·¤¿Éôʬ¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£ + + + + + ¥á¥¤¥ó¥×¥í¥°¥é¥à(src) + + + + + RTP ¥é¥¤¥Ö¥é¥ê (lprtplib) + + + + + osipua -- osip¥¹¥¿¥Ã¥¯¤Ë´ð¤Å¤¤¤¿¥æ¡¼¥¶¡¼¥¨¡¼¥¸¥§¥ó¥È¤ÎAPI¡£oss¤ÈALSA¥É¥é¥¤¥Ð¡¼¤Î²»À¼¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¡£ + + + + + (²»À¼) lpc10-1.5ÍѤÎwrappers, gsm and g711 ¥³¡¼¥Ç¥Ã¥¯ + + + + + Aymeric Moizard (jack@atosc.org)¤Ï¡¢ Linphone¤¬ÍøÍѤ·¤Æ¤¤¤ëosip¥¹¥¿¥Ã¥¯¤òÀ½ºî¤·¤¿¡£ + + + GSM¥é¥¤¥Ö¥é¥ê¤Ï¡¢Jutta Degener¤ÈCarsten Bormann(Technische Universitaet Berlin)¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿¡£ + + + The LPC10-1.5 ¥é¥¤¥Ö¥é¥ê¤Ï¡¢Andy Fingerhut(Applied Research Laboratory)¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿¡£ <-- ¤³¤ÎÉôʬ¤Ï¥¹¥Ú¡¼¥¹¤ÎÅÔ¹ç¤Ë¤è¤ê¾Êά²Äǽ¤Ç¤¢¤ë¡£ Washington University, Campus Box 1045/Bryan 509 ¥¹¥Ú¡¼¥¹¤Ë¸Â¤ê¤¬¤¢¤ë¾ì¹ç¤Ï¡¢¤³¤³¤«¤é¡£One Brookings Drive Saint Louis, MO 63130-4899 jaf@arl.wustl.edu http://www.arl.wustl.edu/˜jaf/¤µ¤é¤Ê¤ë¾ðÊó¤Ï¡¢gsmlib¤Èlpc10-1.5¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò»²¾È¤µ¤ì¤¿¤¤¡£ + + + Pablo Marcelo Moia -- ¥¢¥¤¥³¥óÀ½ºî + + + + + ¼Õ¼­ + + + GTK¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¥Ó¥ë¥À¡¼¤ÎDaemon Chaplin¤Ë´¶¼Õ¤ò¡£ + + + ÃøÌÀ¤ÊoSIP¥é¥¤¥Ö¥é¥ê¡¼¤ÎAymeric Moizard¤Ë´¶¼Õ¤ò¡£ + + + LPC10-1.5¤ÈGSM¥³¡¼¥É¤Îºî¼Ô¤Ë´¶¼Õ¤ò¡£ + + + RPM¤òÄ󶡤·¤Æ¤¯¤ì¤¿¡¢Joel Barrios ( jbarrios@-NO-SPAM-linuxparatodos.com )¤Ë´¶¼Õ¤ò¡£ + + + Linphone¤ËÁÇŨ¤Ê¥¢¥¤¥³¥ó¤òÄ󶡤·¤Æ¤¯¤ì¤¿¡¢Pablo Marcelo Moia¤Ë´¶¼Õ¤ò¡£ + + + + + + + +
diff --git a/linphone/share/ja/manual/.cvsignore b/linphone/share/ja/manual/.cvsignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/linphone/share/ja/manual/.cvsignore @@ -0,0 +1 @@ +*.html diff --git a/linphone/share/linphone.desktop b/linphone/share/linphone.desktop new file mode 100644 index 000000000..09e110454 --- /dev/null +++ b/linphone/share/linphone.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=Linphone +Comment=Linphone is a web-phone +Comment[fr]=Linphone est un web-phone. +Comment[de]=Linphone ist ein web-phone. +Type=Application +Exec=linphone-3 +Icon=linphone/linphone2.png +Terminal=false +Categories=Application;Network; \ No newline at end of file diff --git a/linphone/share/linphone.gnorba b/linphone/share/linphone.gnorba new file mode 100644 index 000000000..b9e50592b --- /dev/null +++ b/linphone/share/linphone.gnorba @@ -0,0 +1,5 @@ +[linphone_applet] +type=exe +repo_id=IDL:GNOME/Applet:1.0 +description=Linphone is a web phone. +location_info=linphone --applet \ No newline at end of file diff --git a/linphone/share/linphone.pc.in b/linphone/share/linphone.pc.in new file mode 100644 index 000000000..abd76f414 --- /dev/null +++ b/linphone/share/linphone.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + + +Name: liblinphone +Description: All in one linphone libs. +Version: @VERSION@ +Libs: @LINPHONE_LIBS@ +Cflags: @LINPHONE_CFLAGS@ diff --git a/linphone/share/linphone_applet.desktop b/linphone/share/linphone_applet.desktop new file mode 100644 index 000000000..48403271d --- /dev/null +++ b/linphone/share/linphone_applet.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Linphone Applet +Comment=Linphone is a web-phone +Comment[fr]=Linphone est un web-phone. +Comment[de]=Linphone ist ein web-phone. +Type=Application +Exec=linphone --applet --activate-goad-server=linphone_applet +Icon=linphone/linphone2.png +Terminal=0 \ No newline at end of file diff --git a/linphone/share/ringback.wav b/linphone/share/ringback.wav new file mode 100644 index 0000000000000000000000000000000000000000..21f4b5bfb763e5448843e4410ce9d742227aa572 GIT binary patch literal 24620 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 literal 0 HcmV?d00001 diff --git a/linphone/share/rings/bigben.wav b/linphone/share/rings/bigben.wav new file mode 100644 index 0000000000000000000000000000000000000000..f1ba850f614c38bdb124771778732efe07c89e12 GIT binary patch literal 962604 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�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%0AkueJG;v7OOEMffBFrts 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
    _LYtUGB{vQH3*@1Dlas!Jp$ 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%0ANC9SM_P9wFV4Y~a7$xnaC@=Q)Q9v!>QQ_M zdz!)H)Df@JG~9ihH?059k;|#uxCHK4{Agqqa|t;wit!hsNMWg~yC>O&vgU*e5MAww zp4&J*u`swJQbYKO&JX3egYY5Yepab*VHgioT3WoLF*8Yzfl@*b(kMKYbR6f#oW!=n z+`$ouDTMcQDd!(}$aj_%OE_tqDeD~`YjxH9tfDBN%kI|trTx?xa|Xm7N znjXqFW&Oy{&K#HUE02)cm-mYPoj;NGp7}}encSNZN&b{&;4g^#nR_L7R>B?0u`Dul zgSo|JiK=;dlu>v*>j8y^ehM^WX8`Gu)&5rzK{(H+_x%l>4OxOnSdVaAXe+oFqxOuj zR3bAXuau4TbDjIOC(Es+jONv~SN@HL8qdF4G8BVM8bhUbpkt5S26IMX)@*BGV7Z6r zY6*F~U83y>a&`=H7h59S6dTKT@nWG&SORArmzW238d14k$MAln8&E`C zQBP=P^fh7>>@4ON%7J=Mxyaao$OzbJM=-}6#TH>?t?#;x<5v6ENBeu5-Q~bsc%?Jw zSRH8zmO2YvCH_m^3fFnpNmrKru-6?fuyu0=5fn^@C)ax%7lT81W;zd|tw^c$fVn+7 z4kxutbUek4MD%uN+XWtquC2CR6SBFgR#bBbN-)?O0}XGKoaPga8K(Kx(kfV4m2r-e z`%hb!s#vMRsJ*r+t}0kZPr3aBItCHa$0|Ty7o$Zwr}2o4)$~&4)-e<}jVo;n+)ihr zKkEA#+83&benjlVz`!!(7i6sop7w+Pn7OabQhE0y3!XLxrputmW!G#q-u_edN#1&GKqiwMl=>l>SIfImdJ{O*V zToX9&dTAEhiKaj5%`H20Ka?r8E6df=l-Zn;>zJvf4v#Q&M_OoGhplX^7uP>wW9oiaDgkh&vLl=D5Gm{^~3sm<~9FR7a) z2Su-#QO*~_NKzaDM5tjExOSNFz+32zs2YYvg^*7oCqo3V1FSXh%D*qz&3o1N&;P*L zXsZtQ0NOipJv6WtRuJ4AReIJ~ibJ{XPr7Q&bn|uH553kV*B!GY2X=;k`|d?P1S8(1 z(dWTK-qFDh{`tX)5NY};f`h99%;9$U!Kf5}3Dj@y2GK((Cac3_{-(~8XBj5xr$Qt9 zUgHbLJ=>-5+z=eo85hS$rHlB}c#mUq#k=D%l9rSm5=Fx7>>qiBNf(p0=H#T0j$6b> zCOt|Jb2_k3r@YH@@!H1ax9ODElrl1HU}iLVQ_?okv833v3o%>xj@*YGV3N2rVK+|q zz1c&u+jZWNM@*FoZ)RT0RC09O)Le4@6!GKKiMjt0E@$0Jy~xoME{e{w4uS2WeaIGE za=1gJ0lSQt7f}Y^Qw~#Cduy!SDGLc(6{qXxA&v(^6-Uaoj(L`f>deMn)}XVd>1d=$rs0P*WVvK#`w7mAegJS0cEVe540eCPetI(JfDq4L z#b(n_b564)#CWuw{e`ynEqAv3O#|)4x0FKGzSc?Ig>TE&BVhxOe04O3K$^ zAG?+%l|1_>{>J%v>eq>1f^zX6@!!(=d-AT8?dz?^Uyc@ek$$C*14~#4dDwZAn_e@t(+_OpC7*qje-b5vB> z3H?3AY>2y6D!Z&9`VYceouwf$auE0%Mp#Rr@#ToR9)h~5m*vA?ECBAh_Hj(LNCI3@LI^$@X5_EMKwAjLAzh~ z%9^7yS)TcVVXH3_vCAhicfjsLPF1uv9}M^K^iT#JSaxGVI{alb25t(iGl^JikM?02VoCv0|tS57?AsVqZXpO1Tf*<=)0(l zs2b)4#lR-uJEA!}%m;!efep6VW=?pacciV#r*JiSvcLku+VElIM7$}=gU)ZCO{tpg zzN+gXXK0SetqQg6wRg99k@sLQJyH{C2KoXR+)3~yicj0fTZ=nR4G7Qjt(=4W5KW8- zb5!_FzBjfXQNZ(`#c0DiR=Juzf@nhU4|ox=45Z?I<57rgz=QK*QOLW*^Ee}^oOdBP zk^MpRGj~Y->g4LQZyDPq*OL#$ALReXX&*}wWN}>FLP0N)fs;XBAvOuPSRk^SDZrw= zqy0leWsW?=Bhm@isL%rTV%}yXhS127vi=Z<5m;QWpex}D#1qlShpD?5^TiW*S(@(IbQk}HDyhj2RZ3M*@yEt|Rz6*GeKboEAhdUaHcaSFYA=BhY zn(vbJv8T?}=$Ql?fcO+y0ltZH{d}lbJkveQ*BpEqD2N2W`;ldk-{Cf4KlUy0BDoEn zOzlnY#G94aopnSoFRyQ>KFOlosrjsg$$7hz+EVU^`HVrZrH+WDpA(AmJ63rFu9;A_ zW`{cn!vnKz&H4_}L4kakq4BugVz}IxC|{+G(YKlhM~ZB_!mp53s7!D$Dh(8a*FYzv zab(e!fTuBASwdDa{tV$W`4f^w&|%Yqan4=nb0FV+I=mZMiCd3(NntZS3D(jVkR9>t zxLug}a8}GJ>IaB#V?+0VIh@_>ef{~+J%x(;Qg4YW_CQU(Ckm^!LCf%SV(>uiU#4aOU0TVoZ zl{)V!U0n01=3jEZyt(CYi%Z?x@Vwz#HQ&_7@Vio7U8g&4_#lnb6xzB4$+nj^J^BSs zV3a6VBVPwX(!AQ<)`04GC9{gq#Av)z^SFM5^jq^HX+}$^^^ig&kEo}r_ZU#d8@Bh> z&Q7N{4w&HC64-%zM8QP2fGUU;HxGlyhv|2ie8La>ckU5EfY6B?C!EY1O^GLCD0tKq z>=5|=2qpB?H^5OAy^Q%_Be}WE1-#7YNu-HuXW&t}@C(Ex$kl-nuDQX*u8Wpk#$*Trv4f|zs&br(VY;IW+pgO}z7f86K0Klt zndLd?Yzy{+nVbWHk3)k)A3y?WQFJmmoj#kPL|f2HAXbn9oEUvceZ#yQ9usZg*72VJ z706tHgfj*01P@XHLKk>SG#8zMcoH5RYzR;G-*ls_M$aerB!gDp=vwStXkyv&Epv1u z?M>#fsve42`eT}o^0-#IMy5Gh=l`o$cTxQMHRM;XmW54i{w2s4w9YZ+xb&!6|7q+4 z#z6j8W(@zNXl-J=aG8joL2c6_nURWXccBeE!=F-?`8T07u9W>d_Haxm%6{Aq$n1Ln zJr>i4UoE^&yhGQ;BKf1a+!%-+LAbzvN2Nn8o5lDon0+`ntpKCIFM(wDkIC(*DB|5v zD_#qKVv5R|Jn5E^O7?m-Ig&vv-zm! z0&*8Q3U^|*a1X>UBClXSPN(Iy6)#Lp&;Q+KPj+2SLjHiZ3-gxe6WTYlf7_PZ_D0(= zxkK|NXKhaHATp;661U-mS+(q$lorA8J9@ z>Kk5f!2oJ^=2VeFc!b|qjys<|-Vh__ltRp44@6H0(J+8BQ`W<8Luxg9Bj{=Nmy=Q zs%d~Hx?2?I)jQ2k3@Ik9lV-l@7!@pseehp~4FlF7+5;tU1jqrg5RZEnN<$!oypea* zVp=AmJ?b-IHmo;tTC|J#Ol!#TO-rrSRorS`Q+Kqy?jNb|uFI z0rX)>=*rMVnUpuRg~*$aSJ=fsEo2 zdfF)KRn1;@xQk|izAZ9Hd}Qh2wm|o*_Td(I8M}p91{zT(sriHo)Gb63CJl2c;tF=d zW61ME3|Ix3Oq3!1At|6YcoR_`5%~&zj$j{%^8YD32A+hW1i20delRAaHa8~1SNh^> zyEW_WJjW8_gV3G;7ULweVJ~Lyj$g)2XW5c+B&`ey+aRop5yUJKJmWQSh6`qLZ!va3 z`Q9&>O_)L$7I*{S_ zuh5rB4A158dQuMbiaZzf)>o`w4j=6WTKElXj8*c%QdLWh?7DKT{E@s|8!?nACh16) z&yI!mok6mHQ}iPI9IPI34itHg8Fs+*en;!ghEa|=rXvj%txq(hi|)QpBH-5hOC9h*o369lmbC=YHrffxV2(#{8`aDA(#I^ z)K~H>W=$+H@xG)YJ|l6xXc`ZZI5d7ZeKw^NU(L8n-NG3{I!)lm-AdX@*~_F$#_=hv zUDTJX8s=rfbX;HdXI2632W}TN4f_Hk25(1mz1&E%Z?`SkwBJ44wayqZqTOiE4kHsX z7(Mi8kpoWy@c^eyJ&Nw zp8!8aN}}Uz^my_=+GBo>_ymU`pv3o=03wulSRx`VOB@v6%vsfbi)486;x0WqQwc0`?vjHILE6gqhx0*@mX` zw#f!@)AH6+>JG|yxkdIsv0ZLzebw5pbzf7mCeQJ=!{`eI1%WrQ?a1_xOQ< zS(a}|SY(x9yseWzHb@P3!2bij5m&Gmv48NM373)kqgM0Ol=kpa0EtGzSeQkGhUjW| z69T)c}eANtgWo5+tN_l!jK+o zoUb~oan|jt|E0VkYu8+$#mPJCy4bb82lf?#F5#UaXY?)XmV1bn85(ZWH$QJgYa@!v z=J%>2YKrMU3*2pSZ4R{ebAr3V)1h~Z_Mx4T3z00?H`G+vT?CY4VMrk-`&qW1*^>fN zdeN#W-SFQ~r)fPor@=?4AA*&_O#FOe0Vj>@!ktG>K|{$}*p~1I43qvS{0e?w@HAl< z<|es+(!99Y^mWum?i}(>Tn|_nyAAn1(8=qGcJs!&hFh}?#}uIUxdPo<+xk*|SXH8$ zW5yXq+Q+p}`7NzVllkhgQ$q31&kk zZ5YMIoXva$@9u3&8j0e%Y2iXd821o~#;#>{;D12&jfi9J(Z_j;9H+6fVH;dh_xkYH z;4{}RTZaFbt4hyNPdCSF&nr)BEOK9~)qKk5Pza3sP(jjkUwe3zx|?hScOg_53oJF7 z5WqAjrTVo)I<}CN9{~SQl2orQdQ(vG&50;Phj8S z_z7vGiF6U+3@!mYj?}{2L~4T=SRhg!YKYE_b_TWs5cVE@lrVz0i!p_`6>Z`KS>K|2 zeRxVex`%tDZy>yPv@|*mKNP+hRY9(X${U}NjiFh_8^Jr~F4B*Uom<~Erz-~OcdDOT zKN>D-Ub%HHnryagiDilDwq}Yw)z;TPA~FK|2^mitMN(mg$86&64YiuAK!vcIXoAQ$$ z=jg6Gr5^8T>;B!`x9PRTZ``P`Sl(N6{hh)O(Gd_wI)(3tYalytDC|&tEK&hy)1)y2 z5RDj@s9ao5&=7ILWvnWE4yu|s7>S5%c7BHch~}Bc8!DjA#Q}Y$zS${vxpb?H+x_L? z+jf`tLv&TNZ3q|c9W95mf+@kbU{}96m$D`xpx*PUpE9ZIY&lwL}%>KlVSu z1*{b}0+);D;%DQU@sDwpm`i90>JPjE*#fqPR|g-WzTm%wIDn2ZJmxZ?Ewf%YGq#mi z7o!jWyw9B8^b?HNbQ0kVb|C8yuM2JnF~F~;zoOhAeughH#=}pVSJkDKey{&kGU|`A zqVdPG5?XCRjqabZ@@NI^AHK4-{Cs8a))!U2W~Xt4TduoiALj4mZwKWYuDTD|#=4K$ zCK^$Clb)!KfpSQH62E867$E zMY8<&?NP};)8@C^-PWAaC8=k-NXI^j1<4D#kLaz*IF;Mf<8J%*IW;L?(|U=m0xF#= zcp+L#@Zqs3ML8d-R$fUyHE%^6Tmnm4%B$uZ>6^$JWFC=*O$lB#p8*GjeU0D#d9CL( zgG-hcACN_wlZrS+_nXU__x#>kbwk#oE^Th7IbfV@tgZo z$r>lAT7&;k5A8Q$?Xl2B5Az*6B;3|F0CfRw3d}|D;3Lt`p?2RI3XeUBZ~*wr8bGOZ zcXL#M?l8>VA_{=HLV+;0 z62jy&4rtFvevBI!+#33az=UT6jlN>&T#EAq-Csl0sKX}-j|)wAPmfFtNz6Q5N8d$v zwQiDy<{KUv;@;4LI=AXiHLvEJa=mn}w%U0gxaK~Ah(otWe#Fei z=)y&gPrzuuPa|pBYB8#to9?!(P(Rl_mOs-Jn-4mFnXh^_`w7uO!L^|i@M8FuP-S#8 z>;ZfNPQq%ztfBQ1J(RTJ9~Qrfd&J)?ZW2hCJLw;|r92k%F!Q!>wdgK&FSe1th*1`< z^({v~h0XOBh8rWru+PXpG#Bz2xo=GG*ka~pRxe=-_Z4+6ZY!%Ni;oSZx2XHiW0T_<-gMWvJ2nXGI{{vrvdylW!e=U?6oDY!}7erEA1I-@--&`*=59FgQ zUG!60Br>t)xo)ody`jX~-`8sTs5>8Fz}6`C$vTD@ewJpWLmFrYh*c`Fbd+A zSM006Y#^-(E($_GR_GL5m+6M%0BkT89x4a7 z5i^PRumJ7|dO`RTm=W4*U8bPghiKO{X4RikKzz`~j!nt>6e4)v`fHT>^SCb#x%?`L|ghJM#t!y$lI9i;)M{`^KV>U zY!9LZXJIpF^TERKW-5mL7V5z+6Two|Adgs***X0a?I-P&cqo(s%s?%reIoA#zo2Y{ zH6R+w+m`qQCNiwqog+s#GK}pMpXA zEpN>~Z9h$eZ7{FYJlWLLz{soSQ2aqx9AhUn-mUTSs8v)_ z;I_X9B@VyW<8al$_XRa>jxXrD>B|q)2iE(JcxL+&Tyc)}Cb^Ym>8wdpUbjy5Hml?& zCNP%R;Nid*Lv!IROc>Xf^?`H+GX_RRABE-nDjnERbD)QPv6C9k4JQYR!=V41ZF1=MsVueYpAt@c|?V4rA^V%b-12&mGr#Zg{X<_L0md~heqx_<(Z_%2HjL$tQ1Lx6w zp$6C<0+P6xdV*R?pioXzW>K%QU&P&E%;9ZM-jG_xm-2fh*Tfa@=CaE8=h(S42dReb zFqCDHD?T9`UE|pcNQP$;-Nv1UWVc&t!9nZ0l zA!-B805IG;ed=+6Esg(u2=VOD>V(=?G)8(;z zf)@c_%@x+6zvR{LPhHOpRi@QmOQ6_PtD7D9 z7Xg($TVFzylzZ}_`d9w;urJP?K{{>~ZAW;vzk(^H4|M*q;>aIxOC3vsNZfH^Ps}9t zFh&diu3(Cg68k1*QOqjN4MvDi!JfqZhi*l&ViNgE)BrSMvQaWvZ&V3-Cgd_|2d)U-bQ}yB98Rml0a!9EL;X8pot$Zb2beCn zWFQ+Pfiu0?(K*f{-P7jR%7*Ge4O^t!ey{!gqXj4L^>1>`eEAvqjs}$UxO%Jkb<;!H zAm0!GuRCppTUDMU z8uVaL7D7hbdC{IDR-FBz;f?X5&Y`Mm-L1W-B}+%v2DC(-qk40#O1nWfqY);%rXOQe zXjbXBTaH>E>VNAcmRM771Jx8T+%&GUXS##72KQBW*nYsr^xZIa(G<8@zK7wB&|ETkm_h-ZC4TVFt)z!th|A-Mf``^9kYsfLGH)& zM~QLVjjWgaI;g4ejnITFj10vbMmj_9B2nZij19(y?Za0SdIx@5uVXL4&*&;t2cSNA zCym!MBe(%p%teRw+V4mOpznYa(V5u8D| zgRPD32wp+tj3a zTIIhJqDTG%{fHe{74jo?Y?hG(bMfgFTL(U!Cx2=8&jTl*?7j(Eob-B@#f&(dHoa|ca)1Q%M{n%}(2d)>KM zvB13BN%mz$u42vt7w{(tCHS$FuH@^`t9uY9M`hA(@%NzZ?>u)Jk`mUi3=<@*_28U0_63I8nSX3br z3%TLE_&bcPlw&MEe@8rB7?f;EdY?c^<)_XO8tI$k=W&nWbl?@T1p5<8<3RNupeOth zY$W_IY;R<5aCP)^=wzTn*|3wq5qwA5P2N}*v`66I;_Tq?X%5;v zvKVWCQRy|jbK!%4U*r)}u#X6TVvZ1>;l4(#h)z+R>#nIXibsys5%mx8T*`IxdPf71 ziRt6$Xzc|MqXyG!^RsY9V3UpFNO!n34Hl(V+C-||Dx*qymARF=dbG5#=5TYa%n6;X zSoc)>^S|D*VDSN!`uN0I-*Mmpnd%L88=BFh~^ zsu>T_Abc%jT0hm^Z|vW6`rqb%gOrCYqpH_8%?=JmEz;Cl6Uj1)$vY~LL~KB<^u2X` zfp3E?vkPtK5UFyrje&kr{z37WN+1@F(WujbhKkfb8w2D*xbqE~WMG4<>}F;iodEKm^SZXw@6 z*HMvR3%ZPu7?Sx0)BCb#`}>95jC{VmV7B$AXB5P^uXPTzy>*M>gD{`q$FZ51 zAwUm&HHseY6}kaG1`EPtu!oRu37?4rh_7jn7|Ssryf@W`UFRC12O`T{4_ZU@D$^#d zy7sIzPgS5=pi-G2Q@4GLU1}fcI}+5}`Zz0t(?h=C4D2n~XN;G7*!n(Czv zr*|eDg;EY_I0teKxrJB)yXYHFFk+9HNX;@37NXa|8+!T%1jfmy8}op1ggJJz`6fe0 zAFH}ozmPZwv8Md}-(UW5u2FR>RUA)R__%#na5H!ny#T=CPNTwzrL@ibG02m+NeRkS zGvyT%m0psx2m1e^h^^d>G!*d={U>n;dJ}L4I}c5Y>6dI`3(QbXy%e}*U1caCBaE9#4d@5EiI8*Hj8$iCP}|cQ=+a{ zQq{c`vt&J+1~)IS1)Gn^`&VD7m1}8cpR`0Sv3${PQjb zT-595p$b;b-O{A$Gt!li4SSAUVwBr)s`VCVVG5pJ%XJCWFH$Vh^u|P)7 zWK+cVVt;dIvFGu1yp>cru8+_ee-783%uc)_meXI*&8&JPh2(+n4X=z`^l$YXLl0&S z_pgGj77s}@Vo0P`Q2{F-^5y)&Pe1?>sXsNSbItKiaJQPLsUaD>`DxR!>QYTvtKm<$ z=w@AW<@j%m@BDJ0;?l3d)emY8w0N3LN|`!nIHMY*cxwEjOOtn2!8H@Ky-lOMlPo4* zCVVPt4?w}dk$pmq7!ml}ea~4Q{Te2DTf)y^Jah$O6;MIghP@ho>J`JBF1PcB3kz98 zMh8|zzw3XS2LqLGl0Ct(G_o}Cz*cBBc?mwIsnB#b@F|*Y5!=G3e9B5<4)q2i8n*()FkN(O)Ep^^C?i9oWzl!=yU5n4H97-x z8)J;*g=olv&|zyg{7i-WtV1)M6Bn{4DhqZcx7vhU)gury{H z%5s0P`!#MFdbek9crp47fsVRI{6!zd`$FwQ|038Y$Y*rnw2isMC5vXIA)qh(Tf1}J z7iG&#?8-~l@-tR5q73HgeX88@X_X> zwuim|au_dq2A4)jh8>2N(g+L!yeeGFn83;o$^vwDTP7l`jl87{!7?L<{3DQ^kncT3 z-U{?y+=$Q!pa55k8HmXuL{LwVFUbq3a&Rlqjrx-$3G}y@p&!HE8M^A)2ZKJ9;ks>K za5#YU{B-g0_lesq7!#0HI!N;&c@GgN~{)KQQ z?1=A}uYI`G`_g;PwZgH@`qm~jE3M}pugu4+1Kp?H4{R+~&}o61%Fm7S?Y`g#i#9Y4 z^NZe=^hS7%+m7Q&E>8K6HWa@*p2FLK%O$^JrE@A+4g5=jRq9KK`X;w>;EXmBaJX0iS`&r9u63cP- zG$+opBy=#^%Xh<<3G7FH@SXR!AzWcE2vgBJVr%1IWHy~1JD(w>KEr0B5?q6$_vEBE{)HYpO`*wswvzqLW+shUsRm z`J}wA?u34oYJ6GY&v484=7&YtU)ik;<;lON8}8`qUCFK8W$Qy*qPLpoHC_pI_8e&( zrO2`$v28RH17c_*SPL%0Z;fOEIphSY0zm_3($(xk$c?zdn3;SQrJic$jAt|w9wR4E zFHuuqdm{fBATJ$;LVOmZ6F8`iC``h{I6XogZ6}<~%L{sZv8?~7!oc9*UaUX-*?-RHOAhLhUM*7tU%$Ke|ZL%H8r)_@V9PCHH2CE7D&RSQhZLQOD?YySTzIt#xh+qVy| zyL)VG)aXcih{1zkk6#+h^N-UFZ4z z9*1K&Mvs+Sqs&{7xq)lue;t)>mU|ko8CvJt9w>svLPrM1_z=Jv*Dfc{Bys%X8la2N z{pULbNi)XTT98u+2zM-yL4D0kfdEhhyM-PNy$$#Xm53_0&bAOPMU4eH%fIm5q^GWN zo;8HC$ZU_oxh#+g?lXGq>)riak6o4CW!B%?HQsCX|H;0IcNuo6SBc+B0o5j5mT`mU zr+r7@2K)i`3R*&l!q3OkiMw&nh+WiXd=6Cza@}(|@A+k{P9{fiDD)f)U>^<56{K-} z+;al4V0=h#UW4F~02TU3Fk7e;`UK9<`-027fuI}X6mvHDJR8p&jXRBTgf&Llv4;si z1Zk8-_`ZnDK(leXcf9qxGDNe(;Eg0P9Z1MdssJfj1>?Q;KcRGlr{y@dLVlM2o?W!yfj{m{3*LV7Zz+qK-y zW^du{0HP5(?sd)(+yz1_3&LDRIz^FDvxx@kFq#1U5<#Ga(JvsEW8ScK^F;VP`0>I8 zVM~$ke0zB;`V#9Sy%kG_*XZ_{(;xxZHbzdOVhP7)KQ=%uRppdIO`_K%f` zeu;MjThRAt1kNYoH`*L-HfsiZl%R!P!7xYdjD5kb;bunn2#}m2>RSdMpNH`SDC8vA zAZMkG0Lk)aI3gTpoKGxymKfbDlglJljFoLRRIC1x)QD-)$vvf=KRT1-mkrYHh02RI zgX4}SK|9F~mEoTs?GLjYD6Ot+{jD;nv zk4zD*OMIPJ9x*m_VEhyjIQ=JX59KijU{)hD$!`cZV21-!@hl9%^V&*-^MTbmmGrSw zX-o(2_g&f>x)hbdRA}LO=evu78L;h`lh6!^1fxJ!`!n2$klpSk2ia3@Q5su*Y%=@r21EiQ@+-3 zu&h$qmDBA=2U;~qqq2{2TsADVC%OW@9o`=QXJ{32foHI-8TAmsG=*7|ur%Zh_cG`a z{3v=hZWxZsWwLgFK9!?{To6s*ay)mqjfozXzZN_{4fWT$^Ue8&FIKR_q|$fCYsflM z=h@C<=9%tL$$9lrXcsBnqVnwy5k#*B_t>YBo+J%s_vJId@8dV#ch+y-T|SnoAlwhd z@h4)Bpu(6!0tM{KJc2I>Vt}K*AHi*~Hvkqf8JgztpkJW^y58MckkhV~mYj}b=D(&i z70!WlcOddXC+-L;jGF+R<3AK)VvYCj4^o*R#Rt|3-NyRPcm$d=-jU$gNzOQ@0&xhA zcb)M}g%`r}gCmeTkrGrkejT|AeGC1aGLiy1)#71kc!jRp zG?0={o@xVZ9T+^M%mOiPafdkSw2yR9=R-$t^IH2{>jcAgN2&F^X1#ui(V*Y$I0*J! zQ@v;LYsm}Xd$H57QlJYv0KVEhPQJhcGymvX&{d!<&>DK4%T}A_+0H8;>n=FqzCl(1 zY?P0|ehqGfzoLKVF2xqmal(lrTKMF&iAlwMS7$(am-hde{WQKfVpn=?f?V)5e7)#& z)XwO;Ano@_?5T)X>`9_q{9OEgSdelWu>mm-uM9eanG7Wl0~cWM;X@)86MvCLMs5=w zBTXkEVi(8QNadu#f-Gt#&Ig^2P&z*RtCj-&T-|6R)-cxa&0L@_)iND1u42_5 z8Q#%kI@5EeGugn=Q(I2eXX~;wEj81cB2`~C`Jj=_4eqkes}?H6o)w-Zi9veEdD{-v z0`_cIA>e}KV9%g_5!HAs!A0hi5-91ssU#%hYkYja@d9Dos=+S?rle6)*Y?53km8Vn z2yQXKL!F7bg;|V!34I4SNf<{t0!u>X&`&YPq9M4E3@~K|{^r$)&%QN5vGb;LimT9k z*2MIbyI)!k+hh)(rP|(Rr-Mei4fYi0L+@MIWA82)9@~IDOPIsh3daVzS&lte+{sZnLqmuCtdLcM# z!SD*vY@CiaiTMb37&#a5$`S9vX`gFNifP@l)@sEQ#n$G$=2bllTXX+jZ#Y%=t~#X_ zQ=_X7@7Y`5-8s)V*7F-QiN6Gf`wsdC2H^H3>fydcj+N4J(nxEgm9NS&*0_EKzS{A= zo5;yTRzMTv(yWaCL8b&&GvTyaUuD399fUfE9!r0Ten*_mCkT5O;hYN~>H8Y<0y&kw zh4u-g{H7rvUXgti4&LcYNrDBMWQL?#FxvnP8M zRvmFB(rqrbe}$l+;HTk@MNC1yaO zwKG}PtLuC7lIBOPBU+}l-{^VX%I$om9%!nO&{dzECRfCW8*?OU^=|2c7IL$r!`il|You~xcaHkE)~NQGmfC*w z%ozf0b$ADiQx=WK(B;v41z;tJekAJWx`VPKq& za2Ff94!_Lv*guKbO{xMe`qq%6Nwwe!^EPe(>XiDsW-M$Bf@6xZ4Z($y4_TIIY@|la zk@hoP;`DucXKG55zuU5%{JgLy{0= zrcH=D7;dGHB~)@MNE_h@_b99wx!c@VR{+Zb%*xl&W3JQocyWHmM{rY(?}`?$bq#S4 zyY6?i*)8t&PKAUVbiyf`1Ex-7f5dP5RdAlg4W#-80Goq&kfK|M3E)OhvGiu%8pcZ6 zC*j)AYSO>N0&ahH5oIO2o^v>KV8}I2hS14RrX9x|WUVKj2i?;x2y1Y(|9W5qY%F?2 zV6<-*?lSI-Yqz5a(}4Q!9O-?Bx`-|X&rQQ|OmYd06*`b32@^$MOKgpyCG;e(NW2yY zi4=*l!@bPUM0eP(NIotd_W`8gZov0oL2@I?0L8ltoL{s@^}8fJinYos?ICSZsx-N- zeL%I{umb&wC8=T--}ut~@_=tnd%UPMa^{S{^8r0@yR zmqm+1TG;1AlVdzAB==cDldV%i$d0nXS><%RFC^3eqEncV20FB1`XnQ0@82 z?U1#!S70jVwYb`c*R(aMx)&>Wos$$?eUd|^Z7}@tN&uWG%4!cFpqo5;FdHPHoI<}w zY+(*&e)o@Z@Tq?MMB8Og5POFh3$Mq~89Gi3VFTL73L(KETZ2)-4X!^3BB8>W}c{d+FQ+1Q=RRDGs?EZx65-IssYM=Q zF61>M^I#kKOF1V3fBXaJ=gB|)!-1Vd3Dyt13sxetV8`GqF)JXOAbflY7WDgoc3r*q zg=>RxjOnA|v9z=GiS(ix-Mp|Cv(l|G^2jC~e5jd~@}iG4^tP4E*j#3bZu;3uXH_Q@6HvI3pJ zcW)8!8vYIUz<=4jl$1vTyLgr~q7r}B+}GTSb7O_pNuFAqoqPqG&l$&0j6M`ODJCp& zVnS3@kS~im&rfCqD4XbL3Xz&Y{Y?HvK1j~MEhna;2LyDsbnisd7DJ1^QuRZgYW)xR zrpVTfL(nmY%rEU8?0dY}HO5ON%NS#TwXmTa7F&nZqGnLWp+gbwKt}MsOYDI-CfXjG z%~q&QVW!(|I_TcXc9yjW%vM+G$0{$nPMO_3pTrbRrEG1_AH`lU$^6!^)!{cKd)IkG ze0^aDQK1g6DHhcqvB{KSzmIr>8SigJ?k8_#@5I`0gE&OS9>N}K1c`*d#XFHOffUAl z)caAdQ(;wM@>oPjE2jzf8ZQm@@#*w(-(TMob(iK9a3P2?{$sral3aQmTb*MNzfenD z-`#A?A&kh&^$T#{Ne?0QsEf>ryh)^TMx;Q^-_3DxR&X4wsVq8k33sSK$Uetk9;p{W zqoyR>4Nv2~iFZZ)A+N?#1-rNlu}rFwQ_4>Rxw&fL^054nUi6pzw~S@j65t?iWFXpo z$L@74x93M*CGhMmy4+ATQB9@-9c-a7$3v@IKsUs(>{Xe#Kis+eP?k-DmuQ zngc#JYHb~;Fybm784|-9!K1^y@c#tA1ry=-AUXW?tQo*@AA>rAI2F*s27}4zES#LW zhom5`W9G7-;csCUao&YoLM9@%3z?z~r~`!eqEX@V$QI%UHl8>G-78>3)FQz=vtuyf zC3BYN4&+iOF?=t20&b&_%Wp&#Le_CJ*kgRjZUW;yvB-JUzC7^K*sY%vK;r>pCRJgtO^JS)GKPI5uNH?GVZayF)WmKS0`mBGOI__=IxsgL^=;)H&^T{T=mfRkCK4 zs!K817;nET>DPJ1nd~TPQM9Tod#ny|sJh%$1sP(w?cI+{WDJIcA_Uy!JSwJ|kizfg zr_xO97(r{;DUN}O2nRx|sb|RtIm78R$`z1&=O8i}_ZT8#KjI|DQ~E0+pEQp`#-|Z9 zC>sWDP5;w#jO$cCm4CXkd&;}=+P}9i?XHrp z?+z-g@{zJ89m~|GYsO!Z{bdv8Olm`J#+-vrg6e~G zZvt@Bv%#KiyzP4H1k}@&G}nF4AH_vwHBc2CrkbdVheQSwRd-ag0jckcx=z#E$MxUT z=UZxn8YIR!!t(_`kF?0W-C2)Upf%26-kYfH*tTE^x`5olo{B$7Xbc&^Z6zEaDH#Qn zC-lGkJn~*zRK(=SOH3>)EG&Whp4OYNjVMP%Lhd_CfYqJ_`mc%u?oQ7EX@$h^UF;bn z5p_#lRW4I!ai<5&jLj31C7T_ioj93P(aZZVuuD7KbRHT3ZLsdQpAC?Jk2aUJGN41; zw0C-&Nm0B#s7lT$;Vj|Q$PF<)d~wK@Xi}7oClOXfevTd%85Z>|kPDE{iO+)1(p^)DAd4vMT6Js8F6EsV2HUxoNz&mTTHx{xDRSqK(wh(_Y zFEiRgNTEZ+X9|W3fbcxQM{XItnLUb3AWtIfMZbVv#JjL|pxEO^Tn7%=!gQY;V&fR; z{q|U`RdedE;x9tCMdxX)>nzk{DD`4KNXG2Y62vcMpKT9)FN_G^MXpXH_qJ?tbmM%x4}D+8xgsv zYpA8@b}->_6wEb$!cD_Dk%{n$crNK*=ojd}jP#J9sCfiApArJ2?xfUFRw3!wxxgP_ zCA7wJ%p%1DoYkIlATqsK9 zFx*n4*vPu+l78Z1MW$@I7?366v(5hH$_{f26jP^rg8--xYp6#p=+A1 z`Q7#6@8d3X>#TOX`mR|g`JnxuMQ*&R&)0V7*BSdN-^%XW8i4Qe1YHkm45`7o!kbNh z%Z!CgfKTK)L&u^XV!08%$a=zc(y_>O5zk1gNO|E41b0D}-(U7cViTT;{0`mW+UI}i z2s0lyqU;j)G1CI`7f1*u(=b;48q0&JyWV$(d-(RP(!2T`=aRri=Yc>vmcV=oITef! zxg0VG$n~FN(-}6PAFPQsgYgD-BRHLLi1NjI-&u{F4twhmyHEK_JORKAi}FbWZd3#A z8Eg#l0I8UC4aGzL#qUHdgWmOB4&L`zZB|`~3-75=98??v9zdBIyMYJ& zG5GbghkRs|f(;94iMbk0K%?R3 zT@?6tn8ZNWM55)C9PMw*e)d)FI8S&WpWQ;+5!mOuMnaL|+;=<^iD=vuz!JO%O93qg zrOws*TGdIzea#@%9(9)1X}GPy>awi2TsituLlVeHG8^w3mj$)KQTlnB{(%B7O~cnE zyW#Fa(-Aw(R}su}9dv5p5R}q-(G-EKg5Ni{I>#c;qml4`2(L+X3@!{y?UTk>Sw|=I9JL4EB&-$}_OB44+aD;y-?})Gc&(Vp9Qu7s^1A#+-)qk+2 zpccaJIiA{o1MS{U%Sf}y{nMFmUS@f1Uuol7r`V+S6E3~;jc-0EFj^YqLK9u@oxY$N zxaOG{tO%@!7ow?z0Yoi>fbWeIu&ZeXV87=#t_AM*-ABlwk5Cgxdl+z1Cw)8PD)AZP z5xE^Q$}w!B~TX%ako;{|`hG}l5E5bO``oi_o!}i>VmH9_P*MNP) z32;7q6KOrk07(ZHk#>7hnrU7DXZ@hbma-N6 zj_~%Ijh9=BJKXi_T2@IE@{Deb;)wi|Btl7)9qG|4KKA^l@Pir0pxG77f&q{iLKq$A zX*N}ok76k5Rq}aIyV^Shsgt@p!_+z<0X!*oJy!Nmn{7_Q9Xt*eWvY&KK@Q^$J zJ;ePSnFAYTxU9N{$j4FC&-5OWfk3o!?U_i3f3W$4rW@>{jFe$}Y^Du*mpHSlSU#@R z-ukqD&u{Bk>t9rg;7tqVJ${|AE zAioEGBU6}PSZnYHi0hdb8GQ+fxP^>%#u;=XvVt*_VTKW*&CK4MSm-)f8D}!{6l@dZ z4{;@Ij*n$q>??K>Oj*Vswp<(Dyug0Sw%Pi|^Cj>Ve2u;kOYo}xmz4t92!9O35$@rJ zF`e`x)=3^ypk)%6lF)sjr&uN2HeqSx3f?eoUUYQSD>|JxEA%ddhe-zKNUhim9Evar z^AlA;fDpGLP_T=HyV##WtA8GRu8-k%TRz*a>ObqO@_)4(v~5yAHd{Q_l5vDwy z!*tuYLiPXD?4jCdjo)n4f3}BtZUHX?a# zPeT^a#OPm82);ii-N$n!6RB*sD+%}>zAM%b_hCG7FJsQ*)?znC-ii2(T7te3`8KK= zH-v1DEEEi))0pGf0I`fdoiZ3v40hD_BO%Ud_Hf8HAR0`+Do2@

    `G^&UT~)kDwAjKX6X`WNaMmZ(0Q?IzYrx!iMT(^d4{!9%6Fi z^GPjH70Ii3k78iaX9!mT7YOm-RObte#dF(n+IrmD;Vk#~^-$SR_X+dpjy=_X$|q#fXmohkrKqk2wik770qqu9E7ylztO4a!RC2xHsl)o z6<{QofV)Th7|6A6#^)nG8uBb*f>r3IUxZi;UqFf{&5O7anI_m7c_XqQ=}qz&<}-R^ z;#I+9#?>%~`)BlQE-jMI+(;-Tpr8N{*Sa-S3V^9>GB#8RdavHEKji9@<2AJ2qfM=) zZyL>IXUchv=SzoI!NdqzVasjNtKRXAa>*3Y%AdgxZ(HZo8s3$CnOixm8e5T5KeOpq z=bV;}Z5{m|G;3ORHeA(_)ylfzZC|7dWci9-CrE$DyBiEe-9;=RQP7pBR@y3RDXxY( zg<3(+kG#X%!K`38gt=MYBHwXFkFZU=6=zIROlcegOZi(kG3SGT&mK#OqxXe#^fy5a zLKou{;43sWHZjGBFJOq1>UsMj-!ozeqrq%KJZxxSQ*cvgedrxz4kkPU#%1C`a1gzp zvdFzrGZ%H*_pTSzlVY5zd?fOB_bFZ~Z@0u(!)1d-YfH5y6>WbuHJ2}~k7;JLH+1h; z-4!2JmRRn1K*mw_4zI*L&k1lIaK3i7+oTqmC(qv-w$&{2E^*zl%rVV(oOH+xYmB$u zIL}_&4>!*~SR?Z8cdqOP*FDm{?>7C?)PAXc^UL2!QrW8vP2bI9%@ewZi0{eRT}2(! znmXGB5?{mPw)v*ZuowMjoJ!Iy`a;-IVj-=UP)C0g@e`p3ET_icO92r00?Z8@0e_n? zmO7g8134+!L%oeT?A7~yh+U`~pd2`qaFv#i7!2JWsgHaDoE&+0`a@^KVT|^`hQiwN+)?TcC}?&l&GOwAe)Q52j**;ljoXTCVA#P=ZTgORr5TQ5ZQ@->J1ZOFJ4`h}4oT$M4UU#Qc)^=2RPu3D9r@!vo*ZZMiPV;}_#l4%t z9>xmEg#P974o!?qD!Zh4to$g6>Jq3|SOjfvItu|ExD|4X?E%d|f46RpOmHgxU&zLK^)a_I4mgjWO>{=yV*N^Q8wVV6$Wi4WjvOss#LNRVO zAGU9>In2fO4VEd^2fzX%(K`mF=V+4v)H_^X*5urI313sa*~gL=ru>Xs&;7<48hwa9 zI4UPLf}R|GDw&8 zVaF8{<=cX7zQKk8J_LY+n1Y!|4kMl-FOX1}x11g9uizIxF)N+E*S5?068{bz{+B}% zan?{=Z;sxSa_zHp(7$59@1_{41%E z8O61dqR#D2OUjaJ*k5OUiT`xx<jLEMf#`vz18YJ%Re;U(MqL^&K;e{TNc($ zYTQ~gv-zn+TR);Z(^TMHsHt}q`0E@!pgW*E(=o%-z+TT`>w%EiT@jGM^TMaLAZ#`4 zeCPtQ0yWrw0@#RNj=zEyQ%&TR5&y7CBDaQ#0@TPFW*U>mY+&}WXbd$iDvA)9PG;jm zBm&|HY!46Ibg4MM?pU>?_KtX#F3=(s*$qWnOn-MDR^BS2 zh_k{YCh;#V6~Yjp(?~z(<#e&)DX}M%WA_; zbB$tyV!ZUO?16H$f~ap))k*#~vklLiMP*W1V`tHqNnieKEUl-NpYF1>koxGV7n+0W zhuVRXoW`;8JzbkC=nXfUZnRX%w}PAchPleQ)3cY5whHeI%u3N@d`&vZyAmb{&8Jty z)TcI6>zMkS)tQTUH8EO&oR-Ob!MK2Bqx;CWiQBOgv9UxX;UD-8zX`J&-ff5AY5)8P&iuvsajN_$KtN&N7>R!}!p@!HqMdH(@7{2=o-OUiIZ=7>G z>oT5%E$uJUnei`ZQ^SZ^3283BHsc1RfcbGq z>o7^QhJ8MFMW&d!i@ZJMmv9LBDR3iaFD=OtqsXHq(iZkjk}Zn3A5p2Esvku6Q$OjC z=q`|tVa@8VvZdfl&fOw=t4Mo8@unfKi4?X>!MldZAeR468XmHslmhX;W`{nrZC6u@ z2BGq|mPrn&Ht1l6Qqv;K5-Uo-UlC`{*PrZPsL-gT+Dp!t@OF1J@&$Q2eGlzTR4e5< zS`_V}%>>s5PoZ}M-vYm3j|3KiY*EI9F}QnCuj2P{+WD7bX3>gBqj^8MPw8>d69m_U z)45b`qwsj_Q0{%+bHT4T5@&8iyl@o{j(Y+g7O@{Q*muQ20!8?~+c$Y{cpe6y!`?-F zfL|roCQQ!#ogE<@HTZq@4B;i7B|*R`reDJdS?QdS@F(b738u^))N^b}c0!6GWP=UDOitVWyDlkNV8XoG4wY zXldQs{8DC?_jR4q_Z!5(vEF>pi7=Cm3gLl&u*Y*Ckb8(-oV}d?g}+@@(PP8LgS^OC zZhmYYQ%n{MPYd6Xj?+WJnTd7mDT1ph_fyxgOYj4QI~XwkZhaxF$Wg4+=>+;T{W0%* z@E2zjU?k*@_dawis6cx{JjFFgS0K?D{HiII`=N3)4R9KJ0J|PsPw|k}xX0O~sM+9d z=T^XQ;3{YarZ8d`9>w|0`aydfuTO}>>;TP-*}@cu5}`{8yTY5~Y!n$A#GoK0zW1n= zurAv^(9r~`EV6rEOo>Pl)U*E7|~D&UWeqQY9(&&s;3 z6|-v{k_BdU*I?}r_Y=ob_Y7~N<+@{-Ym=iN^gD&=i2n#+ z%`(5x?ME$uJ~6936eOBh4Eza7qpzc5JznJ)yessy`R`JRj@EUtm|h93?yB;%mq~Xv zFBJV$r1vlFqlr(2@6t_ex+Z?#Ufq=DBb_9-9(Yyi(I>-qLK__WT+e{A;C;KnyIaR z!v$-7gYbVKNq|^XA#@KM%eWj5!Y8x-%XSUC7CSHL@63ObCdcoLnHG1Nm%zOeofWAf zUtztb_uy}1!v$3GGAs{YLP)_nh`FRkh~=>5xb091q$Nc2KD8L!Mb;|I1J8TY8A~3d z6uZ@t?cGYsC(;82{+XC~)N^lY;5GU`;%5*V-N+QjHc@3UNy#5l3Q{j-RVHqZ>&l=d zIR$4E5rTIdU*@&J#heS=Z$mZ@T*P_J}-VN(wo5@=SI^kOay8+dM=3!ItQoqXo3^$v& z4m=%yB4QE$Y!p0RkoNbW=cy-?=MV238W$TM-I?<(zA=NIdoE>o_UggA25uTSW5AfqS*h6cAHvxg4+g!CnHckM%%EvE z;?^d^XDKJFOdp%LCFd&tZZv|lifYF5QRCn<$ko&|?-!$&FA;?_c6VQB z5v&q)7QGc`r>RJA$^!2BSR8?aWXA5{jD-G$c*#7zL7L(~GsGRhv-a_U;hsp!gx5w`291Gq})PsKRh4saQ~*aC5uW2FSX zBhRu8mxlaDU!t{wl7d%_18h(H7=OSq#rZ!^spF>IWj0tq#`oHPlm_)>km^jonAO&^eaq#Vf!#A&|E@mVSlZmyHlw>uCh0NsAJ-o=WoRFo zsitd&>$X;meoFPTiJ1;Wwbc9 z2jBOndb^XLoM`lhlXX|^BfZb?KgsGqd7z7wi`(GtwiLh%LvOWZ@`di#mcxB-M7MMk z)ajiE+rP?AiMv|yP4~No_9*L`8jj138@6|Skhi+>gBsH-CoJ^YJ1UJBJso-0n$qt`=G-wE7o_({EPCFQXI>^Je ziC7}ofD@_c%H)>@N%d(*^|VIGDgd( zqtWC1zsL{h8Z*j#lXZ~guqXKRv>g2KkUw+|vL*-%Ciye{QvXpe)APl5$jWpko9-)n zd%lJV7I)gcT?l2m?uYcOc9Z>Z0IdC@PzDSA2-)569sGm`Y%4(Kg%H@0w8s&%Y4nIg zcuugH@Dh}u`BT2wv{S`0U;+w_$2JRdh1>yngu07a5E_R}2%NF1b!!ZN_7@rN`O_pT zHEa}!RN`6z6%k${7Ki6$M?y=y?+DXy0?57P%6%SP?X8=t&>NN2KN@K!jCpUYmEWgCv+|CjJ}lr=ju zWn)Zt^gOtb#1A#t&uPDy_AA$^PwTGBM`}ezhgoBRc-WRFW=8N4Fv42noB`c}(EDG8 z)}XGz*9C&kzW`%Ad-Z8*rnSISrD-!Jn7KBs?U~bV_uC%YPgs1$3JuA2z{^wH^hQV< z5$$>it7jZ%#gJanJ(Mbhj{FSyUtpp4T@dUp25rJ$@^%4dMpz= zwo_|%144`J6GD$*!%=p$h;SAC8NH84Arv7A;Jw&LWNPqM5QI31SqYWm_fQA0(;0^t zR)LNG4p#&COg{^M=jgJ$@er(XXAMMZeHX~a>&Rmf^9j?5KM-Q_pQMYv6;3Heg!L8t7C%_}ub^DT3Y8mg6;?`RLIzeuKa^;QFF zT%Tn>Ru&I`x#X#=R9H`W9{;w!YjjUz@q*GVEj!CfOCElC{{Hft-`-#R2q=Lz(W^#w z|1GYUO;$A-tE5+Z(k*5Ky6tkKN8K$;Xui?&qo1x!*NS};%yM8VxCRo!?Tt7CxdP>} zdw7RXJ1Ma-_hVkM2J)uFOo}-u6edGrOCd zE7*S!sF(|^Jy8f$4VuGWC_IdxO!^$x7j=cG#!SZl0n$SmfNU?$eIqa}w8vKySO{JR zyA!q#2q0!}uH?_wc0;K5cKf&9xb6u(X2lZKJMngLv^1&hX4l82ysGUbJF1tI9w;5! zWcu-@qDMa-^h;c9ACEspvcOs7kN8SVBlQ<~8SX9tMO+mo5}d~v(SFz|*e^gLu-k_Y z1ppk+za9rr6&UFT*h(#|u0J)aIt9PBe#x&{Uz+tLrtJ5Uab*+2yZAfR|2BcUw=|)f zPd6;BT2eWuzO`v=^K$*qp68Y(u!^F9J*OA2e$vX=0QM~8ThL?bWLzXHjSRpZC3kVL z!u}|@;C@sATFd*LdBS(r=_VY;9QB=prsGzUCL-Oi!<0Pg89=J<0%Z%O+LIkHQU9O= zK@Xw1G$(l_q{*))jKCbSZq$B&eFG=!J8k!1XiQzWxw4<2#Ww}o9huM=_XpEGbD^<8 zKP_;I0&-Abq4bACmPG$Z=ovgLEi2_`d^&%46oB_{q>Miz_HsT04*>p{{2|NOkC7-3(O-N>T>yq8`SWT3U;POBQ+6jqt4AWPEqhPa?Tv-$N zw8zvxw6|VgDd%^yd!{K?>K-euS`L|4nJB)dz)aOG(HD=-Hl}4w%Tdcm`@cOcYQK*T zL)v$^%5Vna40DWf3+@lZE{VQxHuwn0sCn*!!SrZppvE7G`3l3^SE-WxEyg9H-JOf2 z!@EvMTzX{JK8f0U0Q`@JXWb7j@%kO%PM?$REw+|BrC=c8ZE!on&FqZIBZDIPqjNde z!aI*R{+T!|zg#djX?OCZ*dP3PNw)Z1VaJ|4Hl06`?d442ua2J;(;Z)&o|5w*b#2Ci z0k@LRrag-H2`;8RIkZdAwg_W7dX*aacE2 zD2V2-#{Geu&34noA%-&pGX(rphn1szzuEri9UwMp^OV2$4_7Csx0puiN2{;9k9!6E zW5kcq;JXf_^K06kBd)*_wJA=o8D5qV&1~dn_Lg|q%30?8iWKnXv zm+p1SZc1^UKGz6&pDxy;4hY>}p=Y2Yu|*^=i9{(Q*-(>!ji^*mvv-B(o&UVY90&oF z&X2azAk_84z*p?k?~*MO#kWJHOSP2t)8a{Xh0CtErY^Uj`u>s8+N+z#*X^tAtsK!L z>wa7t)AmUIM$Z*HWGl2Sl1U0w|NW-M^6j0O4V<4ZYV)gB)h-a{8=)PY@)Y+Icc#VV z=Ga%-g28m?Qa1p63rnX@!;g=sXIo-IQ7^cOu@_?9v9Q!{!h)pyoSZ@Wl!HmbGr@6t zV)irkFpgvA;zz)zAkN~}fV&aR5w|(lNhQom&V71YWEK4se4ITCTO8CIn{5#9n84mp zJUR__nQ#I-0US@8Px#ArF3k41>OLT4DI+a+O^Q+E}(%vmwv zXG%G|_WJi-C4rWju9osZ_2r(NuDXU$>$&#B?Pt3#^+I}V{hQ?1H4l{>b*z>vzo43+ z+9(;{TdqkqWlJw;&)e6zvTOyO+4de?zWauyqEFhjQq|M@UQ%sLkq|ZZ(BG(s&K6)C z!s88FD81v9!+IRL(F$01vGjkcJ(g}u3a~Tu7`Gm`hup(D$E_eQCQ zDOv39xZ&}~grA~r#KYK7@y&=+M``L7@LUUp*cE z1)j#xLO?p;Df}pUx%0k?0-NZG>)zhhr^)Pl*S$}EzW;}IzUiy=vPas6 zf~eeVn5^4wxdAD%kV93>H%aq|uXqcyUu0ZQUYu4LKa-D1!U#+FlM-9vIEj`4=uwW; z_^iSSZ4-;KHfD~UkT_~e>R92P!MjsA?1u!75XO4|ogWCX&QkrZjrP~LKQPlRe)DeB zdw7|-%Mc4@`{GqH(G^31{B(U+MMf{8M^sT)bE^B9D6^5@mL-l6U+=ixmC(CKDiAlz ze`p7K3M@~c3{W+sjtpU*2Tt*7=pnq?vQb|MjqvB0VZJ-QWZ+h$i?#seC14 zSxoGh;5_mf_!UcwmgL)GexkwXkE@boZ%jyQm$X+Yvpsh$F`~S4gG(U$P*W)DQ5yUW zMk#Y1RnBrUHZj}TNBN}4gy`FGrxTZQ2t0f;H-00xgc-rR!x%t1hCD(c(_+GIjpG|v%J92*%unztjRdO&1y)u5-jld=j&jT&u@jf*bM z84vByk9AzE^Qau*@R@ep45&uH)I4~^G z9ZZiW*30?j3j7J!E=&PJ(?FATnphS}{>a)3BMa>)A zc0%N&QIZsWYvi@4ovyEe6Qow)XU`;4oW0SQr7-oSSb$EWv{HRDti`mb-^f1oCUy?! z<%r9>@QOjQlh$L#LR+bSIc1q}z%Ajr%q77P}XBEpv5rGH`Wp2)Zi-MEFUi;PKeW zbR#jFyo~S&dd$-Ug?VZ`{{e5gYeS1LZR8P%cC3JS4SEX220nG_wS%112D741Mb+vx z7OOQd&$z&$hR9*D{&RpLXc##RBEZ1tKkz5;FX+icFLoa@i%Nlj>|fwS+ZEkLty6tK zU2ptoeP{aQN;SO~|8P&%qigPcx!eP+ZG5AA`?|zZ{Oil5vf-s~Yw~{KN>0|-)+BxS z@#44g(jUra|Gha-`l2TB`_kIOZQZ>mJHCoWDCcUV-HMLY@)pthj?>*0?KfIc{dd&Y zI(o&AO=$CG#UAxI!xiIFO}_!|dJS*)T*5w}6i3D~H*lQnS==Gq9UK7PD_GB2%Bzee z#hCajc$&x$r0}7J7>#6rY9T>SA}}7h&h@}c!%QM7f!WA2I5MOVy&5*l`AvrjzIRU6 z{%+mnnC>XnXDZ*S~qzG@D6l6u}K86X4nkY%z53T+1d>mL!G$ZrXD zxSv{q!Eu2WolCjgch<*KGPIrmFBD_Jxd!?&Ecab@v#QV7{*M&cIlB2~)2ikv&3Vm5 zjYHaO9mQ3HzVlmU)%|aUFBCssf4=%0_aX7i#xl__x@ciDR*A4R!kYanh@(kH;zaiO zm}eLaIvh-hvEm0XcE{gH_jCLB_}p0opT+0|Q?vG^f#Zvk6H-5g~}xPU}K54T>6{*ruLGtLYr-6xwiw# z-Ho1cFa*qMJ)^u3K%16#pjvUF<*i6jyKY&>GwEYL6G1hP^J<}!0LMKxM^~^Kvd%d> zP)Yn1Hyb%QGG-uaq#|MZfEi)@k|Ud+n+E# zn#HkmirH1d?OAbxp5*&O%7=2YhYcu6r*Xd|m9hV#PNI6Kb=0cp{M1|Q6=_FuJ`Wh0 zdn&geMZ%kraY$IiR7SROMKMM}Wb(KaaTX)l$cJWbiwjWx0T$3c0RQI@8Xt#qh1+z8 zbvS*g;l4gwC$tW;uU1}=AncE*Q+)3?ScKXQ;$YtSfZq4356NvcI~kns?Wdnq+kewFUM5hSRN} z#$AoGJGwhIH(Y6m>d5Mx+3f8YBHAiFC)udEti9oYT1GqA0Sj=BwN-5aUhq>z$Of&= zsm`k_Yn~|oLxvL-guQ=Ric6|ds!I7Fxmc58-K=h~3=M6-Il?{J3{HOHRhlsxn1Rh| z7mP@_lTng7IB{A0xa9ogPXY+PA$eSKBKt8TGl3-dMj~O}MZaVE;mz{#c1ac1HWB)vMWH+UtC2t+Z~oOb)YK z-x_?{OPVMf%TR7b21f&ku50!g{yC0v<6HGR^BhZ~+$4MDJn0{#z>a5s|useg1KTgV@8~JDwPHHY(_w3JTNJiSwb)fr}~kh`ZdUO!JVcP_I7Q z{>XFBGbY#s9U7PeD2KN|L!qMZt$rqe;Wju=LJkp}p6x&Z_g-oUZKWK`zLWZf4k67D zqGAW3>ycFnr?QXY2eJkaOi$m&zQugX-$>n$Zvh)o8z4`7?atxQV$}I?ju1^KAdo@> zz$cM^_-=xy246T;{@?u~;1^U;#7E2|nv{)Yi0QL%UesH^FO+W`XmfE+E^DO8QY!ktE&8B*P-5Bb*&v(%{9wK=`o$$wa~Z9jIc_4XFdBJ6N2wNEkPD~ z4*eqnNWRJT@>Vj!OaXQ+Z3?Y}uo80#d<*p&vNbe2Xbt`0t@m0juPrtiP#)9X-BSCj zr}1)EO<7eVNu{$M?SE<->fIbjamNIhfnFa8I2_y;*Z?^P>j@|Gvm?q$9A*ipk2``} z!e7UhMNW=M6|kfK7qdyYEfpR=Ieua0{EQO8Bu;4OxsK z!$vd?7Ut`RZyES_bZ(7mVjoqB)2<8sg$i~J<;;HkJ3x(@b#<}>AP?Djuhv2#scl}3v>#=*#eov7%0sENP<0pkAv`VH7U<5r2`^4z*5vW7tLiAkJ@9@R28Bisd z1^fX03~C9H!W)`P_VCxp1T^h3`1Gx&6Q)ttA&&1Ju?=J2?B5f%6_Fg8;0$nuZJU_{ z{RZ4_xM}cvS2(U%pF37M5OO06c+*$N-<4dHFj{yp_6*;`uHamX>gFcLmavb+{4XxZmd0%n zoFmsms-u>Zr#bDKsfaTFzy0L?hvq*O`D%;lh+?Atur1Z{%znl*PtP&!^-lAz@SK6u zL06G-@;k%XCt4vmVyk>Fv!McRTC!NMlnle(JWp1%v3Gm#9oeYQ^ zd{&QSr?;NWP5Ec?oU!insRI^=LGl=AUQn!?O^U; zF6A+!PDOr>dzlasxquxeswMJcxhZ{#`XplJ#nh!qxv@WEED>>0^C-)Sw{h$6m$3j` zD*7Q>1gU`7yeuEUyvFQR_bH%~E$WlDZKAUNI$$FPtG7DqaD|9&zsL6}2n`-^9t@jv zqbNjQ0u;viPcQ>#3Fn)KGk4%7A&252U?cdCfWuX2usf>tzpE!H7OA2X9n#l*iHh?| zuOwamT-{}G>r!o+FokNgy-o_c22x0e2{ca8tG;<{5CqFV;^ zwaY6yx_XAHA=<{i$LcoKQ~6Up(&&^IYFVadR;KN&cbI!v2<3a?9S-^gSrABoJVh=c zreOa^{gW|^okG`AzOiZ1w@At4Uy-MypHe$0X5Mw45uc1W8(B_l2tpk(P`8__zpgDd z4lsQ)VC_v#JK(X$=9R-=!3++!A=kIbY*WblKCAumDbfhjX~pvYqv$Ny+DN-FJejz= zdvJ;uT1u%ab?RGp_wCl*-F@rsx^;J<6n71Acb_ERe1Cw8D=?Y&J?DAu+Y*S5qX+yY zu(z!sVFeQ>9@B15MuUQuRGM4VOPGPo{Wz#}NM-)Kycq@Wx@a@Vic#6#BmzH5YZK|I zcubkU67vi5&eGj_7B45gbc5kmQhU-vq#QdJzYT3gCjjH4bYHXglj*%xuWzSPv`Ta- zI)y4hr&sN5n55gPyjwc<>*U&1r7u6!zMo!FRyODp_dBn8R71Pp*Gq@Dh+2ojbldk$ zXB+Zs8LhPD!#av_yw~n|g*_ih!~CYX*_R31@Z-4E%t=6tSB5(oDzKlklI;BreI4(- zGxU?qPDm4$yH0vo(6nHIr_l8|h>FM@1-8D3S?EXB-}Y}L0XI2t0oyxfNaj=Cx8$VU zvw6cZ2WJ-MUCbSsdN&cu!L?_`wZs%;=jFamc%C}F^Q63`nJF0qv&s{XB(9a8l)mQ1 ziJOF*=;J6ig*}7>#xVh3{8*74^CY1)DJH!nenjkl8R3k%@k>)4#IcRnj;mE)xf-p}{lW)9Mi|a|7+r-IX&f( z3)}#b1K#wz{Y>-;WQt>ip6}C|8-&d%cSoLjR7*CJSM};Kme#ulxKaoao znmd~Nk-3CdD}2r#FT5n4EEGsriTAVi5%?S{;aMaxbUhLuJ_}KRz2IDY8khuTk^aJ8 ziarTDqtAQ?p<&P@=W55Ha0lS2dqBt;Jr7C3|N0+#UYgC8KV)~R7{>*dy+ZO8Pywp(hA<*4I?Mxz>SzhRuGdZ@dk*{ykJ zuMdPwvpuIG9m2ej+kZOH#l!M!cMf(Ov&6U(y&*%Yu_Ra?9%zZTrvh<^@wP$6p^;Hu zjb?*trG3AZtiGsAaqxXjCcdQ{8WZklxU8J+`)ut|d%kptHn%mg*jPetj%(drqgE!U zE&9*qQg5;4q{|BwU_L_WXc@srtS3ca8_vI^?KC>MnoOe4#CfoDSff}&315icXg7)1 z@eh$j_}w^P--NbZ!M?H22Fvkx9d~n zlp`N#CSK!hr@Z7pjhotTQcPw-cIxod6^T8PWGSzcd2mGWgr*QLwo#6=w_JYF?yFq zhoQ0~GHe{7J(Wi$k`7Zh;6-RGe6vh)-}C|9rB?+$TYs=G|hf6{erUf-OzU5H)SnWBuuuCyLEGumZ5 z?lrY%WAb^qDz9JqGtOnw%$R&Q|2Yn|oZX$h9lZ+kkTaP(3w;srbNaG=dVZMG$hnx! z`V&S1xF50ChIAc5u%pS2AC^0wX{LqN0{0Qv{rM_nMf|Z)TneyD}^>13)6B5Y-Lm;)@hcm@lo2MJnDQ=K!-rGdS&`qy9pA8l}>Q z36@g6F-4)6P=LLObq5-Q=)u&oSCCMAh3sUzXR*861+#Z`ENzF0w`ZP=A0t2}hYiyhltYoyA>6BWQmy{fJS~EzBD7)UYtL0JRY^_?+%h zzRteyjwiMofpO3}+j2*4czy7Z`?7DHE8bQd=odOXT1lIk9!Wtet& zo;eW~!I&KB?UaeBtQLA)S}le?$zwE`=S0|7&FQP97LNVp6^!e1uNLZ87C zh>M9S6f$!s^*nbMf34(s?32_uMS5&(dmu*^mlMa!9+~+)?nu(-^!m(=>1(oy9b-Fp z?XV=XpmT0^k0gtHYH~!LDD5KuA`QfLj9;AAA&uUNm#xg{(Dh2!maODhMVFZ8{m>fYmTBvF)gwsGoU~eAVZ)&Oze*N42b0r1gw$MRSMdQn>jcZ64NiQ)z8H z(KxH6zE)ZLOufYTtVygMZM|xv8VZf$Om9{D)ROuS4ZNDbpX=X`)DBb%ejF>?45++>MjXP#jTn2WVqL z>F!3-GNQ<~%`$~ZB`>s+Z9gbmC}S)flY%%D*V~w3LBTfNlkTq3NpuBo1?eEOT(Vf+ zfg|BeR`}&}*-b2oe7CHajpsJViez0lC+TO!mpC%qI^W-tZ@ z>V}w4VvyEh&tti`IS~eOVDPESsO#s%8?jA-N=e(`hHif(Kg+9nlui0P>g}K6c11-m z$G-YpbiFk2KIgZ#cD?#Z_1>mzbD?8n^R9+#&J;LEe!niyw$Of|HQSi&p6PcxH~3h= z&c2VHUCuYw4u;Q;68CTY1dBA(2-@AE@H3*8{tDepyw2&sFQ?CChxwpD#6C>x!lQBi zB96j*Wu>z!z%0aB#x&{?z#Oe6-6Rx89zln3Z&5HZ#q}>#XE|&JmA};`sw)kfns{bT zaHw{*^8jHwodirmTN#__b?9kGIdvLk2kmX8h2aTtYP&4^*~p9UzP4}o5QWNo^xOHo->pg)ZT}Iv(~e&+0ox9ymP&Yiz<)I zQ5CgJ^QAdaYLA`ndK`QjTpj%d97ICl)<8X?DO}(Why1~v5ElW<#iR40T!hwJ68vnt zs!eY?+sv+dQPmVX^X3X_<+b8Jaq7fF zsYg@&S*Oxxq+iU=Z+|QGWb&(w^3>JwS7hFHvyu<;Dwtyu2F8|9KA;atAF}iO7~L>T z#POizXRAc-)=o1l^vEsay~gNN%$!J9u*>_=3&%rHmOx`P0+aa;VHS~Q5aGNNX(eWNIMee!jPxzHEi%vXumXck zo%R0Eg5dqOi;YK}kG02Yuhd;`m|bgG5Fat-uJ?8x5j9b^}N=0jrS`aHnwjqC|g|fNBi62Q4X>kbae`n ze0vbjqY3C2glg7p0)?g$Z;k2A^e{Wbj*yOGSMcWuxuTy^Q5;oXlW;ZhSK^8^XV$fN zUCg4)2`NnZMe)M;Y4Re$c2T~xw*n>a8h zxm@-|d^td;3`ggNPWbOcxWNX$DKN@Qa_0qofhCUL){>wdGMk5)?f^fLpY%%YK=eFR ziZ)hz16+%kseP?203JoG+MAjkp*h|+ZDX4Or_~M{{+h13B>s8Y?T*dieB^g1A0x!& z5>}A%$%n9b@EPs|coxbF{u4d|XCKzVWz>AcL}V3W2WX3ogSNR>d!^>fMzN0AwybrN zzKdo5|7TII$-Z+ioBcXWc$^&U8b(8BBI>9Nv?J!DiReb`NL(uJU&1Y89%@O;QV5IIsJ1( zNnQ=9YJ6L4>vmnCb)~P=_`(o`ri3f?vyJ3%mk8H3!aWqx9Yyv|c6dPo^pEaML)5-V z^Rwbg`I_d0mP0i&n-8jQ8V{+yYi?Lswy0*k_Kk&R2^o6ZYwa)s-Zu%RD||tAj4q6< zM9d2BD|R7=;BGGpN;3$UlVofuf1hN{m)6W(AnA3^%>beI>24$cme(Gzh|m!<2hQjn)-P) zGaElu{i$thnON11AK8yKMK&V(BS;_@(}cf-JwYiTt{`k;Zei`k>j@UdD@Gv&$;jmB zgt@GV>b?F{g*LC}B++vEA^TR~a+YPIOw@VM)@m zgu5x*-`?BO|WlSO&q7~2q698?R*y@ft$ zq%b_$d)(O+2)jW`cZ1M*$kyBV!*tU;$`CLDy3cC1($qq0*xhu#o?A<-xl`M&mQjPL z9b0p?x?^2UZGLrm)s~vURpr$e>PJXdB)umbWzVKv zCCnq~$tx)_boi|WcU0!lUg9Fu1k9y~&AlnebCg*C+gj5r^H}%sK(ftfogPy8z8LQ+ zmCh5kBlW7PG@H-lb0x5<=mT=)08r)B?gDyqnM-jYRwvPyh?UfTyqLdAMJ+ zM?e?;1iVBXM_fRDLEgg7#l9h5CcU72Wc?#JM!iGmEttmnhRlG5&?e&7dPvUwAP{YE z{pGI(&k=q_EU5m>&HM-OZ0aZ<$vTa$0`nML;~XF2#{0WRr+KR#CDCKSzl>GtU5>rR^O`Kv2V=eCyra&a;h=48Rh-Z$K%DOTK~^6Kjdxi7xC0tgE%9|1dWQo{h(A!o-X zh9=|^1S`!49CcADLhIOIEr*7CwiynnvDV>+X4PFyrLoplr$1<_@%#x~H~!F0@QG~g zRcK|Q_M-AhD;&mwEhKlf$(9#pv$NLK+b{G#4o>vFwBHPj@E|q3<{>a&FT3GS{S@6g z_5S+*8p~T$b;sJenEtN2*KGEf5eE#feE|74rx|sQs^)hQbZ07=5Bc@He#{)kF78oQ z4_ZEH7sCM0M}?RW;}B;g<`yAYTrL~Hc_urfh>tm!@Ht5^QUZ7fWD&m*S77>56B$0)LGD!XwiGbytfaf>Rr;;O zN&G`x*dHLe&E3e`B%CRz6}**P;O*xeR4`*FvdA=!qE32%Sc6+3DHor>PbF1I%u+dQ zO?)iXi;Jk4RjkVfcHKY=z3eM*Lc=ltZf#$)MJKAP}RkT%}OBfr+%6>q)N$O4c1opx$My&P? zwHe`i(I{)wDh-^0dfRjsX2cVMOn+N0c-whCIljTCVML&7a7w6OV6x8~X8_|1WN*7|ow3lZpM@Z#*^M!rspt#HyzDAao}W!vs|*s$-v^4^4U_Hxc%u_HccaCD9*IB)$bV3DrhSAr;dOv%De&dnEie!%399sXU)x zGw%`iDL0cnn({B_FinMnu@rFM`7UMxVIJx~%x%hd`VYJnpF{5pcQgutZE%wKSFqF@ zL^OamJRf`qQ2kNeg5)44+U!2+{?BkiOKn+RPpI6~II~4o)v@ukR%>n5Y_e+I%Uxy8 zp7!^a7~OiKUHzeLTHAf)c_mi6$+TIuO!M6y?ih z^t|UqU;b9#CCY&X%%f@_jYVEWe{~pzUhc#0&)mG44ol#V5A7YbFfl@qB5?hBuB6`rciQ- z6J+rP6JbMEgvsHxu`kjl6M3{e+<)j}z;O7@Y7F_jnQolj1~Z|#)~HG965B&MblWiF zZOw}MQ1!qzZ0npFpdnBBNgJaaY{<7?^d55U2#yIUBbR{yx+C}pol5vl8h}s6cO+jX zzCe!xF5yJzzk{>fv0wu5+Wyp35?vKGtAma4zO|OR%A(@&ZG&oF6dy0YS-GQDT%XXE zrK~izHwsMq+`+}65kZk;8zx@c3jH5fn*Wc9VfyLSxTfj%YF9aXxdgg%hH6g@%+mVTUK#ESRy%e& zKcFw+3S8qo)kG{+A4mX#l*hz%h>4MxXdpVnzty=um1YZ# zA810HMlC>^;N0@UaGs-Uq|V)>>)BRpon=mLJ={XH#9BD5O>K21i%|>HW1pMz9Q$mg z-ZI~lNFY*yScIxY^#t-m>kwo}?wMuJ^6A~HtsCu&JomgRr_!~_8*wGL_jti+5Re@h0zh{=tEIC(nyLwqUzOJ}=n5wz) zVG~j_NSoFaXr5^#dS7V@JiibNhzG#6#7DGB`ZJ1x5~cO0r;|@nxvWY27pw!qkYvAt zpzy@81ro|i(9_C<#Ol|@*nTZkh zlb`2w7c7naOFmPO$T`8=MjA&wg}aUyQ6YR1Qz+b%hJS=NMj2pLcmyN>!(p9o zx2-vt6`E!8nC?YonCW)E=N;iGZf^kLzY8q(9&kP}g{@u8`?OBgFUv+dLiI$s$zE(l zwjdkdm<}6|_223`m}j~#H4oO6MBfwePInMywXk{vok1aWEN%;83lIjs07rlv@Gr!B z@F9waF(5{Ti@^n<(VmTFgmaXEr)^Nht1DG>cs4yods&Y%)S7M?1D2b%L*91oPSL#) zJoXOmBF#pQXZYB!_;KtQ!AtS!xHZy$;}@hY$z7AtEpJV)(!r5#_w!GWpbx#?zE9$x zUYl})l3c-r#GcaEe4?n1H;{8#yipip-C}NK7f}||M^O_9(@0@T9Q`q48t*DQ%74Uv z$WjXtf-RI2_(z;3CLcG8xROC+#xh>>PqAn4t_b__P`px>n0^;mLNQ|dAofMDVE^bG z@DcVtVmE3#@d0rIIv2GFGZfecP{a2_aAGM~>vzIu#~0q)u1ijoWvZ2EOfi(`N9m60 zz8O&#rV(dZW_f1#&o;qoSDk5L8Ot?b^WK(a>I$t-m2bRjWZLf7=^mA<&G*?W@(d1k z3EgtF_tHX_AXa21em@{bA7iiNj>7FnUT?eI0yl4x3Nu>1o+x9ORnox@h=g)ObfiQOkVi z8-xfm!ad9rgRQ}S@E!{m<2B@o;8|(|lPwbPRtuiUddnfs7J9s7lHda^#4Q$lmFFlf zB(F`*&k(1cPk56qOWes_h=0L#;paqq2hGtNfqQ;@;DJZypa$-ErIstkSC09nYX-l; zrhTOSWD44^8x!mUz2k$8u76$oLt6qod!cE(=YbtG?lWJrJ#n-+etIW*#i3$9=(`i{ z8b0bC>3$YE7CPX4=X(eJfP~KO`b_UyV^O22+|XE2_PTiKpGm)Y#p9}fH}9+*+t@)n z)wo}^(-1bi*FLv=x96$Jx-w5^=!PvPRE*k0nS+wxyzG;_FGyN=Hw#T^7q}4YjA!6J zM9Js~?g%yl?`oGKy#7+}amRbded}3A7hkR&^n8LaK&!8he8_w9IeS+4nmE%~5lq=Y`+v;`^wfe08FBvHh%N3j9pJvqbEhl-kx#?ki4tcJgp z^9|Id5t>9_5OvKVj_|41D2e#JR(u2=x0HHYkVBFIkAw$aG{!6kcLB(q0W>V;hJ~dNu)2h z3^f;=hU6kv0y)5`NOqWsup!1m$k0sSL1?t!;7;&xY<-=N?fK@%mIwCJ&dqKt#P+R# z5|A7`33(lVit?M8NQ-j%h!(~Y6mL^{w|kX(GUsG&P4Y+Cz?_aLBo3O~9D7>&4C_Q2 zglBmLa0W7yl}EZ1vckse?@@+bX0HoR1V;FVVNYVavon~T_~jC2jGJd-IpxR1ooNSY zk9ZroOW8}r48B{`JAQNOI(a1aS!TD4y7<*`15^G=^eJ}9<|K?s>>?FOPseYNO%plT z8QdQ*^GOYs!q9_3P|v^#{14)4-&Xff;zR6ShtHM()`mved%I=^W(GcaCj@&3b$&(o z3G~`kU|i|Tuq;)PTIXp8tN&7-*S^-Bu?lQwo!fkz&|}9Oc$cv$FhU=r?e5#}X)u<- zZP4X`36X>7Ahaqn6FUNZ09xlqfhN%F`U3Oh=hM#lG|*ReEz1(kj~=D`!gxbx{q$(1 zf4KLzd#Lw%V3j+|cOW_jRR-_38`0e`_fY4sv#`SmC4^&?6C^6Bh>9i0W3NYsVp1Zj z-D!?{zB7Khix#{R?v470tRzh$Sjm0aX?zRSOHUPTmv3f26unDAWMw6^&&=+4Bx_)Y zO&LeymvG}^PBWVcKfn&ylIUQ>eK0K=2P{QTz@or3lm~q>IuBifIvo5Ecnhi!+2Qku z$H>i?_sD;u53xDuhrW-FFz_XcaV`pQQJYAyI0pRy_mQxWF^<$uu#iPTUJKnN*WtPZ zbE09ao?u6Us4t``_|K8+&NKwsU1P}AAWbsuFZEr`K=t!Bs)pWH+q}2tVpBoQ{_-0o z?y?J|9ZQ#0C0Ffl+txhAqOf8;EB#|5f7~~${BWk149}{!z&ilG>6oM3INgTx^mF%f zc6Gk81x-2jEjEK;jL~h=*n{Rd_NNYuqhSs33aOQ|s%EdV_luhy+Xt1<=EM*;I<0 zNvyLs1bZ?9^zP^$m<|*JK?e2=eO8K1GMF_&ER)aY zbH$%xsPQK0Vud%cE_p=U#`tdV99|k%Dw``Gm;Vh@tBnA~*@ZT}lMR)PTk9JGcZ2bS>31Y zX~d5jtm>gX4Nq&4a7MQ`Vw=Bv>wyNnqrv{GF0JXH>$_`E+fcQ_X4jUqCe|Hn+1gxI zHlegPoUFM~TctVY<3q8|Wq}z`s?Q%982aMi*&f0BfcXwfUN6p?t+u|=VLXLoP8=c7*@(A4)k{8# zgOUz0XQcZSjyP;AC+=3PLj04fm;EdG!^ZNeBoE~_!DoI#+}b!B?FeSKl*}C;c@!$8 zmXd0s7YNrW40eg2Z_HF_ZtSVJG{u+LH}bxsT<&=BWr3VmEj}PTCm9%cujpfmdx^tgMu-r54CswRlYfQYgAC^SEa42FYwfrQ}aFdi`@d;`&fj7Ou;3QQ?-FhE0n11^Vp`0{|zazJCNWxfo2PrL%pcpC}o-i!FS-vV^etd_d9qF@k{z*NTuFPJO zye{R5Y?EXT^C}C%ONj4K&*9IcbEM2a+rPzq(Lpy%u?J1Lt?TM;=x(Xb)ZD646 zw9HVwGy3eC)e}`@Z=b;BR;amW2p7tMvvga7<`BmCx2qoz!S46p3ehPin6D$5s9U_} z;zHsUT81Jl|4P1%3h_&cc|NeSEm54E|v25SfRQhk48zVAOT%~Wd~;$Gk!U?dw;U1{ELCaSGGs1BiAHLiYs z3T$P5Z`A1X+v?Q)TL-8_hIz^h+Qaq?Z;K`9{^=X+z8B~b`eGYnnHT8l8)Hp(bocJ| zU_F1lQTR5Z_KtKXI?`>ij%&7VmS5%=*NGs@_Q5$BZom}y4hJt1F~q(hOE8hRk_v@7 z09x){St_oHrj2_UTfo`KSs_+38H_8WGU9UBVxNbh5q6NjV3!j^q;9yEBp$IOI>75d z|A{E92K@&g%W+lTUVq5?*!)NhH2pCAr9qS){+`}4zOnb$J3ntW?rGjs)>!KHVs*~NgYtHG?zM3^#qgC*~6S++MxNMdfDh}I#%S@gv?HBtU<$Uupe}9PQ`x;#t-WQ3*#1TW_3VaRq7=1dO!b34O(M3W%pGw1$9UKHV z7vBlrB-kM*keX+5%!%`a#|aX%hPhD;l#Wwu)lIJ(jtIcuX@^%lpFXOvbYY3AwV> zf+>Qb@o(d^VGC!XqJ`g!^oAs)KOqw6MNBnr2ey%sOE#bifwyQ~q#^XgUl_Rx9`n_B zYw#Ore$RUM8rD8mq08ZnrS~R_opk$XVg-R|rC5gH>JV7tHuYF=v(CD^ey<_q#x|R`OArAm{h@G?tM@b z&0{}eP6I}uxJ;1AAUvmvnRrGeWk1eIArY{^3qKNl7?|X33SEKe)XR`(2@S}%gpO1a zeH;A~r!PI5aYI-t>Bk-@sF6R4xhZAEyonj9XsCb>BoOi4}q(GH*XHZ3FVvx`*JxpCUvfuia0uXt0AhTTcp!J!1{y%zrz(IQyG} z`saDkIDfT+GgpOMaP8K z>KZLO!?zI6Lq9P03CkF>C^$wXZ@Ng%%HeGmACU@VE8>^N{zy2JI3T8HLYr(Rw;6YV zjlo?H61)-rX_$T&8?eHu0bO_pc*LZ(Edv`PeAfC6zs=uw5eR^w|uXkXPlOG~_FPb6aT>O@Q;=S3*db@(>m zV>lEX=`OdufqxdlwJ}8U&i6N<8)zlLHQ@r*ROaol5K_?Qky)WLp_!CZj31Ezs+1w7 ztjBJ}9nTT4T@uW-&^&lZj1V>2GU-3`b^86p5W$4z+V@JI||{UKxLE@ z0iwe2F8|fY^MKHqZDiZ#H-}q}RLqANc(4A9FF{r_lrt-v8(v!S0yk76OpBq8L4@tR zJ=b;AP-F!RQ(I0pPH*|APSU)!bz%*^Zhy;xdVBr%`s9k?WxHx`)}X3hG^ErETQ@7G zYGA>ZbC$MQ|0{R|kz-#D5pfRkNa8B7n*s966Z)jS7k5-_O>fRfj<+V6vOagTq$H(v z%13uSpYm_wk-SM+?GzGWL;Nf04K|x46j?-h%-zfanO$LIo#No-FZd`fiAAGL#^Whd zarM~!gsbS^=qkzz$_6+Gf0*zXJ%fCkia`p{D;NsidAygrN_0*97yTCVI~xV z;P2yB&~}r>EFqOdJWr^At?BQHn}}&BGI}>|F8VRL4|*QF?_Q1EjHqM17jFT&fmtzq zV++yQ_`|Xs9)YAJ%p`6=1;G*Ujjv~9fxFVuF`%(WwI5rSYv-sZ*5Yeb`fd(kQ-bEW z{{ghpEOz;Vr|3I$A+}do3oXP%k(t00^d#^I$RYg3_dxAJFTxO!#h7Z` zH{=SUg#3v;Q;12J5*wS|J8e_~f}g?` z%$JR2Zxcl1CP}`yO*oV{mvxCfkUEw57i%T{2s)jGr2vAbRORZ>fOFdYy$i|lns3-W-4X%d0cBLA3{+MWioJYipQ1mT?Q{0Bfr-@#7i zIZ#gMuuW_|6;499Eq^Q`CWQ3w zY%g)g(I~gwi$<|9UjnVr0MbQ@5zrv`gny$eqLJV+cZKDkzi%+k0$bao|DkRM4*KjExHBy`>>Vwu&BH8+E9cZB|(48~2&68C&$n4I2$YJq7lIdUc=m zr_E)0nqiYcp_!mz8IPIlreQ9Q4RGEIq=o->%ed4=^#n39ds|~ z{d=)FK!K;T`K_b4Mc+E55?8k7=ifzvABTRuuZ%06U7OiFLlXl##g7;~#*^+isKrFH z9R;np5@(%HLBx_eME*mKAjien&<5@BJaQB58(dHQX|}P>D3D3GGO~s^DJ_mU{fGb+rEeYTz4X1nmad$uKapS-Er- zVG^wg?*SP>BTV<9d-r-?TE7@5zBYfEu348EJP?GL2eyXbn=s$w3Y|sX#cxB-!v95C zO@B)M%4E@!NLzW6g$eit_^+aO;=^P-W1M8KB$YjbwNA1?WTajqwC9yE*J1AxzR^xI z&eDFf7IL+MBz7+2vtTrD2c?lRjq`=Ok@1`-6nqjnCFKf)bh&h!!Y{)}Q{fF@g}9Tn zo#ehWCP6NmAjnVMn)aXIvmlzZT8`r1Vt3(XFqrgjq%sb#I=m!FrsVFl%MQcEfM7{|Z1Np!j{~Nd`GnUrgcN^*> znic0n{wBVT-7eNplw=R{HEA;b8}bZH5WWZzyxG9lU@zMuL$;^NaY@svPJq9cats}9 z55lp?Q!a_84+e{(c?P)@kuSb1C)$a1{%gJI5ZZY*rz_Tmbuj(eq2caKe^yu=ofKk4 z9AFnB6WN|3WXc8ec#CAkVx4GftRxo6eZqJq9?coaC}lmPQOMJH?}QxU6XJUDPT_p& zdd4hH7WFZs2X!`fHK4*RLzD;4`xgX$doOtA*^OSYpK2Pdmjs28eA7^85jX*F2t10^ z&}iJZfE@8zSSzIh3nOA#M{yOT2%h4#XV5)U&Dr=L&~LS`xyg0KY;O8TY0%HmBXyVc zc-;}@Qr&IUw7O%Zi<=wjr~Kf34m2dSuKry5<3)vNC@-B@GL7$4$06O4{@3Zr3v>pN+E1iUZ&mHI5={VusW7}=rW9n{x zZ`^0V8}+6I_J!6i?z!GzNEB!awTtcn_J%(C+hBiGM_+gUw=f9Bhj=hi#O>XTYQ*;N z7~Ki@OgzzTbk^cOlm2y%a&KiV6_|o!5f?<|d^hR=O2eE@J`PSs3?#)+kAq{-J(-tT zUvL0%8T}mIMOcqZ2Bjf3dMM(ZN8n0`6hW(jxIrl|9YccSx|f2@b#JP^JXIb}Ox#Y76A*OmhYbRcA3p~fpa>8q8w zN||P4tG;cAIo>~4f5|Z_JQiBz?dI#?yU)h_~s>Y+nsIpJp%WZ?DTR zb_=ftpIS%`C-ytZ4NsKD(bh8lM6P1%m}ribdWGfTPUEF9-xF%#-|Z?A8TAp1u+PI{ z;5$fdGgh~A#0-qD zl^+ssj^!xOu-68X1Ox~^$bmR{%qqql>Iqs;N)f3$2}^DyH&W#6QS>FetvnjiH4U;hxK=u`aQa#hUE-N&pAs1td}>J4 z}*rS=!@HP$rOZXdk+^LV^*AOpV~p2MY6uh5;LiNPZ33Bny;p~sEb z4Q+A`x5owN2M1fnn$=J#xXjev`WOr1i(JgW42%an9ohz+KrBM{4_8O4iT|VMEZmz` z+c?}LZBut|*SWwLGKLT5;O_3u4i3ZZ;O@@B-QC^cz=n-6U)`HpnzTv#<@*cT>uRpI zZ=UD(yYHo)Hc-~kXiY8$|E8X3#I3??}A6@9)^yP;1}R=@OgX+F%_zy z*q`SkQ+=fKa!`x(adJKPsH}Hgq{evy>lWQ@s;PR5mtz$bl~s#zezd|UvVSM$#_HRz zT297F;~~SQntN0tXQAP!jm@s$ySzl`t9Y*T2ettHAXzQQ^(?Y4f)ep74w-MhuZjCR zo&#QX#$Epa6C!V27wi~9r>@&2HUC-fIPO%@s|R?ldyA`)>Vxja_FGl;Dn?qK*w&R* zR-m3x@P^@*eJZN+ul1bpj<#nR`JQRcwN<++XqJ0b>ncap3QO~T{bjrBdQ>{Brimxr zoo6421l6z=iO0ictTBxr8%YkS61bEsE7@NY`Cmq}Zh?k{1Yf zK^6QMFrFMsopvy`8A|0fkJO{B6z>sEV6QfcdI&$UOL9`9O5Yd0^z50oN6Na<_jwT9F15AHE;b!2RI7$ zK)o+E4^0i%XQVPl;u9%$$h!EZ=wpf;V2mahht8dFX|j9C zo05l%)cjleEh>Ut#3&WC;pEYJ#J%hZyh_l-Iw9D?zbTk2-NC8=Qf2899@(1E2uJb{ z$5h}p-fiwI#Yc;W(9J@#+KY3<+amYke~E}9zZGpnfk=m+UhWjSvpzl(a8`nnJl z|I*kJ(#0x~Hnmq~g0Q_HBi*Mf=1gOplg#Eci`R{eV}4;S5C0qPNIA~0V?Dz>cna7m zcoCUE>_?gIqjqg*bZD0CkF`bE7ddJD$DxUbfF8cl(N^F>uo!5>tcJ>%P1tjIA@&IF zYSDdpUDg&_4^=m1Bg`H6Ecsio0b2ol=U0m7v5!*a1HPsgcPzYI(_1x$mJnSbVlYRC zoxwVh#oqY=++S>Unr;UtVE@{e`YU6PSks7l%*)a#dWN7x@+Rd)N*mcc`7!-2^(i?j zTdZiOsFp31b5u#1VTz$jKr>3gRQjZ4B7$n^H((>|=e%6za^@qETw0GE5!(fJ zak+Sq?2;T)IaMDLB-%XPzQl*RLt4HjLDfo1s1B&U2|(U)Ws*FV-%mn_l%m1Pxax?w zOuARThZB*#7RP8JVlKBOLrL8kt7vKQ-QX)|6D@=B2`G+h*(3O?;+=qx;sx>qDs8b> z`9Z0ow;<2TP6{T5)_EcJ5Qf|3@bm|J(~|wg{x(t)5b7`;2SH_!Wx3QVyjN>L!-|O*D45WLH2lx7W z+j`gD^UiVWDbJma;uz7Z4jKB{7TPl?-dSH~nY*P!K}{f4_zhw`&kLOuchgPFEZ2X@ z%Fc!|Pvv~c_9V4P@TIp;YNorQZJ_I{s;e0JLDnwiD+8}th3igTAM3RKX9PQAS-{)W6}N8DC|hz|1&4M_0TL6`rOH{YvrJaU#h z+M0V9Zg|!PZyR@5AK`tXr(6q=f^ap$^Lr7KqpSV4N9?}i^7fksL0GwLo^Gg{-Z@4McC+ zEHTL)2$a(F$ z;I}R_E_6z~Bg5+h!|{XhuFOqQbu^z1GJWB{g5zmJscZ<}*B0xH>3s(g0|Cq#KBM_rhhtjm!v)X&%Q#HG~cYn*(QDk-tM z^e+iL^|I=Uya9i}w>i8!yo=ZoT|^pb8z^?> zQ_{-33M27!$P44}AjW*~G(3WSKJv!bFa8++?aXm@3{CYHAT`nEzB&HU&>hCNz_);m zz6+QZs23bW8^&ma4vk(A8ngr$;c7DuW&bDJsxxPS$@f$5rVr9IP*tY?n?9OKku^_~ zCihi(gh9(LYA~paE8BLlEmk5f55ZoC!)O>JbGeiTyPlUEBr1vG-PHqV;O=2`~#S~p^q-g z21xr!dtsSPv2yoQ2b6pao%(o+UI8Yp!&3mgZ0`|c46i><(b~CtG`$8h8sqj)xfB1?&?*13<&IX-D zHYG(}gRI@GF!v^FrG24m9#hD;;9cT>4{d~=_y_prfjO}c-hrOy=vX($?RI~%5!TK~ z8~&zC=|#CgY+1iEnP~8s5Z@`@`sGG|RW# z{WaVfTjd<1f*AH2iS`?vu=A9)fTA3a5mj4Z_-)9%rCghykAEEX>{N{by9tP|CV zSCef;34*iOHUC1^aPX)5r*kPWK0Li%C+}GADt}M^p)e0sMfQWgx$A%&mP;a0Ch|Lo+{zseZr_4X4=N)Tz_vz{Nt}zNko&hVDDsm`4ZU1u+q9y+1BECJ}rSUjnSKy5KjReSf^;mKttbQ=Vtc< z`)u1QtIE3CJl6KwzSZ>5lZPl$xY!*c|B!7^;L-} z%*t-^TxqW8rFgM$osjyTqK}f}iVWRjSzpD|#AEuAiVEp;`8Q5C-U?_Ov<~b-JiyDD z?RZn8uVTdlD;ERifGwD{wB5if+J#tdd_GVFzKBbynRP7oJTfdipLj)W6dz+R$>-qK z*i-r$Rvp1(R-C;+R4BZ}qSFs>C3F*Q5Y0h`u>;^7ctB`+K*jGb-WWI>%9bdlrP!Vr zCY!1Rm;ishMy>rRIUsGPR0y+0Z`h3)Ly0Wt9@!f08+s9W7R?K`M!pa~BVuPi>n3zk zU@+A~Sm56u*l+*pxfW7kgF-9G+0n+pCO`|mX5_H@$Ja*3b0)DLNAAa3vBtrxp{~pw z%$;;MT?7=-?o%y*k9boY2|B{h(HT^!u77BOzlE*Bbj-ciN!0YIsc^kU3Jqs0RpIWm z*;K!5KC2P0GyZ_E3f_vUX+4?qBvWKxxdu^zqOo$FyrpuPa+0F4YME+|bco=FvY}!Q zw+-ipe46|QhryjLZz6BY*#hfjH^pAYTjohoW64E!4ZjK1LmEwSAg@q%`hO#ztN;qaLu9 zoEuBP_C|V#>xae!MuoT(ATWuD5dY9E^cJ`!AP0NLws{V?+D8UsS;%?J7I{liAnLKyyidXd@DavbeoIyp z28~q?4FK2huZXTd8yHh0uOzGBH>`G&G2%h2JM^ofvx1^{A%2h(WsL9-bKL+}#@E~V z_PwN^SZ}X&tR|nuR=B>nwX|dLTONV;dh`;?_9)y9{XB2BTj8nWY44qeJPVxhcJXXO z%fkcROm7!#8@@OE6XL}MtmBf(q$0{z&^~)XgAqT8hFM|Elq z+J1_kil4dy$`?FLvq7;`I9b&~x{)1XCJEN_VE8igjG%#d9n^`y#Uq9D10v^ePIGz_ z+f`dR%@H5zEOArxduXJ0Ga`gKVaxf&ko*YOnCwP&La&TUpeL_+u z8n4JvUZ9$V6BTvkTFGkBcXnSfA;A~~qeRA*L#*Ab`{I8&^%w_9L#z(=(AUYSME}8Z z>}H2BUJTp43&K~#5&0TmG<;I=P6l%pvo}hfixc6m^a^R3jLpE9$Ak}+v0mfoc z8JU2VVTI^4*Ey5QGt#oHMp%2U_HHd|I%dbrC9Vd}G-ow}2ZHuzwgKqqaKzfcdI632 zdsrFvCEi+huG{RlQ)%2z_#kLPl%#*;PLa5|i-pS-PnGWke{qBIB54BC2X&M*7qz3; z(2wvD&R6I-z<{qol334Z3ebqw5buKB1V}~(zKQtBYav_>PGbDSo5;9LA4B_13=L*Q z_E7YO%Am{lZ?HDnhS50MmHtSWtsNx1o^T*(NJ@(gsP3#}X(G4I$n*joroNOkOFKcm zQ*}e_RK*pDoUPib7^&!`T26Tz$~9|r{rE+k54r_9DSIcYMDs|wl6{W7Kzd2wgPYTj zu*SsRkq7;2gTJZCiOh7*(6h3*2Crt9zbG42^R1>wdFRTRH9c!()dki67<0{$stGkQ z^Jwcev)DV#c_J_-vInXk-@pmMhZsAhccd@DfskJ~jn|YlQ`ngIK{!c1Nj6O0TG>wY zh|@~3S@MXkj_Y|#p&(utUxdB)---N3enQ^*YH2EJj_@ed6G#B+29NlTfNvP5y+^#2 zY?g3|zXbP*Kg!P2Qs7_8<{CS1jR>c_UrI@ul$(&R9VtC2d9M~~@+2(jhlIIF66GfC zSG`8rFyV^28yAnC6PL3thKGjN0lR4^;bt1>iGp?#LU&8uI{j(J@Va>o2jyjEkIJ5v zN6WpIV{L3}(5TU{rd7F{8b506u5(o1vEi&bPvjJ*ENQILFOrMDh$jnh;SAm)ewfdJ z57Bgj75rkdIpO5dcpoFJuzZe<`NVh4c{fI)_pNypZz$-SX8+2k8 zpB5gv2kBybReQua(pKLTwN14SuyH+H-(Gt?$93eR*JZ0~l?L*NQT8>6kNs5{iymdw zPrjW>la$J*CoWZ`OLlU6;@vz0@DdNQ{)RUMvXEh{x9rotEukDvUCy}3`}jxBK5kn^ zI(&mSg2#qmGZ?Hc@sUt4{?q@~DW=@4x%Rt`nUO8gk)E%9l-Nk7g;t=$$^GP)@Vuxq z21DCHl~BYvB}-CG)um`>Cg^qZ)jhOd6cbe6b#0_0Wv^43W=>FD*Q)B=%FIdVn6M$a zt~ym)q8Kln%+cNV>#@A{X%}(uyBuZ^Pz?2eO0gAz=qvNuP4^f%LgYYas5ABJqjee(mtRq5~1A}}{KigkLk^9EEh8Mn3ffvR}Hac2?gGeEs8UrZ1 zTZJH%dsA{!_EH&CNpx4$K`mVuPzjURsYdDFqBp7IDJObIzB}ny(jLK7$*SbPQ!!bZ zB9I=-02L!-kJ3hK4~t6ShQiBWF?l`k2p@$WbbYpKu>Yb)N3QomG!c96>*4Pk81B1_ z%=8jLR`e)R6c_*|vOTy5>>|h(kLABotdP)TUG%Kv--3c=zjGmbeq=g~B3{ z^7o4$a6#4q#%ef&i8HRUcELEekh6>1TZGCU@)ik#>NEP!RIg5yQl1i4EY#?eXC#u^ zI-2JC`?~hhW4tYDr~D#I$$lgmDvok<`K6-0g5I1}jArb*jAt}nj7jZa22d?qjJb+a z8v7c%$2-d%N&FjL2LA+B`9cZ)K(s z`-my5E1cQX4E7kOgt;uf0V|CU4XZrEj2)fL4dm}H-{=)x%eH)Fef3owG`uYO_XlcX zm@Oqc%4V4I&8=#h+h*D3d2PPuBoA#J9m?QxHdD8{HQY3A4$+bzIsN$~<7XJ_B;{%k zk0wQu>Sf$f)KzZJ`j(la9IW~;eM0I(%{A@rqz1Z(dX7RMZz;MguEVR~m2j#V^!O$g zK<^gb<_DuuKj!J+Z0QPFJD6XUZ!rz58C_EESHr4hRo0T3eAFz+M%WN`OGn_ zm#~4=kNrC)4t|7EBW)dzO-xUPah0jFRaY&oIpxqfpPM4qc8*-fM*C@p)d_g(yHEJW zc^A9f0aIY4^@l<4ABNno*;_lgG`Rhg9UrQv-(DISd`P=p8})wf@SRnhDbrC&=8!nS$oNPaXQ;o}%1i&q5x z%~o^kGZHyh7+qotOdSuShr&A|@BA@ehghe$Kky>-6N|V92RzO`#`$EU%!u=hv#Sg9eZ$g`ico)`f^EWUuyw*+f*B#mZ{)Osvym;n*^J4|Y2k&m zg`Cc!`JC&LW%5#`Q29XdUfznL4t){zfvNb5q_h2ea+T19W>uFq8tc zke*lV5>;yH33n0&=@07ePQIM-wqAC2_vB6q!!vVJuFD7Vd+HEH9;+GqnG}{y7PzEW z70*={6r<&xRfl9o(HUVU0nXhfIjC~*?UIIiDAA{Uq54Ppm{%g6k5NBxpS@UI%<4}iTq2^0;sWt%K?-kxa3$v=yOLP|+{T7ey~t{Bu{Afe z&sS61tj6RwhbNkLIfs)CX}|m`^j%y>GD9I>x5(dw0+|!UA*f*Gp1LKMEhIDkW>h9n>tbO1@1$LvL2owNce3@f2l9{DaHnbQ7ErRC8wwM~j!s zM6wGik8+*%lD;gpBIzjgPP(Grpn4?@T{*0r%*Nvy8?&&K!Hst2wAW2hw5_8`ZzRbR zw@Ri=A<~|T*P08;W{OI&N;Y1|=Dd$LN%izH(k>2vAhP}1KV^2gh_hZ$W|3tU>U z@pq+-Y5q`h>(5RzX5UriG&Mm=!ym1P^-Z)j`N`bh(2!V)@v84tTYYAC4`VMI%iYj( z-X%bcUMKQ6_)lc5uYTYq_@0*+){)&6ixW;lr`e8_W@%f5rQ&s|Ymy4YbNFjDokY2e zwD2-kXHe+oSf#OX(Jf}!Ix#XcdfGnK)sOrW6T5ltYZL<}&$Z2whBorAwZZnD$aTc# zOhrZn>V#86yCUl&MG=4eDsUCA#fAbGX}2P?<4ouldoUd4+GRA|6dsLzn&P&Hp^mf_ z3bSAVIGy!|#}>>G9aY7|^OU#sx0Alwb%jjIJlQ2Ob1&#gby(eTD8p#Nfy;`(nEj>xzGN)_P7wyTleE zXT4qG77}yzbbP`OqodtW$c(xo(s(v|1#K1M9#_Je%c!B9ijn>-tf9NuhSjt-t}1U| z-K=^qbv6sD^D19e9j)r|XWFkG<(*2{zaLlZDA8B2Oj{krruv?%-a7s!SS+?6pbtc# zY({JUB42N?E*bScbibyAO7omz=SXKW`#?{1XqscF_Z~EiAIHtW0LdruFy?XQVtzJj z7(EDdXU*evrA&+WC1X{qByH5+G`E!pb$!+K#oalx#Y0)6m_FtKir+2f4C994dY}mI zPpctEp+Nfn(cZEBbTpcT2a$->$4<&0LCZnrR*2z85`5w)PhUdjUe`;BXd^ z#XbS|1tvoM z4^>+BJ11i&qwhVtJR>MN;%et9$Iq}he9ZkKFgdcARv0OWH)W=<6|}R*DWoP8gv|h19lAKbV`BIv#sIF6+Ff^prb7kYT#a5{j@x4zHT5Z=UdjA);JfrUj-KU_MnAW>*(9aWQr2~J+6*D zCWCYaZ+3ha)I=&$XR%2^mjspGE?cVHq@SAjUDaFNmtsZCQngXsP5zv;QF2LGn)p%Q zL2z6!Il-mfBpfZ;rtYP9EuK!DZY<7Vk(cux+!}ogos0Ug)!1?D6jp_~u^9d?Ivwka zJ|nYekNxM}Z)ii}4{a;WBZ+A^U>WLMOHG_FA!8`UVNraQe-bj2M6sW~5ZV&0!Df>J z=uoT<8VTt0K;-mb7qJ>!l{0pqDWtoFg;O_b-a#I|5C5Y+Lrz-@mx}a)V$=9M7g#? z&(-vmE#Xy2$8jx;DPRoW;hlW72nM;IiXco=&DbY-@H zjPP}MC%p+L$eI<^`D0)py3Kyn)H>M61DoeN*17&hnBG<1oKRcpxmLSVLMx~S(&K0j zvLxt-4@naVh+)xgPn^%YAnKO5Ghv?ik1(P=p|XeDN1>Ux?s6<$Hu>azwLHaFL&;>7n`|m@KYT-c;?C)|E9%O7Sar2DpWr$Ji5lL|Wp{$x6~hI*IuNwOS2#j?NE%^K^1Bd^PSO+Yb9O_ZaUO z2gkn3*T_H2Tx_%>yAZ4SlB>e+!^WZ-Z~zDjC&O`;Q&u2PX8p$ui|PEM@KjzZ$IV?P zo+_&&nkQ{7tE8HFHnE-CiIK?1nK#LgXtVemRO{>LD)zv(Vsp=$ZZ*fs0%dJ}10}bA zkR^(;j9-yI88xW!xnY#O$n=k4ntO=nT~*Pa1@2FdS-;5=nyt0@;_n-!PYk@;bARrY zU#ppEh*YgNW?Goe&-R4~f?P%)paY0Wk;O#USPEs>NQ~Ve+C~S)kJI`@&J~W5FmoqDt94TVmfs@b-KbzH= z)6x6D^PKmuaD;C^3P^TKI*{+cr6LPAgW-ZS?AdTN@DJ?+<2ST0{x()gTNUXSdrUe0 zx;j_lQv#O^XUd*BZrA?v?fvIhrKX?d9|}LE{`_2m6rU)2Rq@-@#@f-d#VbOG`Zb}} zRDZq#yBZS#b(wtDF~JwURXRzsT{2QtsTPZ*oc~n2W#=e|(-lEE+!&u8=7FbU6HtTi z6oFwP=LKWEz&B@l)z69Mc6~)`=sW{-81zu`{%O;tEj_RKS?cZWkW|b&TB% zX1OEiF{Hvi)A`#a@I(XsVp-T~#tzn2acgORy+k8T&CU3nZOLhpr)-p%ce`n*@qbO~ ztLcYX~qt|`k0~dW|E{`oAT@v?DIdC_ty>1fUML)%}y1J}clAByf>UJF;x)XaV%M^DY z?~~hweFfRE_QX~0S7v&U+K)w1U#dCVwA<0b*4jQH*uuFZaFl37>mJ!g9*Yf(3@1d` z@=%^{xc`*1F;X8{U~6x!_IB_zwK^;ZoQGUHOu5EWzT!xp>7(s$c%LlM*CKi#xin(} zObQldzDT<){Y&0A$*fr|Z7%pM>CJ5gW#Grb33vgr*D)XIWIJbVK;3|0(_%*>m<r zJl9?54jXS(3!N3_L6wD-3ysT6eQOq)U)!2{PdU^5X{e8w5j+{pjz?noq2+k%SRSnf zW31T4l1Po(v?QxeoLZ)vBpaLR(jR8^hxCdrqMKkP!^ksonY?02u3(__nev$Oj9Q|d zA+M5rQKiey3EQym^1nk%fF#E^eqf|qwiMgG9fn9H*S>M?X z+DF(@982BQ;?AjcE{Uun3moI@1lgTvXggvZkE^gpwregBPbK#T21NVPUEE*5VZb2% zS3E0v17Y!Wz$kN3#acD38gup! zCK|G>_GlfTo%?C%WTYA?tZ3}QBg^SK9@!x$Za1h9T=InfVYLQ%p(e!JhxjB;C}(}*jg zS>oM{H5`+$7r!BwfEV-j3t;+xV6}LO*hha0$GE3}JFJV0siEJFdod~c*`TkT>Z~!Z zHH3v3G!%t6FJ=QO*`>vAMI|8vc7{C4hkZneE|CfhZZ8tX6f z6?1|6PVl}h*Rw9#p0*-*HlhSN#9qW1v>wsp_-!&F(kJp)tb6!bcqiy!)FqyRr{F_u zCu^}_9dEmMl5~-huE9?C0nxv+FOPSR8 zdjoNLk1TU`e)^!SRq4(2U6nVJyCqJPREi`?`%`*Je<_xv?oL{)nl0a|`6ww6sF*D| zotfWBD!h{5|jzsKIEFogl!N8J$e#vg)#{`rV|d|4c2JE?uiQ+SiOr7~S`f@0V0 zN(ig6HP5w|6_ZrWWILowr41x5$ppm!O$)^{%`fdv1+4$5eb2iOAkt#?R_thCFAc?q zQyv&MT8MXJNO-;&htXa%T=Jcx7j=>Lk-~}&>W9*6@*HikE=}cBPt-3?oTAQBWG0PD ztQ6N36erZz>9|Jbzv?H_1C);l7EEB*kaGx>sf7Cw3rP!0%T13-$p1LgSSAWl5%m_u}2{L!PN=(qJ9kS)oc z>uOBhhOWB?d(I;7Je9~{G@bMYd}tQE4X1m=Pe%BE3kcdIu!L8{xe4@-UuKz@Pa>}1 zPR1JOh&RDCnnsz=sQv1G>}O!R{kp~Od1r5GXj=Km(#$-ie0N2ysj>M}%}UD)%U64; z`%>VWr(^ILzA}!7{n#<+9OGs9DfW@6V~2_BkWRpn&*j|b_ttey-oQ4}#K|0;3OgGZ zBv*?@heV`<|B#V;H;nb=eEzrPx*A4cdcx8h&^uxug`6ript8a)daD z{pauK8yh_4YvU0)4vQ0qIk_UNkb8oB3y~sVnLAnpP2~Q87JwVMDu-x!Z+)Jow zcL?f>fhaBf_2n zL_z!$UFp5;?1irm{$(L+dw6i$yxQ;PAynUSr2AU%u~&?pr3$<+;t!zHZl&op&^+3= z5-yt_nCwdabMwzp%R7g8X&tGx%HaMAnzS92z8EAgBVw09z=M+yoWOD>AQa5xXB}yJ#7E z5wioW8Sntl!YBCOhpMQg8PC<8NT6{kujm<|4Col18Sw$Tz#qiA*i>dYFCU09Moaw) zFL#*eyxhS5A^s^C#aJ1e&3VK8C-Mzr)7JoH;km)iu|C*x?>@(H|4R2^>rZP#XA9R@ zXV*YGWE(aRA4^8!)%2>k3_J+WWj%x`a})b--b(e6q;&C6Ig&gnp}T@9eJh>L8_fMo zp9=p)55|vD1O+p>m$(xVhT6Ku1sA$-%`M$4u}2tpo3D^<0I4y@93f$!=w!O`w39Bg;baNUsDeot}pT0S*x9EVNFk^e2`JxrF zhuL%L_E8;E&q%wh=%Ab|+{j))La;KnD3stojb{4bK%?+tkJWoJf|0v}52GS*EbArx zli-c`Z>3jrF?o!pndVEHgmOFmt578sYp*NMYQC$-YZoT8*BcU)iGy_&Dvf@yHebG7 z=2MWfF20nr5w>#{5*+aGW;5S zJ*SfT@8t`7isr>pAfNx8c^BM6+ei!uzQr+L4|hvj1IKBj#&W@OsJgTYw?44v)F_SZ zTv^`d)LF98_kkiArg?_=%|4sEje9NCQ!I3sdyO$aOB8w%(~Bm{o4{QKA60)eq-3PR zl(070q!A`vOM^3Zr{~uBn06tlZr!F?ManM1%gJXoUbr6piZmqnL@#IE;roPj#QDmR z%Aj7SeWt6I-ZAS)0+2jC>wMOpv}+kt>h`FYlCd$VuD?Z8krJ653 z#Vn!AxiQ92@J>7r2*mVy%Br~wrXd*d-XdetAv+#q#Lib|lE6-0ys>|bj?K!{VYa`EhihC~HQ$C9 zN-K{VhSsb%_?^w8uWZgh8Z%L_k}PA~k^)MCH$$>P`9L;K_DYK856WrB6TcX05q zHyfRcKEVk5IZ;D2XAA<`akKf=(xLKbLbmd@d~b>^IVv1L0i32y;$31TK_#q( ztZuyXVu=!wozW~J;%^dv1y4X1QWlxZw_i|U-{BE6d^k2wr$?Qs)4w3l_D z8T31R11Yz=(%;yZZD1Jsdkfv?Of~lB9=CrPf`_hS-N|;?$&ff^#L|2nJwe}jm(6|2*spKGwI`J0kirI^5OGR)#$a z^f6yEE%sb-wz8aX(pFZ2oVBI=I5i~kd=i)+K9BNmF}GY4yp)roYAPN(jZ znK6uZ5I9Q;qO(8^oecL!U&6`!BjKjR-_kmAIy8hM%ft?lC89I%^v+gnD8W2>nNrX?1@Q)|0d zpF$cs_ZlWRhd9^!@bDR!MO3hR3VTR$#k-}S#SMfxl5T>g+@W+Q>jABP>_+%9e%POY zM66F76AdG4PgJ}wpY%Je0<0SJJLwO%)@15l-mfxbpXH+0UNaqZuW@s1xsDdDLPwgT zudTN|&yixeZSlCi`SKh&ND#XPw8v_I^}Mj8l($TLOTJuIDf-CmBl?fZ@Y!Pp&@S2= zVk9|^Rzv+O9)o7W{RDI1RPJ!;J7s(RHeo&OpoBA$_KGh0ExIG>F}fCt3~oCOEbUGX zKx*M{(R=1X!)5P&JKfmXy27Hiy4+nt6P;`QZ({eEgGmSDrC^~v#P2KHqWMezOvTXQ z$&1sDCjLrkpD{Uu%(zi^QQF1CZP_0)=4!6UiG=M^vE-Ie#?4`73OkCYG9>I((&bVX z|Fj^T%7T*I9gM$dkEvwyLUa^Xjg1baU>%}P@+R?-wk!UK*Z?}?*3fj9FmlQ-H}pXAC`qQXvmDy+gTshaEcL7xPew|zAF9{R|&4dUQ;jNf^1s{pUv>P(F@+?%uJf)zR z(ySwJb75;<3ZnoR$=SzxLYzaB;N}doe+5zi-351e$0De+&&j0TG7B4?x};$wN^b=(8J?C8wM$xzQ&v)Fe=DhrUE5PsCn)3!*?O@EiY zI{kcRZo_b+30ciEH#RD3a4YRq^5&dw*{2hGCT_12%zTr4Aa!GUz0|_g8Og(wn(6fv zlUR_@TGvG3kQ~-5RNmkpWDF2*fy*e0Lshhmcb#XjkL_&eK8FQqr-C!dN6dDx8+yrb z1F{GJ)<*yMOFcJ2SA0u6Oym->*eCS#wAFeiIG)ymRa)bxN*&cuj8#xANB=$2=@19+ zGC`h*;Dbp*RMd>sgpWwx%1?+N$PTNUB|KF)m9_e^1c|C#@l3l@ohau@Q2l z(fQn#lEs1q)k9flQGI=yt}km3ZG_^xkVAZp{@^@^12hBNi}{h+lV2kk53gYMnRlk@X}@hND>g8abLgNEg6OBA@&|`Yhs+Yl6KS z#cMP;n7%e>Al^K>l=e5DDZ2`I;>W3OZY{x%zTwPgjv}9eWz1^s57u5jDQ>7}FTBb( zDi+EnvzkCFg}=G^F-aty?PD%NJ;*_NN$jyB$8-xF?s8XNFS}K1`ZJ+|X=0ZCs7Ruy zpb^6qTgyN}Xfc&VevOu+EzlRlk=+qje_z`@6!Xk3yZCd7 zb$9jh;=aXmN|L^9_#XZB>g(O2V}E*927a6=A744Q;zsqVnqHN6Y6UekDbnD0GwDiIGNEkau-Gld4_+!S$26TLO@m}Zy=)QJ>!`k_dBVGq{Wz*p~C zU{iFvcd<7a*I>K71ASAl{K((vOJH*BB0QKkSH4VCs9K}>su3l8NZ6z@%jf96YTL*s zC>rWAbphpb^#={5_S3!7)t4zHJ9OK1lf_pg3lcWzo5&@~+Jpz1#q!mnIdYjOoqY%R z#!KLRqRy-~{K0%x+yx}?p0Z%b0$c?96q)3fiEZ9v{V(v@_Qe|{7Skbg4Y7}1%r%3(SlxMbco(>Q?m})$YNPlN zSjmu4>5mIby-uqwL@x&%V&bu+=rvOGf<=8oWoI z=d>3&p&qQpa)bILS0Q|-_h+=0cGkvn8s_#%O{-&Rw5r~Sy2^|NNlWDyHFVJu-hc2M zI0-Vri#gAr{;-+_G%DRd+3xrmjWb=DVCIXA zrgak<{G!g${<-~fFYB$^?D{t|qDojiC1IZA1ot`Intz=84>Jk=!^;qA;6#un;&UHI zk^);mX(ZQUa(4@LLJR$c;r8TeXkqj+xeqR7<;4b*CU`g_jVLDUz$scmyc^gE7!Do) z^J4!1eTb{Ua`y(`75f?ceA_zHNJGB8p=*%AW6&dALt9OYZG)p>;H7snz7hVyA;C%P z^PH)yK`atHN0-w^M+<^miKmfuNRe+(t`a6=v2!>)y!u=6)%O= zFP2LD134)}(-Z7AA&E=~P4#laYyC{uAIEUyyO-mNd72?&-;CfcTp9R*RuY$qWzn^< z?zlC$I)+BKA)DPR!p^`4J4xjyUb<4MyO&O|zcNcoHkNEP4Kdv*RhJJlE~t55kxO&?RB+EA;t#H&9W7_RaD;nsXl z)6mfn5$K9<50Kt&#QEqm*H(uuyv6s~e#Qp5C)ks1^&Jy!6P>ety&{K##pE1l2WKwh z6>GF$r;rA}20jbxic+E*v5R81Y$mQI3lvRNb18qsS(QzBg#JH@&N8rR^>4#X+carY zcb#uADa2|*Mx<&0Q?8(!np!fi^nTQi5e;9Ydyv>+UYt@+NM;LasG5o>BZcb&gu80P0w0r ztYhTY1Z%W2{HHf%I!t{1L0v7~OtqKsK^@an>eRZ8DwpoFYOAC(Z@b9OItdH_0Ah2z z5%(ALiLA$ZD42+dI4#-R;3b@SiAAw9iDZ0!;D-B2v@aTU{&aN;hXOO){ahn_-91tJ z=<45|y}^yuwOqTfL=p|CViM58Z%A0F-{M}f8?5)-p7J*G#(cBzhxC}Jk$5(uLgw=! zNWpPI%fOnzN7gQO9eOHI4E#r3!3laFxgoYE@+7(<_%hTe{MttaK1Ub>L^MhNy&ZZl}tk=NpZZ6TEpkjl5PO104jN zq4;h|wJSU>u&C;fs@{QiVS{y$a~(D=0SB+6+t_nCf5*;6rvo*U&m$$F`Q#0JZIJeD zi}#2YxsKbWFez!1b&XYN?NxcsvD5z#V@F(xu~;MARl(*w3GyXYkvK2R7t(Ak?;%ox zOy@NQTZ%a{2S>^spct&|2{wk-$YF6Be2bUEJ4lzX?&DVc6?!-{z{wUZf zyatX1R|4kbE&ODXlW2k|VoNC(NumwHzi>}9>MgUM3YK`DSaK{z_dwqZtJ>Zxv@BBX z6nXnZSm9vcLbM{37VAtrO0Jg= zmROz0qxnED{6k<;az<>sbk{Zf$!|M@t&BL-GMzT5)M6LNR$WA>qK12Q!Ha0VRNK2 zkOd4Sat&_|`$`b@OlH*s>N+_tlIb_4duIebbJud>p}fdYU>9A8){XyUiMi}#Bd{xU zk>3b8CcY-vB*>ADmtEl3hDR#Cs9NwAaQkU?s-^5nG%hnEjS^3(ro1(rfypw~GOh*6 z;!FnKBRWJ*EsgdAw^BEP{en->Na$g7Z*n8{9rzO#N(+Q{6~mNl)lpSKmMbq6jTQdn z&L7BR^mM zdi?#bZ~QO4zy9x=>GR?*`+ux1YV%`P@wMOC<^9ZR_hL&cmo!q3K*IY8O>!`u!LqWJ zFd46oiRQQzydW@RRm4NtWCOzPE#8#gCi`C|NjNFTlU1eHXNVvW!sHO155Eq zwb?LR|5CeN*G#j3F|ee|W8w}B`M zO%L^_B;3EqE!@FElQLgqQnk`^Q;YP4X};9vsc6=d8VgMi^v!E-$$qDqr=n9kXm=^^ zDME^)vK|TtLyLYYpDG(G8l#vf{ldQp0mvTiBzUc`oX(=}C_n0pxF>{`l%;8~QmlKF z64F)bMyr?0S_*!NZ^G?4+Qc?aQ~EGQhcn5!vAO>Lxeo+?dz3aqRe|GbHCc9{Vzu>a zbz|FMf0d(_w>u89KZcsdZ}G-JR}#m8r{GKun_ZJt&YG4yNY#xGr554YC@**tTM}F3 z2Lj`x5c)3oI#egJAVLHxy${f)n3>55HzHaj5WgR7&g|ZHCmV7V;4Pk&Hx{19Z!ejL z)KOF@OPM!dMphf+c|&gQy4*C~VCA0d)27XmWr7}>zvUC5eo%_^h4c}hCH^Vjtiq*3 zv|nVPbiJ0)6pBwsIa-4*NBKsp(P!$HnL4I_(e=~QnRT-EGBeg#hCE|&*4M1- z>H74M8Ffr&Q)i`Qs>-ETOdOL^GC|VWcujXf`X58?sx9s)StaoDda%}U^XVF71S_KQ z6I0`N@Pss4{JzGXEHHf zCjEPZ_?r}iqE3JrKepMsa3{b1pofJ1D3Hf2^TOlfFC}}4y6`Vzm zi)xClBfSJC5HsHlH{@&i4+KqxB6$}{H#Mxeq93W(8fF=K>N;z0D8?zTArB;&uo0I{ z%|~XzTO;$mQ`lTm;y|ijqQ+2vo6C7Ld^I-7JHz*e*h_}oEgdZETVO?XS@mewcst-4 z9Ng~Q6_`l1g^W~v=)H8i`nhzO8r2+A-qYM+2#a5Yjb)3(YvA7OMaTr+LSl`dVc3Rl z*lt$NaM~>W%O92Jn|oVURKBwmS(aOl*mt^{TLHV=*Oy6JaRYw@s{C8f6`0lA)g_HL zkNIo^tcxPNP+K#*YIa~pz*sS~bYEbe&sZEPG&_b@%6>HbIlXYq*X1R1&F{bKOEO)1 zLRM?bfHL|fRuGY+5PmCW6xya`5oPZDVu|9jVykFw+@Ec#PpgSUo&kmPGdNOCQmXT&bJQ&aB{7ZYXYFJj^o6{^s|wa+^ETKi<01d4ut@ zopn!jK5*8wnXMBm@+{ZQg}=*xO|(vPxPEss+nC+q66b9H?%WiqatGbtv<;Y0t02Ukj`Ws{1|UAcL4DzQOTVQOIg=|X9!DTX1C$;WgZ+C_~mlHB9wPNoksEPUz`%m47ak}{Qb~7#U3g)R?M>Xb$aY!W)ru(>+9uu!6@sUv9TZ2vhtO};Llub(W$2=tMSlql z410MAJr5u2*HQo(a;==R;irr-X>A<+1FK_#9-FM)M4Cq^i@rXd}?AovxE9e@*j``Iwf-16aHIKQr=N@SN=rn z)_ym&O^Kz?%RsVsWbMiRmfb05NY474Pc?|#v)OC1M%BJui=XY!UR`rWcB7m+Imgor zQflOQv;Q`INLiA-BXc+N_gkBism2UJ`7q%tU?rp@W7IM7HN(a1p3t(w2^MHz*8;i= z0Kucgqqu-KidBQ@ux65~xHZ%xatPDLEn!aZUTkqV&3oS&_wpT1XI~FdoohQ2$ch%( zPrCjfZYG=g=DXJl!#&ac@;gZygOj?zBW_dH!9ZGE56%hU>P zBVv4_3m+8N6UP#Zq21hJiE+u_Y!&Avi{dl`m2iN2i}MVg0u|E3iKm>!NniM+?{n;K z;H7J#BgdIxp6Yn!T3*(_thcw=Q{UX)UgqlI`0DE9k=h=2Medw%j zRd88Q6)cWii_5~hW4)47Ig_Xfzys(LT*=+bodW*?AF_MVl|cREHbNKkk-exv;U1yG ziS@~%kU3l@`JI{&F-8Q`BFYgy9kC^%bkk@WW?}DwtauK+5&0mV0L~YlmgvPic@JeD zVLfENqOKGZyklIpi;*wvr#JP|>R3nj1D*RvFkK+yE4P4jU9ViFj35~_M@HkO_ z`YXGkOrdgd-g5`(x~AsCamlmn2er29xEXlu<~gl%-e&eRUY1Tb?pGv1e_}ZDox2s^ zisLK~t1DT9?8b?5&tmS-dya?|^@u%P$zM3(YlvsvdO!f0`2o0u| z#jiwqhC-oykHhobKGSj5j@Sr$E!QE>74OmDG2fLyS@;s#IP^#OOKdl8iPXcqWZh&B z5~3sY7beFso4uGdj>g!dxjcFrLmB?Wzre|d>Iq3!zK<(&Z#ZX?FZBTroB zLmL!uQ?%SX~cJw#|5>R4wh6~W!PxSRE?7tG9HpM z5>#|q$yY2F!Q$KUAMz{WR^lV_gR+A{4N@%;h|dVF3v)$F#r334#Z;L^aZ7z(`%*cc z*+m^Nol#;MYwC>ju|{Lsjf~!z%8bwHYctNI2UFCh)#-m`Of}U@>z$dMY0jLSb1`+B zu21%v)O`6t;SJ4E=@$M-zFhQ1q(=bZSowR^W5HPHAGKFe4!p&3Btv=E11A}F;1J@4 ztF5;>eiy&u@9hiYy`rOBb8R>MgPciAo@IIU4C_2AVUJq7+sfR-{k56BV(ZY7$TR0( z9viwby39Y4;XkY)P2of657uY!9Cn^KC1@qOoiwrmF@?Yu1!pCeRgT{kb1=s*x z*7_J5Vql$}DDUo`Z(dM3r5q|d_j`}ImhIB-_a*o2u)|xryJD|niF1&pqrH*qw5z~L zIyCMH?rqga&AmM@yoahbS&IBXc#dO{|5D5uw_%g1weetdH}yT+)b-v z9~u748i9-5k%tOfh-UH*ay|*pK{Wl6TFmIB>duE#>@A)F$dB6fv_h0Wfk9=D^=b>Df$p>S0=YdCqH zv7W*9UDo67ovz(ggDdi#M;x;%E>!*F=;>HyeOFy*SKHjxoo$~O*LP>ebi2bg#xpUn z480M;qe|i z>w-@cEt0pGcTO665C1X$5BXbhE%_)7sjE~RRRV@gV;|KsP3;t4I-|@s@v`saOiJ6B zzB*@o_CIO6jM~gqsUvlt)tRO?hL*}DvKiV+g<8~=e@^fRyBSXg?jUR6Hn1j~AT0D% z;aF(^Ol7z*~ri3 z14eYSYn2}%1Ih{f<@QB(8+dOJu3o<}WlJJZ}-k+1?ole0NrxP6(od?oKc zZ~;#Wh2c-|V<90dQ0$bzvOlyN^wrXSl4bfuTBb=1epAXMJ=vpJ1;`oxbcX1&fWKcb zh0_akBU;f7sIl;oc%=N4;=OUYwi#nzUS6vtt8@0PT4goQWJ)tKb6#XTNq?5EPg!mF zJ2lgw)}PTHQ+<`(RUcCP6cD^!vdhv>yfyF*={3n+!7`+$un26$U(Td4DoKPsM%~4# z(C5?``aq;SJcLumV}~;Xi+Oc8JkNedX`(J}v}ZcL#)`3iE{^98-hyc0>EedtjZv;E z%{4#3_PumReIGrYJht%jc$KHxcb&e*IT7B1c|nND?Y^Ls+&7$2K!jDsAvqu|VY*kF zIIZGGqG{Yw;N|F6yb6TChY6fM&(5T`Bnf;O{=q*bQpdg27A#j)U#P16+fuZna!O_W zqN7EX6|c$_zl$r9<*&^f9Unt;T-PFSG80VF1o#Vfz-+jX7X-I5;R`N6Q|l8==~+Mq z`zhQWIwGzkzAfFV{7(Z(-4a55O`R#5t!SxnY1Ha{np~|{B~q`FZIX`=1ITH{J5|E7 z(zz7OZOfWZ{!3k=Zs1p$ZSqe{jnyJ2#}8m`hD7o?N&)_4;G&Umih#qqLa$gJoC-?zSNg@1_S2IySeFdLzNOCux zMqh~6LapAO;hnyocD5zoQ|-+*H?k%JaKvLMicHi{#W6hfpMY6kt^=o)fdBk z1B%MoB`kM_RaVlk{9xt5s;AZqo>TS_fxY1=*c2w`br1VD_L1m>eLzP=f{}IM{*i^z z#^{K+3I8v#D&Ys-0;55Ob_Q0%a-o));fbYtl_v#XBvsnehJ8w0eaX;Fr&4cX8lV-5 z^|CM0YI%V|B~!{a4mr7XcL2_e`D7PAjRjA4#lz^TJo#L$dr zKE>8Rc2Tixs)%_ntBl%N1~lc4{twf$l;_6#sh`sohO2sg=8??vhWn=a8OKt#r>;%8 zpc}26r$4RSDs3PcD;X;sA?+a_C7LDqPuX7MXIMl>b+dGoq^|I=Dk|>BFk5CoUe;A| z8`h7S6_-UBk5cq@ctB{cpY*M8_VhGzhAqYBQ??XldQ{WSv)6Z)I5)VPdd~Zsds3NO zeIU9wB#uA9k z@QGmjxm0oQ?*oOHye$^ptc$~5Iv#d>*vsYBjeep{3+_)|Jv_zav6oZ=O+zEW94U8)(? zD1H}1=mVT#@h9>5uuM1_Ym9baCQhNiMekc+Qlh`NcCa=zgIaEMg0JwQ@!{Y# zplwtVDW*_{Ubl!868n>@IB)o~xFG)wV&@Ix>lnJ-oah;{ab%8vv77X+aCx00oogMt z?PDB!Y#jT3+jYy8%0FyvtN$wRSKiuEQdPUMo~3iuqpF*>iLTm~8n!<@|MSgoTD;=} zg~8nLgjiAVkgs-pO6-+0-#R{w`c77kskrN&?b^ZkNr$^<`|2=#o$^4-5ajOW&kY|y z>&2&XR+0BPA#uLu31XL?H+(ldm8DCjYo^K)a4x4lB8Fxr4#rP_9^PNkMyNng7wHh) z8hgXv#FJvKSOd;I;2*3%@sk~9W--OA07uU$2N3pi_9Jc&4iBCQ=>-i%tz>z^m!j#4 zRmvYCCNZIMsP_uIkWF)4Bj;|X^HkrZ`{V9V3)oFx_59D#g_)DqxBa&537UgNu9Lo# zk%6&UL0z~CTNXbQz8*dsFN*I$C3sI_XQDG*1H=I_Zy(fwyBx~oj!J&RYSSb>C9DW+ zh}H<7_3iV)flF?)x2xM~H(8t8Uz?v-2Fsq6-7K;GKJ_bE(x|-Z=j@-SDhHaI6gB%r znQNGT7Mn`GRW_*XR64aRS{XDKm+zdoA?34Tvvd5e(!EC)SvzvUDeo4*Mxoy%ong7c%r*zHyC;fx=lcHT}(5RAC zOY0k6=x53HN=$}y{r?1K*_+fw(p2hHygPCVT89rz+~Ylj1_PbAKjG2*LU0++C>Vw0 z!-tR+B2?T+vO+$d@i|OZIka2}SC(chNc~HhshyP3Ez_fKZ4jng^bNGlr7|TXnhYy| zUr-(xXXrp-@GO55li{BxVjOHhH_m-g9)Ag&NN(oTX5WZoXbCrk-x{roz83^|-LM(4 ztwfdoP3XLDnEkND;aTGyXT4%C_CF3C@}6V-umHIvdL1jHD>=^i4#Ej80B=*jlg+qw z*|k`gSYc-WafdY!_$To#@eijn?;pCFrR3if)C7LhpZI;b{i!d}lEfygWAKJ&WaM)A zjkBw>Z?p(YxX1Xf;v8yo$cLU{O@{fzMc|u~G(Hr$RDY+N(+l;>jn7h-8fF>S8NO+A zwAK21`hGfEZ#4J~Rfbc#43p8+Ntq$Kpns%3!F$MAAoolBOnUgfLxEk2<{BAlz$tzLQm!v)AN(#6Md;s#31S(`8RQy!pJhREsMjQk8g}T z0GWoDXIfS3WO}SonY8>)_`itX>~{9Rc+|1*gZL8Q6?YWXHCYcj2%n@2fD}FoZv*@B z@4%noPDp?LX}At_iM=J(of9R0`q`eHF)A$a_`Sb_fK5JdO|HHK8cK*S0Fs&#O1DGFu#{?9J_8{QaD1zCx75wuGLcJL9k8 z9b?hh79x!`Gd`MW8w#K{taf78a^?GM^$^P14 zLIWtfYv#B5AM2;4UrK9Gj}gf(6*E`733s5PG*9+iLv!x) z09{?>W$uOKH4z4Hz$S-bxC>GiTo?H%+#xsv~1sO8k%B2HfWAfhC+* z@HL?xyu~dN?H2T8|1bH2JBitTxT9(Kn%EpP82ul^$S8=v#!pjs6TRcxP!=@+Q%71w zccUGn1bH8PfhSmhNP_AD_^M=+)}}r!|65T1siXyBx0Dtai+?Ep)h?87mY>oM z*N#^llD}2%l(&~|6wj3}X7(VLM5~o{WnWQa(RIaDnL?Z`86|x#ox+%@G8Nr5c3CGm zVfbMhp}3^Hma-=8gj%P6mpQ9um(={6akYq=X|;OQ8lBZMWp2*Pv=f^Cl5>W*#wqag zS7_dARlqzuN#YP|ws}-lANyc?ZSz9wEc<2qR{KP^ z$g$ROEbt>d%k{*wAo?Dg?(Y!t;R$kSWCi*%@snDGK8dV}r-r|U?)qPPt~>tpbaXy- zF7VhKA?I>$JNGyj;V81*GT*W-s+Lt-J@Xj0M@f`UjENnjjm2;^Dr|}kzF~bVspjd%Keq)=2KOB&18}JNTW&2HnV%QpFZcR@zomYi$cA zCEi!_NH$rb*4)(QN`^?s8+Mrl@*9d4rV09P%6dwvYMEG|D3Z>Gzi=|dq@XKjHrLHx zAgB)-Ko9axG=)1BWV%MOOYknyc*R!bBY6`wOSMh8Rx??XqpYbKsoi4urb!r})MT1F zwM+VeRI7fWX_xvxB`9I0?=UF5jy&QGgO3O?;d{Y3~GQsIe))Wn70g38~Q~p_%?n@0$=98SQTB9)c#&hMpn5VpJKO z5&RaJ7;6?ki*3fQ;**F9d`tWlv4`l6)yCf8Pw;5G6=PI8K#CGw6S;{#$tKLXq%5(L zdXN7@WRhcvuGIcySE4gfO~;c5;<{)xIRGPrBm9|>C85E=60Bi#XhOoijRc|Zva9mz zswdi)2ES6Km}GdQ>#aDY{-WKgJ8dXTEjM&d$xY{{yh{C;vR@mQtBm!vVu?jON#PS| zWK9)61iRt!iu$rf&}&{R(IU7BbQ-?G8wL&M*Wou8SViaHsqhKebQO=^1tHX9HA}^# z80$k9wNKSv`$n-ux<0Jb6Td3Q{69+yxvf(ch{uix}JbC9A+A@;vaw7|z%= zUv6Mphz#TfX#dWDDV*>B;r|(3hy%g5AqC^~VnudDI^!qf2hnZOyZB3LKx}lZC+iOT zVsts`W9I|&BZUz+ok1UsmSJP*rZk&4Pb{HEV&5<@vMzYo{SUK6-R?Z+F**Bq--p)6 zD?*E~^9hn(Mm|Ygq?ac0lgUIGnawl=?j#b-?xRbxj2@P}NG$+9atQomd=+>Ts!6hd zY~-Y5BvPzctDclZRtDj9_^Tx&p0*ami27*ReHJ z6n_$1AI(8;c;%5F{-|x7d6(;S^=dO!#}`p_oW6#1Y{u~_`%mRyf%2+m1b}4ec@ zjp&(u@!Rl)P|}^@9?tYwU%HinovdQ`F`7?Q2|o(nCK@H?ahFr4aAC9!v5UGL*@$*$ zvU;+ZGgbn=27bmqMro=vehalkjIo92ned(9qwu~U*SE_R@hq(VXv;I-DTNC=l@BOc z{N=*8PQT}unfPdbHgj9Qo~OdVlJH|;T0t9hmm29tcPbg&Lpw~+Ca`;`q8M;X5b zSJ6jNs?bY3@*c8&$QZ#4NiT7xu&IO;amDG3Eas}Hv+%1x0RI*&5%^%g#De%Fb+rYl zN~KvdFl$*(nLgFju12St?^FIvJC<9XTb*`2wM~s(>BkIu)i9k|bXn97yvbY0uEFps zzOr1bMM*`1&3VIpO?1Imf)By<@$Ps_o*i0Aeo0WM#d211KPz2GJA6JAqV8s)I( zlMlQtz4s!jY(&}z5QyE5D_d@HmAKac*1>)2x6F~-_^3;GE6V3=sBNVcqte3fpE1~aCl zRHpq%?UXt@U7uz#>{ZV(&DLcptCSdH@_ep!88g%?G&fTMhWgqAni=ZZ(zhy>qCl7- zR7fv~iX=Wo9zqHzb-wl>q8H899W}g>EK(MyNpq$d7iQGYZB?@)lY;7>dENLdquA6& zrI(-5&QQl>b(Q;7MkXH#YIka`YPBkbWV1%CWW$%(1!AW0%vuekGfpP~u$G}{Y)X)k z8}2{wL}Z-hhB@f(?_=3Jcq@JRflCYnu64*0O7qxlErX5xi!ATW5?_^fh?TH)@SXC} z&h>7>_sjp%+a^>ulp7lnPv^1{lfV~3tzrm&gJ7x3r>M<;$onE$2*2knr4<}Y@&q}N zp<`$;P4sX`7~bz$;S)N$yNsSTwzIarK})RCS?O)eyd^gWeIX9@K0Yn1h%nhP+{(=P zoypDI4~ZDyhR+EOfC=aXzXMc*KaM{PoX-2npMq@Vo5aIKCP^8?E@&&erfj5kFt+e2 z-6~}h^#ubnPuAs_9;fV0ooale(Wcn-x1`(nr_@vB25>6poTNlNnK9j{#a=-p!Vw+@ z%IS@s8?M?o6u;{k6KIZ?652>0+L63K)WE*P((r0*P^>&Az;xJR{8XZU{0`BX{hjkN zQJ2nR=OsVTEV>+j8D*Ns@n$Fz`8O=^-U&AJKCum}8f6<&y07fR?=girU+G^Ri+X*T z|BWtuUpV1s)6!=@+x%W%Imp_zBCqq7gnA z>k++(9tn#he}#Z(t3)z ze^$6!6h;P09kNdRo^TzeANN*pR=PxCRNv8!PT6Y^r*%kKpc|3VA-ziWlmFG|Rknrh zLIWk8kp}!+K98B1eCH+E+xaUH6T2(7uBeB&f`3jnOk$Ef)GkP=mcyzEX$#Y@sh4QC zWeRH?(RVXhYdx)XCbfUcmK;F}t}B=KR9xYI=3i&^<^07N5w9JkzzeV=l7SY(b3qj| zgDX$oB@d(hP(#AY{t^9!3j{qRLudzgp6D&_ChrqCGTAA9m#w0k#U5eXsXxep_<{I0 zVg_M~t`An@Z}116S?&w?|M2$Se!+J5CA=6t5El}I2m^VFtV{N%o>Prjy%YZ=1E5F< zux0{Jq^Bge+0|^ffCd3}YoIN+Gt`JZ2%L$m6wQD(L9LNb+;!YnNgp*Ob}=50)Q@jr z5ojF}5zbK`;SLw?HXb+aSF!c04W0B`_0M!=hOeoubqf92tmE0kjOR@MW=2xjDIH8* zbRCpO4LaRinMS@wHCC}pzEnC|Hc~tY+0T6{*ab~Zj_z7<(PhZbP&lh)^hwr`b{@`5@ zNRJK(RmVnCBxeIznB2i1h1_CoVV&iVfShz9`3r2to0~k5#Gswf5?V}8P7r@sX2UH+niQVu(aI}~uEJ*rdHQ`sBTA?uGe)^ZH z^nLWd!&hTn0uBAmVy&WwJRhBSgu`&#g5K7l3E_6=7^*nRCvLH=+;@qwtTeVaX`|~T zjwb$NTnato4Os2zPFN_`ndC$l#~LNG5+)Bi&8_o%3=PKb1%AcmCq|L#L{)Nf zxVwi+l2Hn&A9?#ccFU;Zb`T&L}x;;PyR-ttw8v{=QP0;q(yWp^J29C#%gtvq~ zM@I)(fhX=;wiA`Pwuk0lWs-_sm31qgnEAFd6@`^0_EwHEb9S}O(ak;8{>u5#zc&)_ zj1CmV?nYaMFNLRv`vp3Mb_M;2Bv8WoTPe?|~ zuc+s0lj>&%haNKxNLggukTy5nrYTXFQ&*d!^8Ts;#?!`h{W9ZM)9jRE`Wnh-rpNj+ z~wMF)vHI|bu+Jk(9--x5gPSI9{So2+yE^nv5YU-!#uil$+phlLigQ0J&;u;t9 zJyclQY3*Qf9jKN3oTLqVFY7PqR=E&(3iMZ0$z}noSI+D-6luS}>lf}d%tP%a4eiK`Y zRnW!s()baqlny2yp~}z=(t~IFJNVb*60&n-Dyc}m1hTkE0nS~@_zsRDd-&%CTFA!k zCD_3iuxchhz#ZYKlnQ?WZ3VYPUxyd5JJUVF4Wm#Zo61daxYoo*))+XCKcB7R9E3IS z6wU%}i6Beb5_%=Lr!Fwsng8bFsjpIxDZR?~#ys6SMP2!F^;zWx$ycO{vb)jT+-zm z&uUv6|4uDUJ792YYNSn0nWlIkVc436Hey`7RDV|ANJ>bS8cs4lXCpELU$+tZ!I`HT zD_zN6#a4=1AvRz`GD}bd&5dsgF5|qW_`b2eyVxG4(N3cqg7Uy6Y!KFp@p7Mu>@+X1~9sv(HXmafs{ zi_2v94OZPiRla(kYJq&B`mIVTFH>5SyiDxJ41SGg2s$-_yT^K$qg`VieLFl8Fg7;L;WhU~CkJMh z7ngo^t+g$$<@$m$+gKgm?oZ29l+aT@1q^DCQ&@X3hAQ%#f}692mSGeWWz`ste9Gm>`q3K0P76< z4(li2;QbF-!nhpIiCTy@^KGJhM2x(VT~*x?y_M(dju<;>yXXlMYMi5As^c4++8NsU z+CdtRny;4_OEj;w8&mSrn(FwvgQ;G9wr09wg0vm)6ys{^nmmuMNesdsVYOoCBeKv! zbW`|pV6y*HkikUyMtM_0t5K6L8jv&jQZ(ET6-E~NE5fW`U2myB=)3DXf&Pye6L=k3 zlsJ=Mp*x~WiHcZCG&hopehAGD3VausX{pln&}Q(8JvFPl*?zl@xK25qxTEf%@3U`u zpi87*EG5`ISQX6--wF)$Pxp?nzwwf8o9%z@mY&7_tDzgXk#QgGW_iJzKsj^*s>R9hJoZnZmEb+Niq$7Mi*<(lP8^S| zAf)7H^aEN&q{SaZ|Bk(l{1Ip!!_XtX>HcYvMPYep2^tCSLsPJWadV7AEM`)G+o;Us zL~J51PtHsnPuAkxrZfo=Zv!|f`H?mQuM@TChl!z-CpjcBjBde}afh>)F&pKc$!u-9>A>F-RZ50HI)1v0Atxa}#P6i%rB+EZ$rEXB zX;7pU#U&ZiNg|hcn6#PXPlkWa7u7+y>cdJO|2aHS0t*^LH^Cy_LtY*?mwN)vLF5ce z+a}BrmI|H>~NeD@U`}| zil;{|`PPS^KplVc$l}l_e+~Z~ugUS;+s19S9Iyx+8>>H957@4oODn1!6Wsab{VLx2 zhJ`j*205uHNu&g}q5J9W+!I(sd=u|K-gLYdt^o5m-wKF@t$*9_UqQF$3D$FhJv93`4uZi;+cezPu64uvf!-a27)0_kd5l z6Kp_Q>NjZjs!fK5?BB#T<1qaI^ej@S?xYMLOHsYj3RoSTsTaCB#Sdg?9?-=NXIU6!rW0 zXWrwYGsXQ1FWO$)&O7X`jDXsE-tXq#0EW2E|6H1u9O&^o?aBSg>h7n3`*H=Oyif=E z6|kxMQf6gD``s8&#+A2B8;p{g2c7T3#<`Yi>A2-Y+S-is>GiW-Wlv3gYmH@9&(NlJ z&pMDwrLHgQEw>}BeMVN!BWpOlWr|Ak4Zov*PBZ9mbP+ZiIe`trrvui?NTLU2Lno8X zSW459)v8Y!iY)6i%QYn_w=ImyPPf$8VOe4;QURZbyh)CbK0?Q#y!g2|0dIk`#4F-r zWC*qcbfmUZ|Ea)@K2h7y(ZWM>vB}n{rk*sXD$%s3Z>p`zGw3hyU~+<@q1-|$0F1nL z{GZ_;Vz!v+Kk3PhX9^X)^#T+5y29A->d21xT=9PRa_C?2wKy`I5-SgG^Y0TmSkL4i z(6971CKrh!qsfhEbL1YR0?vev@{yzsdY34l42UKCm(V5f)pBw_U5lAWA7)Eb|0w4Jej;QzVR~wLYO-1GSSp(9 zr<6}!ZW?U9klH(Kh_yx9qqINM4`w#b4resaPR-nv!e=+hCXH*<)iOR?sxyx$Nn1-* zOwJ&_GikI7%f;rB5uC+6M0@Oi=wYe{wHW;$%HsdZ4#g)}6BPp;5}Sn|ekpi6dOtFl z>kQtR+apK#&9VB?PqDY$qsS7zAumN%a${l}xyIZdk^jQSLJvbt0+T{7LXW)dJutAp z+C0Pj*Zlu@dxd+)E_-VQT8b?bb-2@fec-966p!;i6CVn6j627S2iCq{4_U8EvEtM?$o9!pQ)8hCG&UVEY)6( z!Sv3wLi=6Y$=t&%XeBLdhE1(>w{+JGi2l0vZ`Ei`1?5*_KGdALhSe5sh4;c66ORH{ z{JVu&+@SyOvxg6dMtS$SR|nhp5qB+bJI_&P&)|UQSLXr`7Kg<70Y|u-pp9MPI!BgA z2l79IEd#g34M|1dLZE80NB}gYz^!n7;Nj}k;{DY9OTU6gd7AtSrEd$`*xGu#hw_}MK7Z68Z3r!kjaOVE$0WwWta5?E{X{8~T-Km~#*rK;-3pAsF=X$%cD^*9kO7jyt27JIC0_a1~Er57cPf;MBj^cbn zX)s7wXc0j)LbC{&u7|Cm{sjG}JZ3-JS+!Afl|8Dws()lWsYUI{+p{M{tHe`Rpc+ob7Tjdz;l)T)g3?@L1V70@hE><7Fi~<$CPIC z@5Wy=zw0j=>KV71nt@OG=#<7OwXFX1Z5diiOUobWy;A#H`&t`Y>wv!*S9LK2GF@#M3pN2eg&V2G#2TtDJ)J&516w6MlBodBIlGiQwL>s1W-(p2;&_7imikv} z5v@^Owg`q4RUYHgc-efSszOVdaJAe(+K9ct8cWR*ZSjkEwd66t^Seh@lz)Xj&>^M( zS%(qKCE_hU0*k;!$!~H+5l-$%R1lU5A@M~l0G^YT!ELgQFpj%tqe_YblfAcW^IRuA zJNyTInZTxXTL?wE#C}Pt;ZE_rPzU6$;wQe6ZG(TIrfL@J3Y0%Ib@hV&ingt0yD`gr zMYT{Vn$McIvmcmL!)leD-iiNCD4-xTO(+mvN2`QZd!GWkHR)9c9AZuRZRC>h02z+w zCKky3nEmQD$W^Sro;2a~FRJh6_m=0{ZU((|m8GFUqsJ{B&6~AeO*i9uO?hpuwmh>P zo1!ky&VV1wKB55K0D9NIqgiA&$X*>%Ry5c&q*0slIitvGPR}hfwp`_`9XZ(*c31S| ztj@Ytse7gBsW(gm%a_d=WymqM$bix>ng?6=XEe(u&Dpx&v)iU0U>lM9O;J@1yd}Pw zB+x#Dm7J;Afm(^l=s0XD+6(TNoB&&;YKa%pX1+)41IQu`jTJ}Dv6_+Bk&Xc*yfAdu zv)eg8*eEd6-nz6Q$T^uxo0ZmgR|Qpqz&JS*FiU6{n2WQo#+e1 z0{6jli6`;}`8|FOYYdZ$ub>T>fimbpVm4JCQOY{nL;g?P9Pfn}po_&riBxP2p@W(M z-p50Af7FNlPd~=+mZX%^4V8_1v?->F=KoUqn3m`_rL{}_UCl6K%@uVkh&$*D_B#F% zxeCohM^aI9>c2)3nZ;-(M zq9}tKun(w=?gh7_?I7%ZifBtLQ6!O0*a&13QWh~n4P-a`3AW2g=q&6(?!&bZU^-<| z6y>qDdXuFUIh*d4(%IUAeaQ00CK{NHlC_!3xP(ejCB-0UFEFA1k+{NZ6ZPWTBdY^{ za!dTTyyrdDTwCpJy&e2%j$BX8V2{wYK>bMna0PC8G?P!ny2NJ+#qqUbCvlr}I8h{I z^4$~T#m3R9T)Wt;aK%V=_@%#*cOA$^sXcu>)_~c2+cU~t+gZ^TwtI>;79Pvn_p{em zOJ3K!w_l!o-IC|bTkvfO;D9$QWWN3UcG#xyoXo3a%M6baT6tS=XA+yCsMr?qB02aq zyauDEw*uzzOk<(`f$4ban2cT)t#wYuA8Do5b6^VsS*X++sn^VIORtnA7CPms)n+`U zn_-@#{{!^C+o+nb#lW?DoIRmBN~Pl2nwaW>Vl48B=|m>s^YBG%Ct3n+l6#?k#Tt1h zd{iMT_G8DHMHo${>9?lNVLEE&WIoJH>ID59KzuH%YpA@a+(Ax6vE&iZ3#=aBDO|#J z^kT7V@~n#2c7VD(CZI~UTUc-DOl1M+Y z6Z#WsA^VfpiQ%*P8ZxBFidRYQCjL|+=nrOsHp{qKvq3-F zqD)@xFAT}-vgoXV+hT40Ri zTq)zz`?Z(KT+3dlS*EU=QDhmddd^NXcr+tuf~cpu!VHABic5(eNdIWx@F(##cPE5L zRt1awJ)@6eD}r<+%q!w`qD<^zyrFnBdXak(*9sj0&u4CQWOzgH8km&&T@`#v59`p` zdFOrmBl~-&p|sex)iWn>(2lrwhgGqOUY&nuyl3KE;B@FaCqq9Q@XNz}E8u|6{+t78mZ$gq)iaXdJa8I~7wT3+p z7{z(2rK)+-FNs2S2s0JRAfC}ic;99se3Bx>oawEv_yZ~u8xB2}MeFhg<_PnN_?JCP?8E%n0!0zn1ukOriYQ*2ox^OV7SIo< z2gGWs9YNv4(HJ^ju}aYvNgz1V2`Wu!<(Kh);-C2X-0hH>9}{~K>JiaKSA@TE0@vO* z)zvK&@(_;CrE}~l#g9w-+Y1ZW!nckEuHnTaZBsp$e9ud-+s_4kTs@Ewm3T+|c%Wls z9@vYtjeg*2gq_|ap)#Jfo^)>+M;ZHF{~w|C&eL8gv?%a2a3FBP+r}O8hJda54|iE- zC)W=D`Ebym6TKAEioEy(@+Wq{_kdab1yRgSR9`gq)$Y(=PPJr$_J%e!qk=`yj?ur- zJy(x6-ZKpX>F#mnj^+tkzb0r(F@FKsQjk|l$pg;p!nFNq&&VN6U&}!40MMZNqVa%t=onRPbsa#<`Jbk-W{DQCA(Vpl zpeC1*$REl{V1I*P&504{Tg4hh0%?Q1RP0r31zg}%#c|}V+yE-4h@v0iBY=ERmOMtZ zp+e+;6ieCgBlLP^40;ji!8l1byZ~OW*qTg-7AJm*e~AtdCPgYnMu$H7uXqB%vB0)A z%)1HX&*}%Rg{lU&`3FS0aFL)fhQ_7?`pysJqr3!rhhuaX+N+$*Y+=8t>Z;!>-Ku=> zJFineRxQ?iQf&tAjT_8byp~*ve<51Lm&R>|vHH%2|7pvq z*6EI^NcJ+Y^t~s4s;X(f&{b7=pmXa6p5;CIgs!H!p5>V?q-$zfZ#kq7>E~J5)G;7S zUYgcB!=xRpEzW3_N$3vh_GL<$lk_+Bow9yrwgxTUNc!*;9q8zcHvXe7gnyBql7rEj zvGi~u^eF*))t+tf>f8qRad$Y-%e&M4+2wS7bq;WLcI-O$U*NvRj}bUAAsLie+=|VBX2Q!*k79>nI37i+BNxcI z)MfY)Oj8K?54;}wg&axQlH(KK=oD5hG4W+=S7v8yd88lN5v>zqgGRU;G&$HM>_-mZ z54r99K?-6fNDO>~VU>4?>uk2RlF6XyrG1f7F8zxpL;WEwC#3~o3UxMARu{6>H4mAm zbTz|B^El=PgPBsaPsn#j9`zk0Xj3?6{6S=2Aj?-PRO}z%EpgxW9$U#BW&TK zI>oE)G1s%wcAgr(RRJ-uIs71K3nfCo1kIq|Rw+0)+#p^@j6^pJMEnM@F*l7Od`YZY zxNGn#e@OT>*gRZOFh^&DyyLyV5f>KO=BrWK$9BYVw8ZU5@$sbzPbf4g+A!i5xR^1v zK=>cbE!|{0JaYm zCX0z3*a`R*Ize8P+@F{${LN_rw|gVEN01eHio=PzkPc}K-GSObU!ZfS0QEx`(j7FX zsVV9~`cAs%`m=_W>`i>1rU_$4R>>pqgNi@pvhXCuTXd*GP;A0`<9fw1Xdjvnd!$_c z*JKyqOKKbbC$=6uQH|lBVF3FJci`#*ej*OMKe?_lu7%v=Fkm^m?+45J@3~M11ZMXe zZ5>Ny`wM~qq*FQsOr4&)E_f^Qtzu_E*T&8jMF#p#cus@+)c@Sa+-(BuJ(JvvoMj!) zN@UyhqP0cGie47{EbMMO=iFnv?5^mW72Fi!g(bmVBnAT~o>kXQ< zbS}P|O`|2n3B>?1f&YPCRP@9!#dNq`awgz$&Jx2yE9pu62Y8p%j#J{2I42%Sv{$@N z9#tgCS1La-hOMKw7)Pk}nqh{un%b(DWC!I$dK9_}?nUO|s~{d)fS)5qAxF?W(oNmQ z%=mk{fN6%`!&%iOHBBkmU7BAtr&M;eOZA;?s(uJ^m>=kM)Nf>hCYZitCsILAA!7Ji zB#XrWs1kB;li3Uh@-YZ`xv($S?y>_vFm{BmjwE7KW4b80+ zEWa4Hn^s#Vrdfd}Cr#K3Pin(D!X%kS8TXowrhG_mZyIhGm^mrqomQ!PcIupzTbZlU-|G*&HK$IYi{Le4d+5G2EczmRN$ewz<{t94 z_;jI%_?LK_+Zc4j8Uv44Syy>K=h^Pq=NRRE=pW}C=SU5|4V|==Ee`qmI2l>4(GbW&O>t*B!5^~fotil(otw4xZ8yk5p*3LLnkTH<&n_uiMC=Z z;fSP3N`fkp2A@U8!w)eEcVGi>4F+RY)TtPShLKK4M?#`*!)@Uc%qr#qXzhBbnS@d< zke{O#OpBBUQ|JTi1;R<()#!DV@X_d9^-tD>k$==jGwcJu~)jmxvP5WD? z)vrujl~PeZM*qaT)38kUUM*?e%DMDlWFwK293GtmEMlWd^PElxRp`&(<$}EZ3ab@A z^qzG0E8bDaIxpKR6_hDF=9ufQYFprL;-3>N8y*}LLW3gOSl{TT=s~f3^oP(Kj^H?y zLae6MjGj%f)5&}Acq#%>;vbP`{QaQDzsCL3v&2=-S+jJH^FO;#v@c%;a^VMmHqRsT z-{pG>huHE;N}XryukGi&rM@|(vuqQ5Q+$m|O@Lp$Jkr9o2>3BWe3pBVa}+Ofg6&fA zjo?k+_~KmK@7{?%hrNq?RiH}f0@#-rLeqklVAasr;I@!Etl^h&m^fZCz~$r@@NjHA z1*U3fA7wy09LpjH8`YK~+OO1DUz$UJQ#(?BSRJBqyg)fubqIlwZkaOoK1Y<$3PKrXrydl13xdi)3eA~ zo0}JI0%nz!f+KwAO4^k?18##YCEsj>caP6)@97#Hm>Oiy-u zIDFp&rl5R4ydUiuUzzMHR}xnWiezswJDLQX+i;{(xI19t8~nC#dN?2C&^r2uJH4fi z>`#gh71VJZ@HZ};Z@V8_7~bWW={y}A=9BIJ+D^J^JJcmYiQf@%Pj+N@y9IVfhJ>2O z*77=WhFCTEGLeKX!(H+FXf<*dW6+$XAJZ4KAJtj(DyoLk!tSC7;Qs2MnXmqzK{OPZ zbFE#{@+~?*y+4;moAidpX}eO#8(tXOr`$8mGxauvG$CS;>Ybu1%p`u1TJY5*D*2Ls zCpCows2#j#hU0tjn;_38;8)0_U~hkrZKP?fJgG_Qat-D5Q}n&`KQwX8ceaMo#1s>w zux<22W*my6wOEJ=BV|GV>kM=xekxih?UU|D+C+=xLHGmEqw7sCW31R%Y(CwMYN40{ z|3zJATyP#XTG>Hak22HMnX^QMC{grM^iO`2FN>ujB#sq-OL*d?@%E4sIT`O7FM)SK zpX1uZFCY{39vX=i6Z2FMb6R=F*v-N#_pm1OCq2dF(oew?+e5!+J1C9HzN+D>;p|JQ z5_<_(V^5_<$SnC%v>?^@UC~S2i@DS2EL$ z<*fCU*OjicJsGpvJbFu-*?I=>QqGtXrm#kBj$0pP!YOT1pfZ7+6PBf>Nm+RM8^c}0 z#gsm&Zd13Eei@$ZWcr1yb!FR@o07FIZEH@u^oOQ18k^~orVVoeZ_ngo*P#{S>ckul zjXevyy_}FI+ppN?11GFCLL$U zQXbb>OVo>JVIE*8noOyNA;@rOoq99f9U6`t zC34AXm<{aLj%jq1hWt-oQBR?Vs=QjmXyc^s^X=i7uZFJ%NpHk7#qP9O~{k&6rrnEuf zYI{A`cd#k@E#Lr2qp9J`+!el9GRFGF^iV!DC#K}1$-kvAKS@{sW+UJDnX!qn+gvwp zN2qEz>098R?rGsn6vdrhm+B|-^EY3Oa6#ce&Oj_hasMB)Xs?d=*gmpF;)k6-93%1Typa)KJ<$UBGjx z9O5*xF`0_*z%C{_Cy!&}u(u%ZKLeaE)+Z;5FOl77`}l3~S2D;7vWx~ax3$XwuWY+& zI8}x?3Ex)qk!MM#h4qPj$%*kQi89bbXozf=dw^GaR#GSKi%j)j=emSidz|h{fi?cE z-Xi~3{|Em+p+6$I{!ab^?m!F)`of5CQ;0{~^7r@_(b~~S@B~PB?DbZ2PYAvVo^e<9 zPX=!1UqYHlTIis^L3pfxo~N;^mg{fZO}EEixAe4YTSOTP_#cIGz`USl@UeFj=#n&Y zw{*AT{))SNQe->GYo3-Ucq5>;pFk+&8}ui<3+@hDKvgLhIaKwG9i$qp%hO#`c4X#i z?y+v_5@llsD8UJgDOAU_JJ>7ADY}0&h}x)quDY$%7+`ae>W22KWtL^Tp@Ff)P(l4c zJC@l(eno1a!;T8SH$mQU9m0k zdeRiMCDv2+Ab%6P=#|)Atd#A~UQslM_mL!eR-O*EgdQfFU~gzOT#Qar@6jG1t`K2O zSUCjqzzwPUIG^k%|A9LQ8GerC(UVl?z&F(!-9qCe%|zX8Q$16<;R0}(rm4=FP8h>P z8sgXXVLv2BNDPsQ1`^$omuO#*8}s3PmFv|baTy(^o}%1=jwe1adZmf=YkvTK`d;(f z)JAEwv&Lo&1qA1l+513(H<2|j3%B$zAI<8L-NSs`l$IUKuo~y;Mx=74x$3j*M%@VY zda4$2n%zpzLRIi5V!6VYIL5zDOp8s8ZsN*vow<2j6>e`d8EqV?8fwoS4pay>2;TRc zcijpO4Bm7>o^$?RJ%D`g>EoPV8gTv(WFub|CyPo8*4z3zdlnul33z7&hdNt&W8fZ^ z;$P_>9A3)3_T#}i@j(z9>CVr`ei8@8dy)npk8~0hz}-4sdKjxHoD`cR4oH6iF3f!d z1GA6iiurJJ8m0bAyyy22Da3tF5m`(OA&JOzt|wK6{>1C0OeVr)%Cq2itU~n}S)gFl zyVbJdiQb9z>c98OtYNLTPo>10dw(8obHj;-xk6{Z^jlcjW z@p$qhU6EM_W(8(Sp;#67gc~MC@nd{rT_d^Uk*$tvj%6GiD{yvn=X3Kzdw?f0;r-y; zXj@TC*{_w(C_ZjWw;SvW9DQ8?uv&cH<#28-$}Rcq#Jv`0{lM7pYZ2ndBvI5&*^oAh z680nGf&Z3i>Mm9dINir0BNCqjl{{VfhavD!?MJ*nood$~0m1Ri-9LIEKGi=kv{+R0 z`Jsk^7r_ePHrmKO*co$GvH#|p=Q|Lb=Ql)lgsuk)xhdhr-XpFuey^*y%j0S3w7CBY zEsxdu$!f3S9H8rhmCrZA=tc3<8_55%Skn((E>dM?j< z$#vd$$o0V4$^DOWxBH^Ei$CJ+1IS+c{XXA6-i-lwcoSetXYr#XDY8YFBhLaIq9ci1 zIh&8gEX$BnAVK>T_}+a|aG$l~r{#`BXZy zP*b3~$gE&xwhp^fxnDJnZK}Mcx}|KbY|6OU#q2mTgkj3-s@LdFY^3&+ZX@ZUExHzJ z6VsXO$9%_C=$GVd^gpDNv`6Hj8p+FIXK{SIfAleEDmx>Sxq;k8t|WF#oX!WNCbAda z30J@l!vp1CvFeIn!G0f5x}>SmxqwL2CovDiU$UUaitXq(tQn@lVv4~~5;i5b0<%)5 zcqld)rUzl8JXFp>#utVUXSlu ztFD^5zW%BHtEq~0blQ*9tjuO9aDBLr6-!;h@^>+45a(bOl-FMxuo$VYo+})f%O3cMtTe$Ej}4wuJbu9=>a@O?S{4>2# z#w_Cp?XlEhW?5xX8T5kskZPZ*w@S;dVJj02$@XwX`9<{KnB<+|pWywUEl`y2P4{EP zWlPHXZ+M24d@B;|kgZXE#h>#^=9X6f`6>USvyr!d$ztb7pXj^pzU5&8dqN4X5a=4M z8*d$bn`i*&P#@r1$e;Y7XaRI7v6_3r^^ebpjf+(lvSK*DOxPED$bX4710J(^ZxDa}*=n4Oxtb$tM zKZU;G)>0_?B=9h>h^rUt6nYSD6t60ch?pacv_hy4o*A)d9qxH(UPQrdjJ}U9;kWVU zgk|8ldWx?Ry%t+4ya?9~Z%I~0tO`|5=|yX z!FQM}T8-965u8LX!yBOSn44;V6yhdLKXVi15aU&AQwwTsXwB2VRdzDZF?=PCAqg#^ z84Ybr-cc1W<)nK&NmPMPN6P!Ri(k0y?)lD&;WxphjyaBL!OUQ5=L(nXujw1$y&uf= zF83{qbxBx57oxY2zUW+0k{&6*q(C|w&x77WkkFoQf-F|l zDTTkpU6FA3pmZnElJmxv!Cx>^loEDutF8*YgMU@dXG;}n_$9F6)sbx}g}SkJ6y1@1 zq0<^<XAwn76E?Bsj3D{W2Hw;fgF04vbX97jj9@GDpAd;rTXipD$EXLkp;8nsJp0n(>TNL zsvk;)?xMP;>aOY(t0fGoiPU!Zfpi~PC{_~|$GURug3Woq&@oUxR1{B-PmZ8b(7ok4 zMxOzeTMGA(i^R4G8|2>7cX%ask!ntKV<4s<)la#UT}4zTYJuL0hup#z&_h_4axqhd zy+=03G7@&Um+*>fAKVjM;^`e4$x+@R{#Sg8cr0iL9~DQ&mxp_WTM65Q)!_z!DmhsG z!XHZX#-h|`l%o5oy6ZUAKlh#s1Yj8ZfY_?X{jV_!1#MECgP42BRvU}ww zNL{9tG6Be2j7HG5z&arHw0|l80ynE7dJkw&IkYzAV|~*US61JY-kAq-%I4r%!!loG z&CQybu{PsH_Lj0=GuLNR;Hqff5awCobb&7NNylx+IcEjOJa8sjYG3L2(@r^dx|Vog)VCo-wQ zx(}ck{ExMM$|Zx|)ZA24lcqne?8eAsl;m)NDo<}9wvc7%sbr9Ng1*L1BI}_CQfqiQ zBucq*b*M3z#+*lg$k&sd@yhtb|zE7U|!G%HIopjv{*!@49Bb`6|lY*J9e9xZnIj&CNXZUjT zQS@eXIzKCFiggnHi&qz1;;zJOSV(x2<+0kt*W|Z_ssdo^RM3s`ch4~*W7jCu8@&znLwcKirK_+WDVMvy{X+yTwo@e>RO(tXK61Q zduvCiR*{?7VN?;Ekg`b|@i^W+{ug1v|B0`RpHWiv2t{;@6^Kjd zV&)0d1N}npC41vm;w)A{(V198JcXNqXL4^cOD>I%#B-6a5x=*qL`B!zyA}rnReY@q zxk8V(vHw%?W!s&=;$R*73&-!lt-*$_Up-$!-M9+=GNE7iHE{!Xn?EQH5}QgkC=^#p z5|%@sNb+zq_743I%3znUe#vogFg_&q4p`IM`8oybgLv~gC;6E4Kw2tvlxih#xd+me z$WweKJJOlVHP)+IMp>}Os)x)=con3j?8Ixh8TK!^nchGRRSsa6uxjN2x*tWNTgfRT zBzKb*(HfS#+L>9)Waw$k{}^efeuyVQ7<$HeWCaXdM8@BlJKj)hj(FkNT90!E4MIMmwzCZ$fe2lXnnXD zbRS=agU^y&jLt>JDvHQ`_;YH7vX8nw+lO_tD8-P)$Z~AAVnH${9#wQl&xwtsVZfj> zB7TNzn^+gW=YQmSEj$!|I2gAD8AY}Y`^Bhonyyqalip=qWXV#O*LzcLq-U5y*40_v zvdd%)&c-t9S}tYZN`Ig|%-*y7XRv^&6Rl_TU^Rz6)0Ne(f#)TSs@ils(FA@&xXC$` zp!r+f!<=WTZLOVAnBB;7+ju7XLZ)5UQ`aJWLfR{RPt(6?z0&(z##`>EO-T6y*qPIf z_ch(Xcan+4$@XL_#-V@0i{T~Gm&87PaO@{&bB*`@8`4IW0;*-hsD&RNyc%f>oa|$w zOQR|S$Ma5^^5vM}*NXcn5M0`HZ+j zF%&}AXVg{lCq$~k{e&-~It zcSpNe(CX*Tq6+!=57kdBFF*f(`7aA5mW;OdDQsBO$GO^7P}0H`^gIf};qihiUI#gy zI3hp6n~{s4k#GU=6<>|4MJMBV_&z`w4iMeR1-J}XA`T%hq>>mX-Hy5UXI6M<&{#UBxSzMWt9Rk#f-Cm(fCS <@L4jP{kRb(S&6$_vy@(8ROfdZ~d8)6N*ATd7P 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

    ^d|Z5;Xe38 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

    ^E@Qk`JG}^ciY|6_&El60z{iy%uOB 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 d#0nb*FRf?i_t{d#P)mo16NmJN=y|Sks+e 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%0D5ADM;l`)#_U{-+@HbasC%1mQi|6y9tf}7O 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 literal 0 HcmV?d00001 diff --git a/linphone/share/rings/rock.wav b/linphone/share/rings/rock.wav new file mode 100644 index 0000000000000000000000000000000000000000..12374c0670812e487ca2fbbb2bffeb69696dd30c GIT binary patch literal 1298680 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

    CI#`bnlSz`oMF?!?Zxf1j% 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

    wYSC9;%F|5m=23lpc3F+n> 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 |9yet9iB>w;iE%?e&dF}bsvrI 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 z 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

    {9`cd& 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%0A=1+q#P**!8cVDiqHHXTIkyg z*P#}Hc@(dE4C_C05xZBl(yvT%jhP@0VM%2>=y!Ay=n=cf5i+qpXLU=-vQQick!P|L@yTkqTPhWc16>XM(eC8+0uAC?j6P(fNwJ7sXuh|K~ zTfwA&F6@P<3AEPu!7Ne?oe{%r!Ed3=gU&*2^sWFugv5HytSyf4Zna!!)@cfq&ogC+w*pE;dZk9<)l+N^UWQ5!~)w%qD_`TNe4v z?`1{>>RHZzApl%^+5Ji}5Y4W$2Br1@H}C7-ASS8ha5% zK%Ihhn3kJGwKqCOKYQ?XUD4=QWiN((l>Mo#=SpzuM9+OFje4DhkI{zB9`ZH*Mvi~V z$6@}-!6{>6=JBeyV)7629*7pAaI{%LmbdEL<_XGB8%k?*kPR`8Dodp0B;O7s8BETF-s;5joPm@+TouBn~a?`g@aZP!R!L?EH^X0dl!PNoi z`TShAzrHdi7S^4*hOs35SSU7WYwY~6jQIZYNuiH9X-B#On(%5#s{E+`3&;2~tb)V;P02o^%exbsJY%iMe&>D@+G2H`sjh`H? z=1pd{b*Qo2G}*Aq7@<#dPuIL4aX6Em0aU3dVuh|6aWV>gDUMVtyI zradS7C!_-wb5kuM7~eF`+-c@3ZrX;6e>iUUdz>ioICq)U>wT-<3|VFR4|T)&k#NAr zP}+wW%M8HoVecV)V#CRsnJ7vgbt0*ga2LM|FT$=NCBc(uyDhue3kM`@Y2PBkOVuiS zniDSj2m{NK@CH+sUj}#!dm{D$|9{la!tb2P!s6idJZ>DGX-}CzS(d=U``+oGq3%x# zvshNw+rup*${h7~jeEofSE23$)MguttMZQalfmY&$Kj;h6O?Tn8Xd)~rlr!>lT)Zm z@fsq-?=)5v%0guhI)!+j{tO-#6AB~qPJp)(L4ePonXWAco@1n_%<-sgile#tgYAB+ z3tH6|7U|~@OWuYz&yw~JZ4>`R zb^Z7Qluf7y*q%xHkp@dKaRX$bcNz9W<8Wk5{vu1$lR5q4elh!~9Y2+a4IO3{^t~g8 z8spwCxDQwr^&Zj?--f7*okyA+@-1i;l^)Z4?@hOj>n38Hy%y%xfxE0{vPax(Jt{I7u{-U2FhAKn=$0TlZ8EwfG}nBT z*54n5KsS$ZX4GBQTN;zK9i2GcH3>%{);(x>@3{MKA-L~%EGnuNgfErC$?WA1ptE#`sDt2n%o6{Ngp0v9fxR5PJB}O)o`YM33`cK4hOmrb+B-LlsIZ-iZ}aPa#?C#DnA;Sx?W(5-AY|8Jn0!pc6DLE z_5T{J`~T$|Ib9=drH(|<9)cWGz)mIS2W%%D30jJ|66S_5qe?xaWAu*Iv7xT8$U<-* zEgO+*RXMQT3H{I8p42rC?5Lk-;dLp%UCNV~i{NR5yMnny-+z+i&Ca4WBHh>M01nJ5P|Ga6VBQ3+~eqau3bfpy))X68qYRf zRv_8~2Tt|f?QNEFIwRD#T6Y-RTHZQNw(SJ|>ZpQ-ca4CJ>HZ4((=*I9vbWMy**jiS zCm*dC4mcsdLxs!F(sxRpATs+rmZ*+2Gpu7V#3=<+#(7G~YMdSH!T;0Uhi&PnxDIuM znd4heY1Xxr53FnZ(>1$$cJG7!-3Dpb6$G;qM5_M$6qEMuA-LlAWA~D}O}0bb|I?=p z{E-ujVS<+Mrjk&;BQ| zH^{4yhY=r57H?liyNN^dZ+HWfDP<$QZ+3dM|GLLBbIpHxxm2TmOP-qGav0F6$gG4ZW%sZxN>|FbJ^gD#OHwvarJm9 zW-fpV3NS~>(VA723sj7cBb4l?fjy5O-TF84Mb&F@iS+GWMPFeaY-9Uc)?s;PsLL=q zo&|I!FX5CXld^xuNv8us?@m3;QDp0gGs685m3}@cnQy93v@CbTE7A5d;)T}X{S0%H z=!_Ap7-1f4o8TlMRX`2qB?RQS4@&5q>v>l;&!H$!w*p$Gn}S3=TDS6&qRDX0mw&Z; ztpF8$F-#t)MVt&cfxS!%W=_NugdPDbjOsDW3m7+$j~mn;>=|7@$sqS>fh3{?Nf9*1 zd@V2s7Z_hgyB@t6bUyHBcQf-+Sv)~lnFBxDmf<}s3f1nDBsRVsSpB0!!u>K%6;@Jd z-q*PSn5m&-pE^%aH~12gIpn8=W_Bn17HhEAXSC3aQA})5w*LN6*fRM`U3d4tdWpAw zhW2E4lHH{+f`);vp*9P%@H?|t5>TV=VV(`jgFFm5=9o{d)AB$RX@z#IjMKZ)k=b;Y znp;l`E^HnZ_@VWvUws7uQTZv$<$9qsl)as*R1}nop4aT`ncx0X`cB&Ic?=p)n;$xd z-!$?8yLJ3v^3+T#W^Pz7e2DM{2ppd2c1O0@()c0^9i3xy+vKiq+TUQdii94jcty;T zJ);ODgUCIiP~7`IA#y{X2#%MOqWHS|_%*I$luxkzbQcD|I!U<2nM7gnH1vPWh1^+i ziJ(KXLvX!6gCdZvv*lW1`$mGJIssV80FEj(d}Ob7w+F6;8zXLz_J@YC%P995={6^< zLmIEYt~@M@v2Rrmf{rss;14^4m>6wW)#_x@Kk#SqFGx9!q86T)Dp^tBvL1xsX zpbxjbH3dqKwuIXzluXCg)-2)xrM;~EmP@E92AIPp)|*561;^mm{WE^v2_)Jo8APX^zp6xLZ z$}Rnj&HBlaYcxX>tornD11OyhVKWJwh)DS5&_nK(tR~%m*gc|12&g09-Pm4l{L~vR zdpEF5lA~5zsGuyu4?zKcc=qNXukSZFYMi(HpM?QjMBGhqkre}3_PevF4~0P`w6g&7Zg&zvRw!4h?mI9H_8xiz+A ze>ptL|0X$*JC6IF9UtnXjf=A(oQV}`SiHU66tSaYUeJC;zW*oZGKLp%g~B7FNg7rU z@vm?ixgj#p&l{V-cpNCF1R=kAO}YiX2D7*}&HTKv#dBKx5&|_jk$b!k2yVnKS}XAc zyOa^h9qHRnzYZW!@cdJlPpl*;ivscf!UO>FU@P%9Kw*%;Tbr;E6%xBgh!J`--uoRH z)`qT4bORRfqHM3Q+kM`J-5RbnNP|}Gw`Ys@k@2d~=n@DcJ%Phd`5KfE`cx>w8MzzO z->}CUM`=}6t@Y83IVBIe&Q_=;z~&sol)fxrqV_TF2=F=TH!8>$2I5F}XeW!@BD!Mi zz-MEwa*&I!<$}NIQ;^dwGx0FbCCUbPrk@G_ji@13BA%fEUODKPr4sT&7w4C5j0>9t zxffH-jtRLDwv4G4j>66*Wq5%At!}Tz)K}ImZg|}wDZ5+stSGd4U5U11Ov4`=Q=37H zqy`4fiIoQQC#<0d2AVKAw;t!Qo2Qc3rZG3wj-gDsp-HCAWE z5!oWqvZic9K`qp2>f8$$p>Bcdt-sL^+(CpUAC+x1su5R6szN^^pMm!PI&FLUPj_9d zZ2SAH^z;{VZD8U4F1n~zaSE-lG=`n>PLBsewuN0psJZ@rIerbHiMWmNXFvg=V~umk zEKv@?)U?FBsRpPUQQxnCb*~reRXw5?4zQsM{S-Ad=n5?<^)2;u${XCY5C`(C9|CSb zT?Af%SPeq}t6SbX1HK%$3_L*^ZoN*@O|PjmU|iXDS}+-OEDMZg<)BIDGogO2L?A6a zGQclWFr12}U7#kyi>V^p6Y3J3i5j7sK~Pzyx;_C<^?t_MYjw0OEn7Gn6*oCD*D>Y_ z^fa272Bl^RF_f67htzo=iGIf$G>#eYV-|wfGSkkiA8Q~NryavIhg^pmsR2MOtlu-m8Rsc9b-Q}>b9 z4iKeRU{cLVq(yE$)C$<7dt<_hPIuV*iDhS`jOs8&ea}Y4TYZ#*>&uNbA#dr2Qo!~R z+?Aep!Xw_-!gkj$?pNz)3dg`gT~{f*L|LNMAa?6=MN`zu{_Tof(KyL15wh>Rh}Kmn zI^6kS0Mxrq);rKCf2zDIo3E`LII7*-e?pbrJygwT^*G?QuSm1X$^s5l>bYNfoS1Z1 zh8>H#uY$sCBB!0(rP35P@05J21@+vhL^i*u=r7N!j4aHpwN_+xZ|e7Y&Ku4CvDW<| zZo@m=fZAX5L3ZZPB9Z=cT-U8%{5ofG^p~89`;U%PM?K1K9QUZDGy3x$aa`RO`LzD? zD!h`XPSzADe(Lp-Xwy9LQ{{%9V+|{727S5liT7g2lb+YiyjNdOf6n=vQ!%-Go;Zfvr{fJ|RWCwIYJrCGjaMV!p@xD0V{pgNeUs@VR z{<~X^s0}VoZ#Vu7>Mr>6w3po0rP*b2!rMTxtl1zXo9yx@^DUBm`&pi%blY=>pdSp7%$Iq--GFx>ls_<=Y9Fd z0tl(g1Tp(-0STI&?h9tCv(M4&2m(&lKS6YMuEQ-Ux8Q3^Bd~K?_9B`T=}?jl4a)=K zkxfV@nnyZ?yhz8uany^*HK0$p6AClxLU*F`sK}+9r0tbXGzF@jS~GMvpm&VN`EtwC z47>fwNT8dV6$O|Rbq+k9eGT>rgG0c9_mQp66uj59pIC1j2`&*62ly4h3T_FcB1zOL zOGhpv<#L752mFH)S21Z(W9gy61&p=AV9px;5`Pw_$L}#Y%q4KWYrWo-`WN!f^>6o+ z{wC7L7)57|%Q-~801;|e5(~hO85nd9FNi=6%p{uv?@_k%7f?&-f2ejGkn#mK9ESjY zfG%}2-5Jha>v}uKe9-#Au+qFilV-B2zL=#pwj+uB!!stl4e&l@I3PUmzWXnEmE8fk zY0R-4S1p#Umlk#9sm8Vh0k<`#vobdWPtGv7e~dmS5So9!0vZ*vvPZ6x|h&5!UCY+=aR_7h;VtJA>%4oLSywN((lE?B;rA#fxGym4C_wi()Z>1!bxYC6wtXL`d>Ql4@tQ4{ z79trTI%Vbt|7+vy8O6EJb9!@Hv&Dl?r%g$9hMbEYk9@(qCD~8lwyXrFG@0GY+o}N> z{ST1Sb?p=-OQTkpzzQL>+Q*z6CqJACViRdDt(r}o#6u@D*(4&PT$h#u&tOaos zBHQAmBgx^1XLH#8Gi3M|L;O&4B1R+DuumZyh|Odtk{(tMGG!rLXGdPPXfy4`xzW+) zx_}{$EP5z-Kc*TM1z2N0<6hD;fJtpU9hj^zB@QBdN(lJV42wV{T8M8JHsOw7H zEk2eoNm>`VK({5J$k{`&AbQ}HwC|p_pert1bd1*+1a&nNs+D`42by16a%-FH6)k(* zXJmJPRLCcUD3C%{X5#!G4!;ltcT+Inj$CTf>&YW(3Yh zz47;;UoqV1k+^0|u||~*)ZD)?16HS>nemMGc(tM!6f2}nb8)!-ZTmgKvpcuoo{D`yi8Bqz6MFOrQkyb39 zkA>-+kO@|ro9|w1&jKC;&OwD9A0}+aF&I|r1pnFW!MvgVo7gk`SNkRUhmwBye&d*C zDhrXpdZMH9MhqMf+*U0M)VR<=b~GT!N+}A8VFQDw3-0eOlVJ25pP;&8O7$C26xNuyK9YS92>zUZYAb5upBzZ zIn@{|tr`&2zZnRrfN5sbKer6+TIIqHFn}WzA7D7sVr&&Aopd91FiAXaI)*xBI}kMN ztm#>Jru+?w*B9)3+7%@GPZHj>5E#`J%UAYi#-J4W!JoA*(sd)(bJ${6KDB8(_t_Kb z>uqx@I?XW^`TDyZnU)>4X7oZrbMQvmhU9&ujD(BmGXX`=g^&f_6+Jxb<3hJ;c0qUF zit>O~ctd#ejwW>1w)SC?cuB^>Th6T)!77DvZdWaS45Hi~lcDj(fopFJ&h*8Ah6YldV);)nq z-P?oO8m|iiJDWLX#dey){)WVWFC&zYiwQ>q7E_RMA6aoJ2l+QbmeEI}#yX}Mf3+P^ z<0>Bdp7k4cR&R+XM^gbjZEXiDoS)#QJ!5evK!udQa1KpIct(EXkHNNv4Tkv(_5F(^CWU^T0s;_t~9e{@rLwsVJ@v#Tv)hx*0 zRZV#asHHy?)vtR}+SK=XQHx(?R7+p$`gt0+%k!K>Yr-W?t=F2FGYC`6RH-J_SC-o_OUwX&HmC29|je#tW?&&QM}fyb`3%1 zyHVt0wtVan(<|THnD362kF<7A-< zz0Rg-x31TZbgk7FnD6WLJr%~hq7a+o>v#9We;6>Rjh7$A7gUV}6>E@wKU#IFTKDPS=fDJZ;I+_*R?@@U39wUsxu z`J(AtT|-M~XKn*r`K*1OwWhz;^Ip*fo~)mU57tP6dOG{EtILW;EU4I;varj;lj*z| zt!uT{0eWoJ!ecEvaT14|q4d6p+Uqin&C@RU@47T%?hr-y=+lNF5kLo*+V5$GM1hVu z8X!N7W8rr+foPhNK&(>jCap3x0Eb$Bi&qU)*F;y%sww{4*LkUup-SqZ*f`ogAjL6& z`VG2IK7yXiHdAg3dECBWMSx!LFyK971ZO68DWwPW4&`+wf%e+YJCm(9+4}uaO=dux%~2LAanJV$c$Cx*#}&*Gix`w+zipEuA~ko}a&Z8E zMQ;q9+82jeD{+IXH3;t%+e-T)Z?mBfaKd;JL;+iH{}^uGw;*;v0pE^3Ks{(aj|^84 zfLB!_Ctu%crP#7fT2H;s3hI=VLKe4D;HOGnqW#Km64+f)As%J9PJM)YN^fAM`@IX^3l~Ms*Cxi6cjd+n?>QQC zPD_qh1)304LiFdK;mA3sgYwxqQ30G=iCEsQ_%pm#{v^sAgwQd@da0Lhp3pqp8QhT$ zx-A)oXf;ORJ^@lFbI=M#5gq5Vl^@~)rr_Ahx%26*v+a~W6LSfPS=ET(xDSw0;cWaI z+LRC!8lL$Mn3naxsfx|FvjT27Z}_PJvvHlkc`$#|7(h;^1sq?8rwkUa4D3gL4nG(* zHRO0^Ex#utn+!{v=txK&B6^h&)A2c)-S;Wzh;lpgj`<(efvljr9BKe3} zsiTSa5?tgD%q7rlXQ3=Y5#JzJJZzI1&CWb`lyEC-*PslXJ!1#elHA3(pRkXyKjs$w zN>CYJNWY$xhuSof1Zo_a;rW~T(0wHs4tUJSg9hO5VIlB!QL*;;f;3q6;a3h(kn*DW3eTW0v2H+LQD#?H}n= zbhl_zAZdOLcoO9m8G(OH9SwWVJOVh%e(eb%?Xw;M91=gV2x|cjNW~@4rj|TJuELBy z@37!bL*vLNkndGi5+ydoOZk-**bHfYy4~bym z2u4kCHlH5xK6Fv&;@A`PRY{Y)5y{_7#Q0xMc*G@yNU)3$&w5WjONyXxz(DyE&~qc- z;XO$|Xw`B5V{w`HF!kQcn(5{*E#DkjEllVIi5n7C z%N@p?wk&Y#@M`w)B!99jXg9vjZx2%mSHy^%0Yk2u2C{D&{v}Ma{1?>X`NWihW!Oy1 zQK+M%1|_Kb%VzuRtow25$m3y{5T|d)Ju0FShYNXcd>gc>!y)7~Q2ayNMpBYR`S1cw zu{YVe#qBnST8C&>4KUT4>jvB2RkXk+HqXL65`V_7P(MTobq?fZLmGCUHH7lpGm5XB@kYN02kYDF4d{M%WeT!@yGD zLq@(g1ToYNmA|lIOE89??{+G$y3I(Au8>lM|yDd3cHQ@#&ZhJ1l+gud)`P7 zxhA!@Sa&tz4U>EJnvR6=&qp(hoAGxL3NR z@1rE6CvxCy*DLX@&MwKuPMqRh=Qt&zYpvYT`Fr48r?C&(`KDXYUexir8QvDvI<@({ z%q$ZXAiKP2A?*qQMam*RREgEK7QC0!GSN+(1wVq&| zSwF*gyZV=Qc+C-6RM(!)2IKIm^T4)WAm`AJ$;u-i#`b*pwyX6^;p+OH>WH$criVZN zHvjq{Y8e0HXv^06BKcJrAFMIXCcpQYRfEi6_)h&}#~k?;O>VbCWT}7Ijx86~mlR#A zm{KyKEVBA`CA#fO(=ky??;+)JWq|go@r7DtGsu40o5Y*6_r#A{UdfEV8Z~b}D@~q4 zpyN#2e)k%M(0kg10Pb)RfXBeu)=K2Qz7IG}#Z01Kp%RZNe}JfKeBhqmGtc}|p)u_? zr#Vbsj%OKamS+mdA2iyRf_m@NvL5ulq88PJdKT5jDCV_G2fD>q6({wRH4xNqLtuER zb?LCNCcvnreYxo&Wh+DJzkmB(E_(;%cO9}ss8RAqmg{}|xCBmy%p=w#^JF&W`a zbAxfS<{Ve7%U#@Ri#yl$n6fp|1Fv+LV}a=`!gg};)UuN`Y=Zj zcpkWmbkJjEWvMls$es|UrKgN^KsgEZ)|vwLK`y;Qq|1Gun&@>2mxK3*^*|$7$DAZ@ zYCm65RXTQn^}AJ$C|#)i(Yw`z^X)*MMw|nV%ovGWHs~(?Q`}oJFnkf!8dywT#q(kh z6IMbMn*X`WipJQE=FPKqy>GDET4A<81j4Eg`)c}_*rNXweO_}RC_^RjAFgj=oQ51A zj^OQrPL1POOp#@Zh5oG)1M!}Mj362{-W{$_wr0paeGjTsaSiiR*@-^oeo1QMYzsRZ zw`piyTx9OAz}-VxG*IIIFs9J8(5d`vz$9XoGtAgx^VHgH+~3FDjN*MzX8U2>a!s3` z81Rs@pZI}u!~X~Fe_`tlz}V`x9dX|q@zJRM-jLDejRCJ<{+u#WICBGg3_~HJ(8$wRwDni-&t5bc%o*k^pRw6<8002CWTGhI~n**nTY6jkH>A|9wM(ABBUiw zUqk;o-Q^cL_6_NAmJ>TNv6~j7``q(DDE>^Tdze~k%rkgq_8Hh6p@QBY@&&PL!H_f>Z1JB*7el>-z z>>cvh42q8P%;g*eIdFB5h2SRm3}-ENwRI1*($?z-b*(@>GlMOr-X8hHx-9jT{!q&w z^aJPM&@^vr)CI_+kdc^wf_Y@HAk8mN&`moUAmcsbG{rukoXK1Vcc!*D4@DMQ75r^( zCmn@g5C;(vh3$_OL9r+3t zjq>pbks?hBvadM{i7ry1W|XS&7kVXhvNM90g~tUj*u~sef+Gw{2#Tr>y+hm|3?-%J!sZS@we%jmz+kkEdD3nP{vG8J4M-#Cd0d(q^+vC)R_P(YcOe90NEcGvM_X$Fg$hXT<)QH9f9$W=`a?NoR%2vX2FX#LSDT<*pgrjWgy1 zfRq_z$JS`N^_}pv^9k!0xP>4GU535WZG_$Iyh%OMw>oS9m=eEOzzTXE^8~p)vQG0R zxL9^1s86#qXuw1jezmOR%&?)zV9!~2KO)k@q(8794*un&M-o5}IbiTbZ=(62Y_h1a ze{+XfcC9DIa8>%(=~j!OkBtxTj~qf83Urp)4$oy2;>#$L1q%t!(wyjsVW(m7DgMBh ze6!0R*K9iql$dAR-#gbB2C#I6lQ*nqxA0!WH9uH&3d~y*>$=!_#QtDlyZy8&*4*QL zuZDx`G;(mg_d33x+8Fe~|9L8g_AqfTGA;0pX9@LztsmR1rKJO);?5+DP`40o1|I<3CfA6I8NDUPd?f-n=3RLR_)b@qt4JMUJ7g!A zrb2FO)9{OQp;W1BE@lANZ&^k@B?<%Ab_S?bJ^uYo;w}9Zl4}EhWo+p-%TMV?a)f+e z^aK?>rB=5!BG<>{xNkcI7dfI_hkYJ_a)3v^7+BovaeWbecH}u`BEOJW!X>PYNovaK z1Q)VR2nX^h0S*j2!1UEwt#N3dDfPP1s!Ic6#iw-Cnw^19Vx~n6|rrPrl9_a&Dhru z2sa&r{{W=p4j`^m|Kbd6H)Vgo0p>{IBFu?*}ZGMIZ z^Jwi31446Oo2vb;?$dRtj_R(deyJC$4l5ogw@LYmR53wzwD-lp{!X6gV(YrT?MZIOVt(%L*mh%91brb(P;+>g(~9Y0WGC4QY~;G&FDPSU)gW zn*ms@rDF8rxej<&aARxxr+2Mw+9#8n$G@c3HoQMkuK6e~J^Hbr`03~O-~RhOJMU=a zt;d3{#@A-$&!5qTqM}2p>eBh$|Et^`)a~8j5lo|COmbLhF}{QaZ26rVN}` zTu`dy*R}g)M+_F}Fm09$+-Z~!`uj*a>!U}e`Y~GNsSej&?g1GmD&x!!qu9FHInR0n z)S-kTzce1jPAE2E>&o&_g)Ji?U1E`|Lp{%`FQ_2lyBnxU;+x7j$2luFO#gd}aCIJ3(fs==Y%E7N9HABo>ow>>1cwT70~X@JoC zkd_U~c)rnU?Z4HC-Sqim4?K7B4{*9>IKT>gqZ|b=xSV`|6U9WcN!tk ztpwexZFl}H@VCf^Jtqv1%rw$Oz>uKga(VU^* zai$WM!6irn);W2StyyuFCc1JCzR{r(3r>-->tmPT3B?JWDMc z0m#SspS8tTF_6`?aZ-vj(Cm#=a7S1)SoI1=|O;11;J9 z?u___)_GiwAsU;Zo9^ANt~6z^DbcX4fsCAGGdP_gWiZq=F~B+@#YKu$JB-tKqiN>lbAUz0!k*UEN!W&X8DBIpITdSVqOXFr# z(OlK-!Jy?93G@X0KI(RS1woLpg_f6+!de;!X9=S6{WKxITm4pYmOg3^&_ij(sJARY-vwM?CXwCK`xPo`=4s6A4IP}e=+|A4))-kMs%hF!OjF6 z=B|anaEZ1~v!_cdy;A!|?hzd@u0vjSrwDXVUWf*Z5}K&^fLvCNU?RsN*e1y3RmZl` zwq!iS97+uVIfEZKCs02*ijd77Co~skf(GIm!S9JAz+b{B*h1=KT0L)EkVSAOcrkSf z?1;!hw*V?oTV<-Ch2xOe!szU{2{? z3SI~}PlyiHviPIM37q4R!PwF5ffKVI_#aL_MePoIk3h0~9v&mTc1F_))Zy=+QLK+8m^Iat@SD83M5&;h zXp7+!W1~ofnvjurWKc97C8)rA*ed)W`X*nd_y9dQa%0q*)X*_g675s7!g9vm4}hjm z_D>AQv&VA6{lp{%_624MbU5mOmjmDJdEz(@KG^>TQ`_M7o8BSzA7U6EC`8T++DShw zxXuq^JrBNylts)p430yI$;mkiMB03hHf20vV!}_>qDYe9O`s}N#hnmGWFJlPvJZz3 zqF*G`f{Vue{QeHrL;p*)JKlu?Y`(RN8S6(=F2djKI0Qe@wBAP0T0N{)UUgG?sN=6OL*{kO*4~A*+B;AK z#7THp>?Gp+5hjBFh#vgmWDzbx=t1ou{Qy1yuJD+Rm>pMq3ITi)*#W zAX)N070aLs9iu=?|zP+0oND>_==9Vep?$P z?3#{p&L=6&uT*D8KC+MZ>L4TSkFk2oV5HnU#DX&C^{+N5Ixm{)#JkJ~^~Dyc%VjMA zzOfa8+H7BuCvB6sZfi;M5^L&EoOK{YXtnSkTJumdY;iWRZKop3{<4p5ztOqfN)@%* zV9rzUxeTu`C=8WF51u?+!?dIvBU}nvgq%%Z3Q}XnJF~z`O#}92+FE^*W|8WPK1?yo zZct=_QCbB?Zb_w#15)V8=zsL(q~$b!D$Os#&qAF-TS>dl@Moepxtto_L;niFaDQ&# zEY<^I9aR|+N($ypA#pgdR1o(wy_g@zHgQ+^zs98nSnL~xw{+gX!H=>A;fQ>HTb&yzaR~c9WaCQia9noiP9N0nLIb@8f7iF8@&$+ zwM+$E7N3D+3@k(AjY+txfC~I;!~@DJd<9$0$OvQw!NV6tVgT28ZPPy<}WOD=;TOH$iIq4BJ`5Rqaj9O=Y7hSp9AQpawV9 z_ofw+%J2T+f6cBYey4QLFMlDkwbC`WdQKQWizYjNOK(6QX>Z}9z#Wvy0e46R>93Ke zvi`bJQIiZ}GFQrT{pp#hl8LZ=m#px%^SE&h8)#c<9^svphe6#H8*MwP-s%SGA4?~< zPwjZrli66>OYaPj9@o!uW+r$C=iV2jcb40V{o35(Nzx~u$8<@*ZEg(w8&?-t zJh^^s>7uH?m6v~|H_d(v>^t)wqdr_%Xbx^|wapr+GCx<=sI#?G#ana>J10qZ)xT-j z@_YE-kI$69F5L%|?0878)xBgi8Gq|qsyn(moGw9s8Z}Un#~Gz9V!qQpp`2D|k-**~ z_H&J!2maK@)xGUqRB*xM_;}9!-}@+Q@8>!4jeoe^h>F}MME#=bu%Gp#JGhTt zh!(#YtN2qwSIuvqC%ZQAU|^AYwz$Lu@3cDs0$!7do=`tOaCmcP zXnxmS0a#&WZZ&-&Wa}{?QTJrs(TY)$+LCeFb!~Xq7~478SaKc1%lUwVGr!uJ{Z#Gg zw2r_2e!IS{!)N?NfDiwDV~i>LG4P`?tBWmRbS`id^yOejsq^VQb~(Er!lC{^d~ij% ze|DIA=N9Gu#TU)~u)eYRd!*!Q)h=Uo_j}iVO&c)F*#W^qmq7DTGeKL?GG`3@sfpn| zq#bNAs$#WMl~?6=<&~l)*@(Ve<$TR!-F#HB86wgKgdVvp#aB8!puMA z`{m!9(Oo}DW9tsFCzfp^=a+dP^J_QwICQ^E1j#l1IK9`{RC_LZvYtVN;y27KrY(x_U}JPw$O*#vX`#jn%yQyWKI+@)|K%wH6cQ zI_(KX-jK(n1YFLZUWt!p&x87Cw4}{dt>s|5N zU;6FOW9^QbXmdf=bbGsOf|qGHf*?8zNyXqv3^{5Yy%2Yda0E+%G7+QfzV?Fli*>r3 zr9U_DRDHN#tGwS6syyAjN6+i~1^rK2#P?T+Mm*8330SQ?L+IB$1)kP?v;I@x)VXw9 z6nDMr#KC^_p5a1oN1A^^=U4pOUM1wJ`~#rSoa!k8p0%YTYc*RD8tF>_MBDC~3E6}! zqAw4)#RViBrah0{g1;fWgtXGZ5C-9{dmK`1kwSWPkKC74Zxl}zo2t`PYrd^F6#vL@ z_thVPk5i1oWw<^N8xYlGCGjDV%~%bwbH8hz1weXN31)~625<~!{zR{b*8z%Wje)!* zbRpr09x%$hOS7jFB#SCXY7Ui8vz=}wf~sZ5&>zj8Nz^u1u!x*wgy9_bP)&{8>=PMgPx0+`mx7F2gE@;+7>gZP@-p8u>_v1d%ABKYQae}E%GN0dj#Xq#_ z8H-lgLmt*#h|u>gcgHIR%rA7idW9?UHfzD!ujU5GotT&w&=Io#2Jx!D7Q zoRr>k$(1RN3EEZO1D4A$B3J`jLVl$`FF^N`qCNfAxK{>F)B_+;C_&qOyOt*u79UI7 z7JiKTCUm|3a>gM1I(V+B(Hq|P+k3uyna3s;Iq~v*_i5!^DA#g;xS#mj|4&M9IDJ}K zO!b_35nCsx@VVK8C}W~7A-=JApqcn}-e6F?cbD>sH?QiRcft1+o=GJeTnDvVo!{7r z?%b5gK-A!0kcH{7kY6d$;A;tg(d4LwJiU;Tu$@tv%)`D9zYBW9I_fgxd!4O_ZGd6m zVxRxCld#l$mYnJGF|?MrG>-53r{@{KKZ@f#V+;943!D;QDVTNHoqGdR`hfl0&d`ve~|nRE%3Bt!vCTZvV%hBUOVM=b2hn0nTRUMDS7QF>Ei*OuL=3+P`tiApXkPr2jK? z7H(0dQ52u<9;TUqp}QMFF|Z4}u~yeu+tszZYpu1#4n#o(K?OymyJG^F8K#+@VQTps zzUTd(d(S=RcRc@{MJHw@62bSpzuSLex4=k_``ou0MRc?@GS=OH)c@Gv9%_O-7rsDy z(|Xo~R(M$b`wv-PDjvF00VnWkQW}4V5fyrXi3~Z*Jm7zU{=(ZxbTMa+?w4JTMC1{p zX4JF(U2M=?_}Ml5M*-YKFL`ArG-X0}NpIjFma|w7aDh#NF^iHsu6D>6YsH^EUmMar zmxA{)c4GEZ*u=F&9=Q?o0ow*z=~zB|Otw#ST!4_CkxX$!3~$0bxA@~8IiN@jpb|10 z8V#O`+W}_rd%(kKc_7{F=kBSK6YPUw2P^_gu4y8~(|q1K&-zV!*nU@*>kJzh>w+s8 zU;;48!$I2{y3y<07=mYR!e`3OKnYRg$;0jS*pFC^T?g!eJ{=iN1Din>e_NkHKgu3j zk9!C3W)@@Z+$7pguWc+cPss3NPxfeItiY|NrJx^-@|%9pqHznD;iU6y4DC4YjVIfC ztk>V(&wY};H~4A1?)bgqb@;7fxA~rD^sx@nb08B~zN%vG63JWsLDNUSf6)*`DgNt-FX;kwDK#E@jJuNhE12#bAJ-JNIbmY_lZbcm{`|xU9tG^P z0QHudj|89>Fe*UaQCY5|8Cu87^g8Fc=((h!3*5N>24 z;~%fvh}rl&19QdGK=eeo&5NdtHL%`e4!jb-g4MwZt zyQ*KYfAG{GPCU|^p==PAf{3Q&bWdCehl{&MHEXY8=G8~S2)}^AEc5 z*tNW>q_g^cX?Ojrc+qg-YuU7>9L?OJGQHY-NM{DVQG3Ep4Xv^F^c)=6ST)ZKa zaYK9?u?}8aUw8GVz9IhG>89CV)0-Za8tOH_7S|M3%PUsaJ@|3EZbSJWwO3k~*PI{z zU6YPTt+yiZ&G+oo_Fu{gT^j}R?#Py*Zf;d|7p63+v$Rmz9$m1nz2(D=c68w=PNn8u zU$qLNPeGl>ImrjS)}d;+CAO_NfbyiZQ20suxn15J->{>8O4X12@?Xfu*b4rWj;eDx z*^QB}E_XVjaS`3@0>B9U%6$jkEM89Z^I|uuHJI>PFaT; zppV7*+OPTMkIW3(CR0W<8urQ(B#`1RnbS5`DDRf|%302y$2L z4V>yIw@-3U8J?{z6of?kNK6o$o_zcv8Ge-reVS+a}(}^m5;k>n1yT= zo^)+02_Ihm^qx5G39v2aMSX+2jMw^4Z>6|g%P|btO8~K;53o0oC@3Ft)wKy2Yax#W z>rY9q$^&XPw%z~S^YzvzM#1`@3%;^i8tOj_5A|V&cFT6CxZ2N}CR4KR^XOF+20Ui^ z4#gUhU>Hpq;KGp79zUo8m5E^#r>NAsK%CDj9(Y1-l}v)YA6n>GYH;Xhz>dfT9vg*! zlK*SZf$nM2n-4dwQM=n`4s8+32ac&9^?^-EJwMD-hNigc+zRqFd}dHOp*VtuJnHWT zf>|niDmmEHh5n|#Z1a|tbp6>sxA>_5koQO5&tmjIe%*kEE*$N;9G;}e2F&WXjXPfl zVQg&){zLPDSINi)EnBoOc>jIOE#u2MT3+Z z^vdC1mN0XG>xexHvLE1sSPY(thzBJ>rn_<-MI(<48*OWq&uul5aNFepti@;0Y)qAI zHp*pN3_(L}dbu>gzHRUv=Kh1EQewdz+zZDB#2Zr%xK1A^zV8Tdq)1k#FIYkWp=^!Bj`%^$sv_XhZOs!#cR9Es)lf%bbmhrb$CmX*j(sto-H z8$<}Bb>VUVliXg?HT{EqV;YwaZf(ld*!$j@-znN0y9}c(R<=e&C+HuX9|KM{~aMUJ_+a=KF<82mE&245(L+g4WdEO;0NIM z1d1cpi|Z2ko<~=BrqCV`D(NcJ8jq96D#D6Ug<$DW5TUd713_MzN~o;*hAHdHfsR$C zxCULxb}qTpb%I+9xyIZLu7$N5qfIbzjA3@?KIbYa7xok0g}M?_gX*DwX? zlrwx09((b<7V9F_hyuH#36T?GB}FTC#u5YYcMeHnkxWd+j!t}aT~l= z?L-wiS^#l`yZTW6L+$RUH0!z~Ul2H{0)9K{Fox=Hq)hhA;g6$ff(j@r7QhGm5uT+n#*kG@;&+?g#?A*uMnJF< ze=2Q|o9Sg{;DQ{q@qxD}K)L|Vann^yU4GLFV_!AJy{ID`K5fVgGtuB8ssXzg?^sGN zWO{GFnuP_yl}nI;z`2vX{Kqy>QDL(&*(@&jAd2LE?kGj>GaTpp>9(cZG!Q0u+qS2= z03+eg;a2Y)Fr5w^wt0wp6r2Mhb?6B2d}MmyF~2);7}lkzNc_ZLiM7nHu6qIhKt(2J zVZ|=$?UrN=eXtd{%DBvq0Is#IcdgRj(mxQ4lBp_FEfdNf!FaVd2N>B=9UJapoD|Wepn89jLJ9YV{sd3b zRymTbT8ka9Z&(M78`42wN(qGF{zzI$8wtAXb0KB9k2{6W35z;JJMIS{=CHRTyC^FG zd$BF%Es*ir)ApI#GZvA>JyH(^!5T^VWD090XBQ`*AIBN?Il$V$e@SMz3dH?*W66jDqcBH$9?I;<|YQ@a7F@qICyU-X8~qAJJ#6AWDhT3 zSRE8*IVOhvH|@Gt9d}eU4N52d72j|DD?LU^9Q#PNBYCTBVoW(|c^IA+9`K7>=%otS z={YBs!rGQ5V82TWW{de_@NLL8bFTB#z(e3~@iMegbBru-YUsPMli81aHhWi$hxt!h z*b?w!kusRDcuf4exjhrFjypPSPZ%&Q!Luc3H8zvc2pYz}at?R^06YB!2zufZVnveC zLlv6i@hA7OhZpUN$9a#t#Caa)Fw1b~5Yz0p5#eGWc4gCK@{_hh^e?h?EUkm$$snF& zo#hX))`y+(-0#~?K8Qc>sCEj(0rtyncA&T?6Jb-lK=;`iaB;A!SEuEn$@Ix!($;*Lydi!^)I8$?xUJu50L+3Jvz$3m7=SO)r>0oWX46Po0KMBfy4Li zMgJkXf!HI@0DaQ@J6xsx)VN7|EAQ1X|LIJV>=VsV*$4x1Bqq>OL#zwzTsq1PdaYid z$?pEuEC1Hj-u%ie$b4;4IEn#=t&IS4UEeE9qV$)oPC3JYAFgwbH@t8Z8PV2jhVbDv z+SAe-LlJ#TMC;pHJI*v+Xgb$8sW!gpP<2>yLTg-ex~i+O2fD6)C;nzlGc=*fYEb@m z3>5zcb}Xw*sN+_}mpdw@#h9v{A6pxieyHf*nx8+iv~UZ&?E5ER%kRy)WA&i^tmcOu zQ(K|UuiMYmMs!D)>v{ve9O{*Ss_D)y?-uzi*=vBE+2Yd*DW)3sV$m*F7A$8MctzE!`k~_7?;#oTQ?WX`4E^ddW@>oKW8XxSPx6?gVBO4#FBw`2!%Eoe88+UUNpuH#Ou2{ zjrxzB3-$AQlhs_oufer~xqVYbU7h^{9_``Mb))SXz27oL(DzUK?!B)UJSi25KQvbi z_zCw9v`T{d#}AE&S1B)#VneRVJRAY)+apx9R;KPdSO2Z7;``E9?$YZ|FIQj4^K7%0 z&J@))tWzH88Ed{SHM&yuE5I9^dq#6t|2lr+HyM&SC*<=&BE^S7vU-P^gg!KAV!v9q zTk4cG$Ppr$fzkOD3Tr$}mRIJI&A(=#E>!op%iCa$AGh>={)jT6cXvqkf(Viilf z+YE=4wc6Q^4SgikiCO|Nz2+I=V&@Tb;m~WS(y|ViIqEn)=-g_Wtp$oNOYT;U-eSM+ zHod4Ua-QuR@4hj(&ACe1;|S6&cJDQKKmu$l5P0`BBp5sm76)#3G2H>C3zi{eiDtEA zNP4?JPkdy6D)yDON{WW0sy_LMZj5}9&R_OiIe&1vJh4C5*xt`Ur^q(2POA?wQuJ6< zvmWjM>cIMQD!n{Iw!DA2;z-Xy=b8=!ZF1*jKT+RQuc?x$#L*WC4Axhh=b9NBf2&k- z$}+oey2;skS|@Bt)*Kv2F|G!dp$x1W0Z8A8iP_v~(Ul%}&fn;M^jgq1;J-GLHB_G? z-JxDpwNH8S{TyZ2C{}sr_g%W2_6%#M@-6TW*E(b_Iuh3Caa;G6{;b_XeOon1jB5Ug zaZ9+!i`JL03sAx6wABk9q@+QrSVHJp9va@o7s9i=$;jj6WLS||WqIFi5}s|~*VVOM zZ+P3kOxdORNiDQojrtO^trfy&}Z0MUu*o5sN>T}kr$`Bf)+#}ecxlT z+(z9fw`u4dzEE)qFVDHL4pf1lE}ufq7RUI zeS;bPjJ-S`QXb2S%)=b8bOEOfOadEwyHU;3Fv4y#kwk?2B$vHg?JWmFGuB29)n z?^U8p4|>pjFiI{^#V;MTb9=%f5_XbjNB_;_1h;VJ^G@>NwCnsugf40Yr2(bydl3q^uhx;Ep+UHn2%@>ko^KM>po+DU#gi4z&CvJ-` zWxeJ1MO9O-OvuOmn$V0~A72KZMt>w%U(s}ROdid6^9=~5AqOYHn#vbKqlPrcNm{jLuEY{R^x0!0H?9lAG z7i5%(PrqlFO4R^b$q3{Ok0x9@{X6LvC(}dk1!FDaJqVq`=*jTH?U;rDT^sk=0*;It zPWHN_=_bdFtb*54ci6u~;PgH53`KXy!9gc8w!aDW?*QIiG1O#s4fAwmHmd$N$nLHu zexTkC()&e^-{)I08SUAgT0ka*QgK+W01-ug1X_UTvY&MvGVPY95AUt(QUCaOR!1lx zI2Kg3BH{)oVBgz#fDRZ{hQZ<5){?zD`sv!Cy__Q>_r13}3pnlCWr&`^FGC9z`c{_0;MM-3pS8%GIOj-v!Wf;S;LY&?N7aXr2$(*yG%{sXLsKijo~^vP%fwdy&h znSify0i{5E()$kqo)aYAi9bD*38m>*pesPjSf@Q9-u|(kw7L`sH{x9l2&&#ZvK6v(Xf4=8Izi8%M zejBZsOQs}xg2;CnVj_r+C%vO>A?MIPr$6--pV)DzfsHZ6BAs*@W}ea1P$3gqb6b@V}gAACi4x{;84 zU#(B4TNkA%QF#f^Jm*FP1%3(0jF5WUV@`2GQ#{!(#&>u<9V7L5>${W&MXYdjSdN+2 zS!2-+0A|Q5M0~0W*O9oAc_r*iREpo;+57n+OW;0(i#GF{XS%r$Qs%K7fyvY`W)Nu+ z{W$HLA24EjJbdP@S zpw35zlTuJW@J~q#k(YfU+}fy21_lF1O7Vq_q1rA8)RyVALCm zF)a^25QhGIbHO2a{T2v%|H)ceoTj>5wSH7Tgmm2Ro>SY@_0Ny;8M! zUyaIFSN2qVYFsS2DI3MffWQDV?u5Ark*Toj0HT1J%NYNr_+@!!%epfd&YMlw~HHaB~JHUGe zrkjTPP=nB_h?=9H?&Llyu{}n0eSgd}e11G_WKRyth1Nw| zVV%pb=iErG=(%N)Rs|>-`J4E!oj`G!|8$6rg&o7X%+fT)`H~}o^dF9A2qaTs5cXPJfTUtH*cvVB3CVSn~?Hsqr}}ud&{J zyD4wj)GC%KyIcEx`@Q<0L&Ww^^8IaKMa{r<{aX817!LE2@dkHfG{4(TDTVyPo^{@E z{WeVLrz`5p69>vaSw(4IE{S}9&F{iD{8_oSBmK*7arw7%IzfvD_*jM6`HTrh6|?XoY0 z`nXSkN8C-LIw`^cv=HTq+9dHF*($--{-weo(XRg3(JbF5$#I!U>68WzZyy}i!o;go zhXigZNazxF4D9b6luwZFQzwH@szLN5NL2 z?B5D}-!qYB=#+S#>PC^Wgly1x$)GVs$x)KEM+Zd1p?za?$j(TetL3nc)!d~U>dG@* z*L`!Q5k(}TUsOQ3-?6Yu%!R%!==F@bE(xwp-)hfO?C%{bP55?4lK=UWR8mG5I?w=B zZ0I_qxhJNXZ>o;Cm)JAllTgJ_v4`21#F*4mKpWSTMVj25iP^8b17AHd9hwUXf;OXV z(0HO3>bHZs1$&(PNq7tp5o@At@0Igd{rHv!!ee*gsz!l0*k(U5N1 zV^{%b8REkzj_P0)8ZRrCV#YR}AElGsfIc3I#{@WylUzpyQi8r}rO7(=Y}d2Mr-!XM{7+u@8JBW`7Ldx%_ZU_M-VwZ>Fk) zdsF}Lu8nxi*yZz#*~^FyViUKF@kdRX1c6OW-vXmW<)Yy}PVx;#Hq(=Ej{N}|&GvBc z8NVHCsQ2-cc#A`(rw% zDirdLG7WFG%_5bfu8_A;OR4KwE7)b6rT!uOz^JZ(eTnd}@ky-688Jl>I|9!HH+v3v zp-F|*Ce$(P7Q_ma9R3Tn1-=4P2d%-RgMTCW!0pg-z;k3WXa)P}D4s1F{&$87sZXs( zw}oe8sJ=k-YR_`SUt}Yu42k1x1bm5^WV@K2U`|N(wXP4{=2G%};Z|xG;Q+3ZG6ele zD|g~()6G{r=!Ohpg(Hu2m+JP?MCYcyAGbS8H|E#^QWS48+#i{EkzF0yQnJlyPH+~mMhxTRr6QZsKdE&yI;duWh}whnuD{Ibju+W-i|D%2U!b`Jn$ zc=R?9;k|bH62GHM?14+?>jREY-R)%=6XIDHcHTRO^)lQW>5ADnG7vIBN9JZ}3&`gU zFHlrtCb+l10a{%5nH123=hE~lu8Z=X-0!>GwZ=C=#^GP=^zw1EXZW=Bp5fvoH>q0n zd;AQ2Bx0G$+mbzSr>9ktSN_oa$B&h$H!a;1wqgVA?MNB<$!K$2DLk2Q3b~ZL7p;>!C^sr%ag0CvX_qWPKq7L7HB%4=_)IpHCjm#pMA#g~r zIABXBmwB)KPfSTq4a6jiaFNU+(@z)8v=?#%Jc+#AW80_`_I~mU{N6Y@biQ}ZC`}^E z*$BE}nd&aq?sgUq;q*R|-E9_WNzpMyZXRVQuJ}#Q=Q>HfLwKt3k>rGd6_B%a1{E+E$f9$=?J>F{RwIY2#xGZO3m zVxWM5nhY{z$i^KQ9P!+*`UB?$xaKwy!%YhEY!w>2dJsVXOXTdihI2mUu$eRkh6`*% z$`zjQl&;sX2aVm3>=wKGWA7|mxp>_0P}d6KxvIQ!ukYoraw{M&*L8`DFBv7>?>ywd z*f4cKOZ?Zd1F^hGq^P)Yd13ccE(eswIoRhzDfoTdKER)Zt)|JKFl~{Aq%F};Fe(g( z9sM>ER1C;Pk3f9zFQF3rSLiVAPk0k%82KJ~1+yJ~2mcRZqsORco24VEIAdvBJmTs9 zjQV)8q(LMf5ro*SkdXgy5a{064t6qgsW03I;6FRW$(Rvc1YQxJWunACu^1vlAhQA= z5U=xK9FAv(zYqIdXgVh|YAsJ3n-(gHgpR++CC-pTu!(TpASp;qwl$92HfA$L)~U(G zBRgljcKkKl0HjVAq5hfhigGM*n6oo{zW>2UQQW(fSF>J@Em`EBKv+TydYn1lE0dPP zIbq7+4yn*Qe`6+hgYztF)D=$fLFCv4xN=zweV>HyiypZW89~06!0~;OxH3!<6Bm6Z zgdbn&^EuAVxfpcRgH9RaUJ3OcS_xe&j>i`bFQ$xu@uRn{Va6fS6R$r!_J`2u(_>$= zV-kwIe#QLZ-5G-ROXHu7Im)b>%%bd>r6O1+?7<$3X+v%Htw(HNW~1g36Q~CG?%<8i z>SUNd+Y40WY_tcW9vb{P`^-}UMUcC`EMkl2 zPtu>%P8#9t;PzbiCHDiz81q9_w*ud^P<_9w z*iu-&)g9f$2makl1yBd)0MZnX!7v>O`P}*&d&%8^+YV-+j(}zXfQ|*m5PhUPU$#(8 z5Ek@(>w44I&~aSI?~D>Bc1;rR=}HsUblmGfwMBJYYXP^`weDzs*?ys!+5W6$VT-j@ z)ON1DL;~*$a<=urQANF{LH~5$(#qOy^bIuywybRUqb9v>PI+t9zh9A6-wT(v))wAZ z9s9Ncbg*I^>__cy+kcJxq0E-tp3ALyO~Mvl<;*7Fx6Zn}d~Fr$-MruOqOiK0)=IHd zJH;7hUxwXoUIGbL`Si;M8j6ng7#}Zg?t1j7@>mZ3yZ5UpMdRM{ijEilTX^_KQts-8 znjBSc;N!c}##hti;F4_Zy-KEgunB+{cRe6{>CXXAQq41c&_pQN!h+uVANFss4>xmm zmO*n6JsCNf@(Vc^l%HP?E9Vrg)Xc8o>*n_L=}&1Yh9S-;vNK@6zTa;n2; z1S~yjo2uPs3pd@fZ?dg%!=0}|mF_HXFMtNv;|{ZJwLj9zjW1>EHJ8N*`INrU!AC-# zc)r$eXba+-8^S7Q|LM6iY$oo%z$RlS`FS%$n_m3q@6wM4-(X8FJbU`n^!jX7{)d)^ z72i@jS9Bd5cmasl<$M3_;zj4f4#cd7?Fi|0;W!AB0mW1SEWQ$%#4r%meOtS-Z515X zvDP!C?9U<=a5noBF(_V+ z^-oy}n;Yf}zR8IMU_CC_-eT5kPXInjuri0p^%F9%^z~Rp^-G%pSKQ`|YeB*84%MK0 z?LN4PsMWX=l#5sl`!!}7?;^&^-Gl{l%5fG}D&ZbuKY57qfu2n?(TLdfa1?St8;Y>=kUK_R1mmvJFzTxKdUC*^O(edV&=tv_eF=WB82?oaWJpf;cq;t$=Z1>1r^fT>l4~yQ#u{ihp zC&4|#bf~20G@?H4y{{sp?t1dSZQrTQ9%CX6dek{RO`hyPKhi&h(lYvEBP& z_-XIK$U{E(nAiTUsBeMXP*K2TZyP_Ja*>Haz_15_8lVuUc9g*jTseefXdwfHJI}>a zHQY?5kR_q-rT!u@NH=jd+(G(mY*a)7#y&0z{brmG>T9%W)JO0R{)yTS+lBoKT?1u7 zG|nve35$U4ZK#SA=#Qq&Hm^*&?${Vif}CKNqY}uz_#RX#p#-#taNBkkXV7m%YpkoW z2I4#(GuS_s5qoadm58%5j`_Ez%;8QC+)R@*?6_a>d$8HcT-U|gyOz|ifd)tUd*k`e z368fa7aZyKC9cH>U=!JMY%}~X_dgHDc6A5562|dTHRTkV%Nv`Bnu450xs1YaV@Y+q zd5m@s7f}r4+Ws{;1&O8$t+(y^uB)IFxeQ(oK7m#QR$#A z&IkanR{?Fr?V*$09KKC?f?O}a!&i6f-OAP`cYk#`Qdpl$J)yeHEF$LM>wQ|xZtoQx z`3z*~SK_0RX3VBL+ zzaV^UUmz?u0lWz`8$yQ;!N~9^gdQFWI{=RbbU`LqY5^H)KhUnhT0Bo!%5M~ghbkli zd|%}@;#}oZ;4RfkQ-k$C#eD2nk&gMZD~7(U<0&e*Yqx!%cdgn-Y?Zx~UKl1B-vhUy z@#sxnYB0%vk6|b4m_&tk3ATaz`^ug71z>eiUsBE9)|>AVO82~^yx#UP>?!5W+yYw@hj_iR)V?sWZF#^tr+>#+<>qCJ!at9Aqdm z``9O$ce%eCGF^)`XPmbN_rg>A+No#y$t3Mk0-O)Efenh632WBx)3ur(my0KX=>p1)Z@VuBj)>;F#|ou z;;gO<_z9LRG^W#&y9Z|TIgTw01dv<9`skZu={##nSm3R3HiHsoAWPuBK4Rz1T&m;-D#Y7eE3;fl%gzDt{P~eWgmCaH>iy+$vu< z+HtVHhcDdN1?Xw+QgsIR^mMX&^j);B;qIt*L-(1M-0sY#zMk`ScLmZ4Z{a}2nBKqJ z2Rgbnb6YPvS2rh&ENDKi{?ansKc}^;H>`=?QC%~?{&pSyXS)bg7-+?OpaHw`IxLm> z8)b`%&UCH#4sJk|gMX=ib(ef7fB((;i`}@R<>An7O@(d?AVrk|SUjNA4)!f>_3wU^ zZ)nYZ+*{ZBXnRHDqobvHkN19C^kU)9Hy^fC8^3`o=hWpCe(p|w!5p}pvvCmpYJud} z$CcXCWkv35wPO)0ItxMnNrX1FCf=}lC~NR`>-%zNdBgL{>f?{;0|7aCHgZm*TaiPs zje9#wr~I0wS>L!(eR)7HyQQV~`RWDjWX&0YOp~Drw;#4VN8wB_F)Vej<*DRatEcGr z=ei#ByOQ>(&tK~2elu3w{dTUbsd(KNN6GVd$18kaeQjTre^aLXea&#WC&T(dw%lY; zO;ukt#7VE&jt$H*-4T2kWY^DZ&HLohD13RnZ76SS5B+CI-`(cnzJ1;N{yBoz%BlTJ ztOth9f{5B_(673eZihBulpbuB!CWFC6<^VpNy7_$NvDPPphx@mj=U67bWLjR5DhX{ zu$ffa(u7l10Rj55XZl%RTNDM~E)FiNSR*KCdMy4d`fGTZEe=paI}7a$@c_OKIxsQ? zKi(86do-M1F+xi=_mfCS?SkZ@!RXtL`+;4+sF{IGqP zy3?%k7ii!6OXO*cAc-CLus^MTulP*aVd1^}F5#J<8&x^|JK?RCc&~{gll`NOGZ+W; zryxDHK9eUDpe}`L27jAAwa#umT{x$(==t3|@8>hWY<<>VgLw}SZLYjyj1$s9uPqIT zI9dn_9QOwPDPu7xF?pPQvcKN&ob0d80Kb*h7(wz@*@Tg*UWd&5QQ_39Y;cJ)WuCcRw&vY*rUK(Zaq+;wMaw;W_IG6qzhr$8z zDds@(LeVFBR_|DLsiJ}>a@-qryQBSY(i(k@A%R}=rxdW3FB_s=UlB{K%KGgwAuW`o z3b}?~%^AV}_OKCGqWR=JP$jv-;ZJRI1hFuXM_!QxnSX&NJv7_T5V0)uP_#K55li$v z68j0WCN{^iBj&4VO7s&5Gp3xH70dBi5C#lQVGcyU1CLLNwQov?Lr+dP;4wIHzt@-X z=R-7OpGI#>?+u@pbkl3d?-4a0^^tkbLJ!EaevPb!cE(hA^v0d!YLfmA3`m<7kvNVL zyD{TOdfV9Gc^^{(mT!n5E`J)7v|Q+QYtA9on^Y(r9d^?*&c`#XgWWqZf}TGA9%;rA5Xs^;udBw>2KfP8L0UCncFiYlaFWO zGXuxGNqOnJ*h`BSIrrnTHUCoY8r@7SsG0r=`+&mnXrta`{9u!Lrvi@pLu1;*B2t#b z*ixp)9f=)PFM_s)aCtKRQo5VwAzqCl`7 zkbow$?+b%l)+Metbw(Yt+~F6E>Ok4xztP=D7hpARqIDc@uI&3*&_53H+?ek+& z3{O3wm-Zv}0;$%QjSpqdL3uKc1EX+ovs=GK`KC!Mo%#Ks0`qIWVP6-;*`^r}o$k5? ze+Zx8^u&FYWmD?gPI1E9#s0q~ULlihYl8NpcKEc>&aV zqK4M@J}Vp7ANP?YJ6l@TGofKu8MzbtYIX0=r@KY>^222tD+R;<_U^NjHE$sQSf?US z8ghYS`;rC&s{Oxb{2qDH+wkz!u1;x@y0^c|AzaeN8N>=E%E_t(O*NFFTj8zL#D-Ib z4tQrst1wtyx~*oEiWC65+qcmBj?;8B7$v2n1G*!#1EQc38&RGck=6osg% zrI!pfb>nQy1zpZNniBUhd!I83w8CZq(oJ~hHq#l~bL+#A<>nE`W9clju94MGtx?wt zMZqmsz`4Vn%s%`yu7~GE)_3}3=4y(9xrv@j>++Q12%JygIn3CRNu(pj5`X9xBB<$>|JfRyM{6RC)2Jk?43DVjyWBIcmx}4t&vKU+vN}>^HL(qvQSl zMrMtS@v0IPr(#5vlh~>SX{DB)$Up!%pcj_tcOR#Wq_GP#3sPejr!1M1b#sX+{nC=6 zaOA>F|H+yDzRMCqe5(Vl`TWBF>HW99h3nJ5f%8)4&ke9&=WoV54=!QsilF6rw{PZcs5sMRVB!(qu#$Jt6PpOSg%Q_sTnpY52HvYfh zVm^@a2Yjt%5D+bUjuES$vK9k(_^u^C4UA#8hD7@KMHB@VMO8a=>@cx<=qxd=IL{0-o{yjJB8gJi1 zxg#G>`OuZ>vs%_Y8VtOdWR8LJc$0Ka+4$#bZpsOLR@_(D<`@=uB%i^Ya--!>ygn*O6)m*+9<&I8P9bQXOMSwUG#Jx8vgTqE2kR-$?kb3xA>#kPO6 z4g*FyMJMT(YPSr&(JYr0s;|nYt5++gsR!h<)N6)*sp6%Jl(<2Rd_bHe%@Zyfpa|+k zB?6&<)W5wiSrXs-buhFiM-<)jt|z1KbH_^2;npbeiKc$R^7_x+yQ+a5BfrkKP5iyL zozwZdBi`K9PQyu>m*M4gqX4GLlZt_ISMROg+NN_IQ+}&8jIY&>zY5Z<^mp^*Q*%cX zk{{|@&VNa*8T+%LYVRgGC!+BO+_`!Fi4E>sN-(eYwe2mCefbe>|Z-- zWzUb7$34FJ?a1SOC9fWT`|h8!yK=*;JB{d)V|9D#fnVQ?46pyv-FVSxKmEaC_x%3T z`bSm1`&G+l+!%p3wNfZV&1%`B$}hYAYh&Ta%gAqDIYZ48o*=Zs7iKW|Z7d=^KO7kO zZK{229l{FgOVdka1yZ~GYxg-Rt+RP(k1)>qUV0a+ke*=J`_JM7L_M0azJkgl-S_gY zw$;Bm(y%W7P)&4^p?Y$O@pnt<+mi3q5qWRBg?Xv!e}71v#ckeDrFbg%hHUM~X5|*m zMcwnkOv`prhkjmPoVc&~Mg5T<3oBtom+Iz!D`@?zs=McSBVf?KRWlktxvggj)>$2r zvCdI?ru(dM#%Lc@pZNfDP`)oBO@Ip9*HO=CX_bII+x{}q`-Cd4Zk?nLajqxUqqBZ3 z*7PINIb8Cedj9u%;i;;%?H+BZ9Sg-XWO5_YNgFVv-qr`sQ*K*P?QE2WJPPDDI-*ueekb$s-O^{=$Sn%qIJ?<7#8hC=-lU!8xFXzkqYs`cX zjp)0DLC!U$KMmOG zK>f^lupb%~$R*2kJ`o6>*kLwKVv>DYR)RXCRpF& zB^~QJu6*JN)$s#MEpDFOz=7}J zJyr(LL;u1?(~1my-3kNFYO#qx8PHw$Fan3Uibm$1Wg$s5D|QY-{Anh?!BbQE9P$(XW#JjQ)^>i;fFk81;j&JMx#) z5pl~oFX}pKNzA_tb9kGtj027+gLNmiIaiLG4ojT+kP?!0#!I_!OhEG7xnb8bD2XvK z2QwFiBNrHBx|gj=O<#UBm!jcT>#bkduD=U?y7P->+L5pi)PMl>z1_JZ2Hc_eWMwD@)rngE7u`;=ZVn&~eN% z)ErE<>LQ_Xu$2AU$OxE>EeWyl?uD^Jo<-b@M8_n@W+s#-JWk$~oRO?f(#GY*%?wWu zkMJAoSIN#}57Ji9V3Z(_cJd;!gLswn4R-|}hf$)^uwxJngk;n_G7pzQK2B&Pt|W93 zyzrwfLmfe9dF+KZ2Ty|FQWt=9$u{7RPy?`qa~zoLkq?c=T&B!~ z+z6?#pH7-=0LOKzf_-->q*Q-32z$i9frQ$#>}`OFwj3x4>Pc**ANK7Zz2aT=-W%UY zzaO+3_mSlT>nAU8A0yyKnAiix1ov%qviONC>bpex?(H#kalvt0Y;7>2MD`yw-R;c^ zCX7Q}r;lh1p2fniT(Weccei;nUkDz{6QHiqeh{``*Lu{!wqm+ne#YIhY=NO_TW7}) znvm8<8qxuqHFnB$Lo4Nr#Sb?dd<#zW^ap=WtaQJajB-p(wOA(d-|ET8dTFe2YD3VF zte{MBGB?37rTRK?!APv9lXru}3w>z3%wJr`B{~WhfuDUTvHz?H9i`^}X%uu=)CWXn zX_`{h|5Lk8Fnh?<__eR7cvBxUmnl8;5v#KP%2I{4L@Rf9t5kc00{uJb0ehp44pupF zuy@coU@xfN9_{#Kz?k!tq0W%O1WcYi|8e(J(5h z*Wau{cFvW*GO)k|kGZJ7_`ASeOx4I*giAlwS}R|t^c0aro4RJTpXtOj61yfh_%<$U z$t}LrweD?@D6C|w?8Lxrbt(9Yt{a=HUxB=;dkKE1Z3AxCgn{O0`+?K+eD_q-4O^(W zRX=FLs^?m6D!z=c6j)b)@^8Qr%}vlJ!x$*gb{avq??ZQ3X_(K(Nl2`L54~gF3%TvA zL*9ZE5kROukBhkHlt<)f>H~TNV>0Ul^DpK*!adp&>raYPsHP5d&1B9}z&UH&H#leU zFFi7u8s`S@Kxs-qT;Ije21!W5dGmxBWst!o6u5nv!Ln^a`_TUkods80OB;pb?m`km zg1cLBij^9rZq(h~-EZCH)_cFYP#0)RDTNj&?h--*Ng(d-AM5;tvu4&iGkZTz5I#ox zOg7?{7c5CXpwdjHIeZF=A^S#eKpjq;Nt_j3&LBrk2soLfN%YJ2n2MQrVF4gJd;Va| zs3KHg??j2WSK1SHPmC|SK4P=i-0)3|KfW70(%`?Ss}*QEUNn<+UVSvc2oi?_s4HV7 z{znoP$M`1sq^(TW<7AJ^;Hu|Q)e?y*G6zZ>zW$H{sp)-N}9aZf05 zuNQiSz3K3c@D`qqx`d4P-4VYKj+k`BfSGpO@MIzz{4&o;Q ze*D%bXO^D={a1g7_?O>6+oCU|e}$CM?~<1?=XulF`an4Qe4vSOgY}v`n>Y(w1*wF` z+2NodW364LsW!b)J~R|5E*h+gHHLG_Sp5iQO)Hf&strS1)t5vLwNCUyvwm2tIVlmS z*UL{TXQ}*U5cS^SRykYrW9YHyCcj4<*XJvv^iGjJ=q?@l(J3FawOtrcwv-JnXx%Ot zX!9CK>YUz3<6rJl8}w~cF)6L7xGOE+T#uTb%2D;z+^oh8t$F=lYhcE)Kfiz^kzRzteXn6Lmyf5qZeF@`TqxN}O zzjkFUO1Yq|MHSX>b$JdW$h$={N<-&VoAvjp*6Tk+AK(457Du)n{j_}KH}8NrN+;u* zKQqyHzPLblem=5}YmQUBD>II5jaJ?18K4uH|o@&NIQN~TY zW_3zMlW57u)-K|Qn!5i!g8tn299li}^?LRBs^K3oZ9$*(Liv}4hQ{gyH@-&%d?=`J z@Wnv}l%iU>U6-zy<0x1C1DT||;lwDFQb_O5Zo*GPOU%35ZM^r0?)LAxeq4=J>}^3~tvhNlBMvCCuS3XJz*kfev)1%lk#;9Dz&Qx{PwXxr%CN zegXa7vdWa%wnKis^BX_7$GdY&&$MnJKTW>JFbFQhcoF8~{)atmNrn>zL*Svl?T+z+ z=fgV5vDz_8+^2_X>c>niLE0YLuqCfS0InPa|)_I;HwMh4p<+u zJ2)h4d1zT!Y5Pj>acP=n}#s3ga*lRsLBKbJ5huGD||_ zX$v^)HY_3_ht}eIB@h|f6OT{)Fj|U_DLrv#80`A-!SPw93W>eZ9{B0IyP)J zRTuXtcue+CoN?@t#C2oVB~Qy?W}eCZJ_eT!DBPHNd)krYxCsRjAu%hc-FT-t%b^zF zoC1j)HHdL}W@OF_89hHawtc~-QS1erlvA^NGmlI;GKo5=cwXwbUr!MeI7?|%B zYM&b7?~#l0|CanuP)ppDhzZFVDO1Njow9OT(ERU(dIQ#)57qf`G5tS0Q7f~~MCOjvP1Yech1Dh5y6Z(t^hoMLp ziJ8dwup0N2wB_c1QW#o!m{@h28K>Pwm}8273vB;6PuUIT%eGD@9Mp$(&=WjwB)+Gu z%l(MipJD*m-HdvTt^aUz@RP)3G2H&C+d5<5^ulq%be zg2Uz8RX%?*AavPi%0HCy-*@?7jPuO1kI`Zln;*kypuif>6hfz`0S!j2&Rl!4b`q%6gls!M{j zSyfoEn~3cLXrKo`*Bpm&GjwRb3`u_Y6@D4}#E6Z_*kn{i)-i;|t<~IB;@f9py#;KLfP%Kmy0e{PHK;`1c4u*)WZy0>0 zem$s`h z*^NJ|Kp!(o;vQfAdh((BSJZRfU*9jITDf%-dydMV@;T^lLm!#1BwOgC#B(rn2K6pg z&tHwU*=tZ*t!e46I8@nIqbs5CZJ*Ljijqf;-{oxGpKAS}yAj<%>)7`f+Kc(s+;{KW z`o6Z3ik{A|yf6LW+E*$l+(uRJ2-cJ=ouW`G zA4yo+&%;%^3z9X4P~}TAPqW-ns__Gelm`H-6jNOHRFj=+_45Gx&3({~wh1Udrys@% zn1(qFYs7p(r{bu%Id~za1%DT59LXlHMh74k*&&$of&=)Dssv0sz9uczLpOjH4xU|V6oK>6$199slgK6V3wTksa$ zpZ5$8OpTyEi!EdB3wh|fp0(ZY0ByCel65g8Fie!17WH`Iyx^UafZnPc6Z2Wp3NLj` zGjnIeJo>y~0ny*58(m0$iAW|RQ2&t~`1@oe;~4U#pV~Y%?6!Jul-?E@y`T7R6e&O+ zy)P1&kP*8+#hCbC#9fL#6037m>9a)b<#T5Zd7|X z`SNRkR|*d3nEC)HT<3P<_0^8OI*qkSgSYsq6U}~VscD`z)6}i!8p`!-!(Po*W0`!| zY#I(T(}b(_+xbHEF78zI&OU%PzrRDs1Wpf zQ7@$~rt@P9oEOMjr8#G!I?M4@w*S$$Xue^klE1c^k*Rov=$-Ty|4vVJkMXO#wdL{o zM$^MPje`%Dw=14&xaUh@g9U%dol?%HiV=Iomj?ahGP><+?RD#%_HvzzdrW;@671k< z+DX0g8U~P44AB35(RHeNK}mC+^<8Sa&*xji)~{TUp{#(u=4T#j&hHp{Ytsqh4c;=u z;D`k)-S!WEu48%Q7h`Foht4+e#xce$Ctd>P`z~>#y#g(8_eM=YCq^p!I50?gk;QrQ zmez5*T2t=FyQ#__-WZs;j1y}`wn9}pa@3zAIjp02(jKV;d6 z831jK4o9ie9$@|^PDPf5Oal5bgUl;2Hf6uPWq76h-e4-Iu?>a>zb*qw5vWnR5hDetHn{@NEYG(q%o#Jq#*nhjj>&59ZGREO{WY#=uBqFFnj zdm|_w5wRbzcl-hj$3Vk9FFB(6%ikNDAHV;nciG4uo&WO@Kj&}%fSK1ilx-WQLSYrA z8uDoymU`E`n&LKA<4?JtK;wuD%u>%hF$3?_x7I$RZIS*-3lwmjZ=p5<6yCA^;Z$C1 zty>(rPnpdK7hkQy9s;ah|u>ZvUeopFtc^?+_M`X9%cvqD2zoKY5PdggD;fovslFeN1*#s6yJSor4j zM)TStk1&?XvFOdTCzPMAUBF_7(WiQY*Lv1bAg{_W&Ui$Q>bzuOaJHpX;a~ z{}6giNVnhmXn1&JQcB!Fx_8Qq%(0p8Qm2pB$AQ!GLe;Sgd{zg!7)_pTS}FM%-AS15 z*+e|TETmwVt30^$2OgKGBRqc+k@x`bgMEtgLdD^4BQ6p^$VTFFR2u0i>IZQPYAN9a z@hWa>Uq?pI6}We0pq_PhWu%0L52+`6Taxy5xxUaz+~LF;mNdr+6%m3?L^k7 zfq2hA?Q=?|3ykkUtwgP(N#JC!rHDYnYt#hmTJ$AJAEITr7cx^>2iT!|W8ZICXuOQ_ z(TxtBu20LGX;w_kv{z(3aS0+SLC0xoa3!eNvP{G0&d0yi~ z`pHoN>F{9MX#G8Wb5Aj@`?mtyQ_+i?(wLPO;Z^iMz`Esn=EVbG&x?ASM=(Wbv zVNg9g^_D6+?zXs;S;CtGEbX1BiW@Kwo;LydR*>FyMf#p^hkD`L4rA7~GhGL}<@%ZZ zbU9&Y=D=sUj8ilO5S4bOS_hifpyK=IUBB{?+@%=)^|sIvhSR!z5giaihu>)GKAF5;I8brP$~bJ`Rrsx!NcCa zr(gPwy#MhyH*4Yrw_CELr~4z+;t^*Cla{NS7(U{n51|j6$qV}@xGr?QlgGADxW>k- z&3TQdYSuPH{`u9sr^d}otzU0WY05{QZmC9;wuvmeJM@xw9jAE{JEru`=@fNJdakvs z>94JQKQQ^%T)~zftAuCEXNbO5{ZF*M{;ZJPHh=I|mxTAW2iyo%vANS(WBZBHIVHYIU`gUs*tpbHsCjWj+=Y-h!duo=!Xa!mc8~Qk z%&F*b@73RfmLm?cIy^H{8`zSu(Vp0xY>%4>2J-As6+YI_f|$g71!y4Ov`)pWF-c$> zEtg<%?$ekq1dw)(T;~_c_6VC5JjSml>S z7^i^FBme8j_T*a+F)vsO322SO{hps^EotB7ruKY7Sft)qrt=l974?O zEBQyAf$bHP*7{&i@0v|`=kG$GS2e_3RrjxYciSp4ux|~octFA(6lE*UYI70ExaqV_ z!I_l)aBpN1`?C8CcACZH{G-`AEEFgGUd9{s!lNtbk+gNgqg|a_USavJuiFOt{;ud) z%x(LVrP5TMaGYz%fvoE#K*+)p`xjZS24g7HQJudLW%jGSAVm}HLEl~d|`GeVj+1n1YmA(p6duQt}2UF{P}Wph*w4vE~(x;w6LvA@ni73 zWr6MxC=1x&dVrZB#gehzg{13Ut1-7kR*2J(>y84V91D<@wt0AsjZ9td@MG4wFEjnX z86&nZhP+9T+}8E$cf0(1Q z;fNv6c0oAeZLK%*ul+0*E&RP)k=r&)-@{9^cT2+{e|29l;f{Tz8ti%U^U!7ZS-BKA zW}?*5nt4<|I`o1vgtA8Y3s|cAY`A23p-8nZ8D3`W>IpL&%5T7EFUq|pJRyeO{*dNV z)^Hy*cW_5s!G^c#hP+zZmv`IdQJi?v%l8kH?{s&NzR z1xQ0nLk=O3V3mbr$x}?#g$iN~7!KK1-|@ti+EM0AIXR);h;5_xlb*zFVwHsm19!1cgf1n%4O|HfXWrF@;Wr8A!+!QO1CX5Y0Dzi` z&A~4ZeHr8!b2V)9WQlKiE}UkJQ=?M?s{nC~^QNOnj_Qe-EkCIaR6Mb+(MqrIAh=>T23g!3m$>@`W|tU;R@%{WWnngsh;=P1>n|zGur$RnNAqA1^U-7k6!LW z3w-T;A$-8&NyJqUIigOP5H)3ZM*LqzS~A?SE%hbnMamRhQWDMUYGRbHG>%Fm2cCy4 zN1n8P)KxoTta{j1&vg9S)P0n>V}8>HvVdOyOFIy92#Ga9wtv)G)%q*zXQ zHM=paQrKayK};5{lrkC7>HUu(E9!>2D)puvn(K{C9z*rKmyPpVo>~}kH7-1QX2izi z8=)(59N~evh0$-L#|ND!@4*fNUl+ULnCKvlB@W{2 zaW2e8^eA*7LWSyus?mPXBUlkcf;$a4ICAI7!L4H+#jZ_6VTfZYkob&xXk2gvAcu^y zABPF;RW1%M$bW?*j6TR|{$qHHed*@$-<05X8bV|^Sm$QtJ#YBOOo z`)k;ySWNQ6oF{SKx#qw-@o!mX-_@Qy^eT@^>Py^QSU$LXNNrjA`=UPT3)FDn2h8Sf zdIp&^=!ZR{{Rltqrs!hPetl;so;_93y{YpDJ5}yeq8>*e?soo~OhVV044o$(D+!mF_H-8V0~Y z(O&@JfQh;e(J}FvsMe-$74Oy*67K=)m0KWI;E5i}_N0AhJi2hxub4tt3^1}FkA z2mdwtQ2NAG!NJ_zC}~GV;DPpI9{$}%#M*wg>zA-atC3C^S}YwLjONZ!pKstnF^vx? z1b!-YqV_Q^*dj)pGoOb-OifOkK`ox6Us$tMQ~5?EPcFVWEdKsw@ZZ)|Jo(W6{yV06 z-aN2nU@@*%xR*R#ya3fAnxuW&Zs~ej^0VIjcz?^!$4#6I?{5iSS^mBd-2+}m9?_^x|>M|tm#+M&MZ zdrHf9(Y+5_K9JSAnV@!6tm&C_ine|*R`ag6RvFZRlDzET44&_6;>{V_$N#H*E9lWJ zle{!&RQn7Ossuv~4{1D6v&HnaqQg9hxf%z?6_!o(;cHL7jQIpB&~+4L(^;;!C2RHbpoIO*9CYM zLj$VQ>VR9~SzxIz0piBigJ#&G-7?8WJGJk)++WZgjjQ_tDoUFn!y{lrbGS zCerJ~ShQED7Cgy!f&br|}I5RCmyQB#@p2aHwB zWrT&S$BuTdQsuv%%hmho-yL^pJCWIpO2RC5g-0jr6gvnj56;&_#=POs6HUGGqn1g> zCwy=SVs>JdM;6om361b!2Mh<~u~xE(jN2$Oeagrk++K4agXKEQC`HWm{L1{x^hrL- zdOc;D_rRPves$B@1M@qCyna~+L8HasdRTVc%DNIagpFI5mxUnuux6q>2~#%Q75 znLrgKWn7;vj>7d0TPRt`_A?zMl0g4J_hI9lP)4+!9M}N35q%c(G#cf>W~CEGxr$5{ z#T0&-@=TwXMIk;6fm$XJH$&m124JG|i5+9AGb1!dj0@$JhS!og#t=!j z>9q8n1*TYG`=Q!v@6z3p35^>;E zW0VKPjR6k=8&qb;t^O|kU~8Eyta-Ue&Si*)ox7bX&!sGNz}C2Ic5K3H(opC|M6m}5 zaN1mBJ=9?_mX@EPC4Jz zg#9Ag1V!sITw7fqt>cl)%?`5Au$N6WoDMi+wllew?|?x0@qsa|51NgCCbw5}XACq$ ze<;@b{<7Q+6oGzte?nw=9>z?ic+z)Z1|v^{L$buS@T{Zy>(OM@c;*9n6o#f+16pUg zZK^PBF=u#Fv?Jq^lu|F5`i)`bxdpND4&aSu5IMkhtfyeZ91L6lEbkMU<~ zkHI!~knJG?wWeQ#l$Qe%Wj11oYKc#+`L9ois}3{TI9qk6_ZN>}d5M3zTqSnbW@%@4 z7uha~wu4`2CFr>TKT;rm73D0wkrYE;g-@Y0qpLmd!_1*K-Guli%c!t>hCCd`@UM8W z=|(lp>iG?7JyroQ-mF`r+TOHI`m6~op4(PCT+sJYd|&)bQl+O#agJfh$m)h;vfYvm!X46E{kvsTdUwl8_!_CnG)wg_d9h=vZzZ;qagcfoaST6X%>(CXSmqOw zr_vw&YX=Hi`JxjI{pR_c%_u)p5pEln2Yp4|=wMK)%+CpPO&ko{Gz^ECB5iT{XdX=2 z^Hn8=JUu2hJQWXHKMnAL8dPn+g@2p!t&FZ#g zmP0Nk+}HNAhkH&KE9+`I+v*w3_uH5DaC+AcmIxP%n2x_951*6b18I+x;iK8cSJAWV zD$h&q&4@6N*76vHQ~U;$3uWdW>t2BVCBF0i5SW@iFUUA1kQtVqh*O2n z0Q-7xv*mkC(tF@esV+knsQVmEhAkGbquZPgI%I2tEpl^ELl8Uu4T|aEOa8}mKHKgY z;XjFPp&q6dSwpDL#QQzGBszMbPRs0a%<&9_C1Aecf9e#Bk+f^TqF!sH-|(G8jpa{@ z3Xztw)nmpesAp7k59XJrmnFztsw(fTHr?YL-XQC zjg5?3IGS!2J_QwK<#vnCw)VWV(}QQ{{N25)Ekmo;X_$W z^QycE6DH>{Xnz`$yf^-w-`9v=(aj-2$*)7MW&RsBBlm4&X_g`i5aSM7NDU#e0Gn-z zwqNRax7auxW(6I@w%{-$4F;>1-v}MMF5p`*Ei57=EYdS@e&h}B6Jgnmje#}fCEjBR zH4Gc>HFXw#EZLuMmo%AhgR~K!PdbU6NQ_47@F~b{ED@nYV&T8Q)sO`aFW@7K&RGC% za00v=TfR!o0_d_I(*m$7`QMo3y&D2|3;qj<)QAF4 z+k4n`kRi$&d=Tb}rv>|uC(Bz8&kkRq3-obFu0T!l_1ew4VnvB@uI7j-z~JGEHl3mr zSfb*VIi}|If{tcE(VwHR#2@qm5(>N@J73F!sfM!MpZIt5avr$BDYL!^h&s2Bv-~XxOxe3B~idzF8 ztk;L=V62Lc=rz(YOYA2IN8H`mz3w@VKl)2TQy-zT@=sXz@K5TXtl2DiqiWEcBU-Hi zp>_~GYC6g@govy1EyLuoQqhNLMdVmqY~VzoBUYh}2%k4BWQ-YjgFH2`$@OLEgmH>; zj(m$DN}w|R5Wds$4RT2y%6E7srB=~_A8%kG*O~7^_F8TMQMMhD^NPEIe-v8{4&`G&m-+$Xrv`@Kpj}DaqKk(slqhw1-^;F56)}yy zuN&J|zWulV)zA2$`OOm9Z0?kiiAp}g*HGBbIA*yT0dPPspu;`exy$j;E@H#w+RB<_Y7zEY!!3*gGEULpLs;y(caviFP)^$r|n;P$o2s9DX9VqB>9?I6TlP;oavw z?OY>BuCwzye*W&MEg#*sr#YZyR$aB#I~4mGHF0nIo4vIV=^R6ILHs+Uic{nvY3aj`92q38rDf;cZ# z6@5!}?Ea&M7lO5hc*7U{ck)&JwYXV^{0xLq9Nn!?q@C3C0(L2Lw9!ibFiE|E|6aR| z12M#PzcFm!dYWcyzkrZqeleYFo0#$zoD^{b$@U_VW%SD|diZ8`UltD!%?xrZ^f_%_ z0{V%5ZXrcLUH&;+z@PKFz^+sR7!X$oIT!OUYJb`+&&LJoDAe@zDI3S^hQm#&qbIY9&79qC|QCkN<{k(8ngEoW2~};fd((2-=SpDBK+!T zfssE(DuRdE+~oVdhP1+faY<(bO8uvJK7^eCmTIGimuu#7N}RcZM_8-=CSw&m#XGkxQ`kkXpzF@Mt$3vfCL8@^jTs$O^7sagM0?ITEElus_00a zaC_Vx&WpgH&PAm1j#N-O2W&ed8lmTCb;>eF!O$1LcToT^*l-RRiKejr(AP!B(W>L$ z_IWok8FGycbC>E6l-!*z8>CFyNZGATzsXc{K9jWR9&D})xdHj>s1 zE~YI~xhdC8?=XOo`(0l+&0c|719}au#=q71;IjsU?Htai;jX@|1Hbz1Lq7Z#=_SD} z=~rXmofs*yUgwwodjBTy+nOQwgDR{|p)L2sxs0Z-U^#WMDnt^Y-^F6e>D(`y~fal482gDxl&A6Kk zGGaeXq`yX6(Us>Rtnek;es~~4|E4%s_15SQ$R4W7?HW}P4rvTvnw+_e6~GHnxG_Z; z+6Ny5RL>Ujf16|vJML@$6?dDL8SC5|TpUz9Y#a3oW{_D=Fnf-)WymaSIXnk?)N#s= zGY0EH`uFPN2EDe_c*`_m8nLEoy(}E%5yN$vMtw@GkU2$!;hDlTL93vTzfPFT2My`@ zWbx$zon($ML3Tv*Q1%mQlPW2z#A>o|5Rb^^j&d0Jvkfi!x2i+9Y0`AB5aBDzvOXEW zyX}f@T*D6ew+4oIQTzV}ZuB`hzXT-%8`LI)6LB52G{A05T(+(s^gDH^qd85!aZn%}XZqDzhnQXsrSv!KCX+cQkatAq z>}TYU)N6D-!y6oHgbvs})n(XXq@R8_YhL#<3bZEEI9wMeXzhH?kLJG-j2Q|QomBo5 zz5!emw6gLA&56LFTdBY05s`g{_Z~cl9kj(w*IS&G;^G4 z63<0mnQ6T~B@=6DO*s&}Uw8l}mu^8ELmvg9K;E`)Yli-RI*c|^wbL+3J=;z-6@mKQ zU*IQDKhZ7ZOk6SHCVryBhR+{-ijQrB5I%P9B7GB1Cl%=5K>5HIib%qqo_zMMUQ>9J zOqOunJ~w#=V(O?c5-@fNd2i4uSS>Eka9j>ie(1|mXF$3EcjV(>Te=!>LmkWM7_rOe3cwyThUOWz zBlu=`QtbS&;!!@nk5b>@6d8Eu$C6wZZJLIiO;goelJ(tc<+7b z1Hl(k*pY<+t9=1TA~e@FMz+2T0{WYCofDN+!T=* zSr;~Qq?vFfEZpm+{|`z(vkEVy$gtmV|Kik$Ai{eHnQ#Jp1p|TJhXLWMffwM*-DhEM z09&E&fIq;i0ihtc%K$HR@;uK2dSeqH2hx&YFXKMJuK6XyFtpR)G}3zDgOQVg47J{O z9ym7nust{nU>col*CRqP#>otqxetBPt^}mH%Z=B888Wf^o?;rn4LV3j_Cdu!W11%% zjclJH_B%Z$oUu42kGO#_6-ks`2ApdAV1oR4u2$Cfs`hkt8Y=mE%K^nU?L@H_}UII(9*r;yHlyx-936 zk~}Nvt4u$?HeWs5o2lYSJ$22N(bkb}AYd8wJK~NP4mX?F4a+w#QGf>n>qc|@zI5?7 zR^&qTZEJJlgiK(OKmSwjx)#|iuwk!wVHI*Qj8Q-A04f}wj zRdc1_p0nL6e=O*F_F*ocR^B}Pr|qqDrr?%>C#}(QmD^oJodRw%)uFNW3dBUmS->C5 zMN^d)rJ5ysAbBu!bf`d-A>1h1KA0dnJWwcP40H|7;=klC>@VlyIMcfuy2@JabnI-6 z?zl5}taFhyuV*goLEk-Kaes|r4c97N+r3bb+_JfEQNzpjHQm9DS2QKHH{q|UZ(<15 zV}Q!)|LJn-&P&KGD8ZU8Mc^RJiJGg!pw1|Ds%9@lgqX@MA)OC{6O#QB z5wr15=P##L3)fs7+Bvj}^RE9!o3m|H+pM3$ZsiNF0qLW1v8MR0^1`pXI$KAAX^&u7 zi&nUJuk_o0d)bCRVF4%0s=;AR$00R5Cm>5c%6iHO)+7M7OP3?IicR2RNvg^wbG9v4 zju2op1=Wvq^IDP(mpEMpzR+c;l;1HVYv$I-_9G~4S<WH`3-Q$YB9FPE@r~G}v~{dsEI}BV@i~4m?B7ufwEx5( zRiBIqcT@$uM(^;((QkMge0c$5BeKH}C1*!}%qoexn9}N>>h}lPfig*Nfr5Kf@NK*y zJX8Ifb`>z*JDPAb@RwJ9*!IARNJkhv8XQ#`A&=Z0WDaffD))Ux&ZhTcg!muGZe$dS z4^d$P0iy|p&c!6L^D6N%pbm2tbQpRHiW`?~KPUz)>Zq}W1tZT%W5<3s-N;oUDR$iQZ-w=e8rCr^y z$1QCdQBLw`)GW;x$`5-DdI_-2F<0%yRTt$_a3Tvcp;1h_Mz` zJ~i~!{?^=Y-=;p+mu$EqlvsBtR~Ro^E)7iuujuK;pg75tvEqZYVB;Yw(>a9ax<4al zg7-l6SPfJ`JBbV;haqgv*MKDPKaP{!!+_`g3n2#K1YoR!=r9>}*-_4Tw+gutQsg%g z(V1yNiVGZwh&&t&6}1}_MT>E#L)sh@EiC6ETMtNzqG290*Al*XeMc@O47#^L6t*x| zt1ZVd(nqydIYjzN&Mo{%*Tp{v-3z{Yfj(C>L;qLj3C7jHG>qSa9dDYy{2m?>));J{ zuJuU#&>oUlN2Z(Ip3G0ELFRQLhAE`$BrQZiyTa+XWuT5o7IE>v*UQ^ey{ z=Z1G`)G~=~xelt+nv0a5&9fxky5FK|g<0^Ac-{!Xb)ukgaJ)b`kS)**OcyK}d?G*% z&Jn8mpNKHs{=w)dGJ6tJqQJjtG0za#a!Ea1qBE5vy0B4R z+XA{gbAp!P)?%&ze+!?R$}9IPOkeH@JHI#fZ~OCuyR2#ZfV!JJm^!$=t4((CH%GtV zTeB5VvBrL`X|uJbPhz+y0;})IW=YF5H$`cd)uQ7Ty*f?)8qnDt0pHwM;~Hq*r90O7 zQkK_!Kos3W=^x-~yV>GjJw=Xb{Cmuo;*?Q->hWoB3{S%p=0l_ki=S(!#iG7%MGQwd zclDzH+1)=~(cG_2f-wW-BzXE8yyhfYJSN4TM%VbEAdiU{AQ-;LeE{^^-T~+}6uTsf zNZTk0%D7oJ!}wCW(~7e*OkH4ap#yon{xxP{)n05)^8p-2$i^u2PA40)D^S0K_u`+X0DKgf9PGhuu?X?m_N z8j!RF35}S9-04>VchR#Ua=hLB3^C665EAA#LGMFXV+!#?Y9C{vXNR9J>23%Eqz?18 zt_~aP$_crFq6V*^O2cljt|sgWq9iSiz7ldNNr~T^G2Q)kbf^1X#u)U~C4s=sBawQKIa^2vt^cSa;g0;I8;v{wE^XK5K)Ey!Wt6*ssxi%0yF> zOQQ6ZeznLYYWP|cmox+Xl;K2f@t%fT9vDd_gcW#O!m(ik;mhI{hEE7T91Fc|G^)owqdSe<+z84E#&nue_Ah^Ku`5v?(sf#BYE1SJc6L$GtNGmhQAv- z5#JGT0ehT5A@tym_$-7-Q`>Dv3T*m-@$0npNe2DnfX#L-%@?A^b)viAa^ePH6O{@0 zOTUOd?OW>WotTucr(kAs#N6Mp#nTRizDcV0O~Tw{U}Qmru0B2NX1@Atq~YMj z+CJ!Q$7knh^gPuwrhC{Yl%t*-LvpQ%T!2XRTZMl_UhbiW*R!^R^Z{o;Ys3DByc#lx zIg?%#^RGjYa7D0{UCBuY4f3+}Yb0N^I)jJ#6DY}zC(2+a{lB39WFE%-omoO+&oeN{ zv;O!R)7SW;0~G9?L^f>>_y~Tlr4}_?y%xS%TaXZBZi(0=_MX`#3BVU+@wE5S6=G7V8`%^_}f{s;eL zD%4f*M|`t??hn8ETA=|}J+d_O08R>Y0`NkR3x0Ie5I#B~#DfzRLJJK$Pciz{dwle` z=-UW2h3(UK1kDuLJs{jE@S(m?XR=_P(JHg)C+XeJQXm|=lriGcjaDHbvA^xL)L3J( zVwo|ekzl^}XTE7vQ>S*gr%&PLMoW(I_VGRpZfYb*m;9V>Q2ts2i0o7%O;R=Puj(x7 zB42I*)YUdxYwo^}=m~#kSG=#9?Rdd?1UVzaBh0#U$S`v>dWN+SW3#?SJ+p*C4F;TJ zk7@+mDh^b<9oQl<^j{ht>G2C!3GVZ!31{}r7~I#>*N^Cq<}ka~bg4Qfv>k7s*qqds z+<2k2w@%xdTC=PDTIGSxi$C+buKiiuf$F=`^2Ktd(TJus@{ny!V%xKpNy^5SnZlEe z=X&$&#y1wUw*A~C&ilL+aOhnLa_#$tfCVMjG~X+q3#si_`Z5RnIu;KvYFIb)@K3N!%EjO$Rz2%SP%iv#++M9D1ETQHJ7=cl&Osebf57xkIOSIq`kOwUS`Gu7 zFS?_+Gf`~Lb@~~Jw;$hX4lYJ8BH}$}M%jH?(LrH9qbsBGVg_Q+(T8Fth24nQ=XW=7 z1%tpEM_fulV@Q~_s6L1qeF88R{}Ql?R0I){ULvCL31}DMHkt^jN8JEVK*hkmqrM_@ zG3U|g*ySiEDj1OkZG>-dKS7o_{z1QVfH8~zPtjR$wXt?>IPOY92ok~F-CYV4Dzvmf zd+P4(TRU}kZ%^G@>eO9;;_hxCAx7LiAKyQiHEU))GxxsseVKQmXIagtM2HS`9W@L6 z8oM9uiE~EJv3-jQ@?xO9;y3EURD0=Yg{f?bxi2zM)FH5z3<4;~MF3-;4h0dk}}EEwTObK%5R z%c-&7mMYc>OOWCabR|B}>9Lo6v?S<#a)vL$tIWB`a*8Tr1rSSE?Z`R8I#9Fpi{+2x zra43us^dta1yKE=K7aVd&RnwlFo;$!PG(jbDrg@et#-e0&Ne@&-S|ESCME#Sw`$F7 z#UXWphN%CDA_1N`od>!w{+OL9M}Wf^i7gXW88!hD&v*rAmOQrKTtW{WDbl1gWW*$% z_TmTrApCZLSqx6+6*g3VQ9JC1;3qGeJ>0gl^cwF z-l2xrh5a8E4!jGyrwOsT%L?>g#q%`{lK(VZ#dRH7zgmCDBGuGe-zz{SoOG|oUu=^1 zi!Mkb#9fjLVwvQOI7%8QmPndKe?^Z(7`|LY85fK1j((Cfv6$jD6I=POxO3TW1OcqA zy14PfHgh@8J(Ia!KHqtBXt#KIXzaw0Q9t%vWHeY{U|Z!l8X+|o{_ zv_0yXHtYD2FylmtSvq-Cy+poR@<86n$rd-ZlX8oS?{zE-4L|$G9+(gA*yOUQT`QJJ5mat ztow$tue^=k+fs#U9^V57s{AF{fY7dMh;`*+%$ra5;Lks7)$RJ#BRte`QgC1RK$dGA zRA&*gjl1dp!@l+27z7Adp9AsTH8b6vlKDT6ZIK6po_jP$x{$3wGC(c^AuYC%vJ8~T z@m!xtmk1xu1j6FxcQ=YxmT)w(Mm+$&>wggOgDyh z8F%&UfL4rNCUhyI?KE&QErlxZDexM|IFvfSG49KlZ5EHTw#x_mTZwk~Y?YVd~{6ypB$JG5sJ z5$@sM*E~Nv<#`;$<7wLgd4R`;H$yVm&ep#SA(tO|3*Qo*;P)k%6x!)<&HuMn<#DC= zjEi4An!c*>k*&Jx9m>qQ2mB<#m^Le#6vblt=t5C*UAT@=@eP^V{FdA`2Bg?Xr_3y- z)r3g9$|>hVv+b4ajrO~z`P-j}ORy^lc;;Bo#CWlYyrAFd(UG+GGbRI79b8tDY7Q{zfB57=jXHHb6>s;dern( zMfIHgzL4{>Dpt`vkPcWT%fhWS#@d@znRYtXFTm>VWg`Pa$D0$xejQl`JZmrDhGZ$I zPkRl#%Q6YGg29*+L@2%u8G`kMlcE1vBMs}+hoz%J2EUB$F)=V+!pYRa zBbPO#tWTAx&A zcWtSgJ1T7}R4o{I2q&>BP|w*9%xl=cCR4_vM}%YCp4?IA&UwS)mgqrV&9?r7Kc&4c zpDf*%zH548+e;@lNkrB_V4ed7e8pvfp#yhCa+Zf-Py5^7yZwDiEAsPr-MOENsz2oc zRYg_wI^6D|)w@pI9ixYCz`&|m_ZwHA@-7WrxcDIS2L#`7g{5XD) zTsY~c-Y}Va} z-u55zS@mhM85RFcKKiwYkN-pD4^*WJk2N2YboT;fC&%Y=Et5?h_Z6qBKC8df9#SiM zM-(){JE^yDTa*c~6CZMXED=Yh${wXM7956 zXyYjCL$s;h(+JN!w6rJo+nnZOZj#eM|6q3*eBh6j%K*#7_jF76Loyckr%1=2Azm!0 zP_(JrjMvN>m_1|`u?QiwDMTFr*Pwp$v(eLf-e7O{k6{i^r5;h%{URh$GrE;Ie~jwe zIJ(fMrn`wcqZMQs8W2x9C=J55D6(=kHBguByxM5=cnXktwId*&J~lZnz7AF=CZnAC zf$21*$@xt9O-(`n#2H~{pdk>p6%I9s0nRjS1y1Pu%~&m4vrp3`1?m-(-6p!I)_PYW1iX@G1Lmn* zt&>`U<+o|JSpv9g@&^qX_gI5X4*K&JJ7pYjO!FG}2Dt{{@5 z5mAVsPlDCiOnAZ(14>fVsH;6gT4?vq96&(8T42K{S8E%dYhu{l1#EH7fy(?q@LAze znAwpt80z51@#kE_a^@k{#q8q>3A9$P31QRACSpIb@&1Il6Dk!CmRj6cHjZGPD3&g7 zo%YkxnJ&V1MGG7n{WiFem}#!}NG$p@n9{DuP=T+|)FB^3UJ}xoDSrCk^{J(y${3wr z1_k61G1b+hV5z7LtgECeydV-(mOzpj`w{u5)v75a8t+xyQ0r{D)^>&uw9hllCO;6y z9EyDI8=a!}r)SM&7Dk^X8tpd{I?V%)wyF%TO8u1pAmmG6F79367Kd%YK<{ng3nKtA z%6LY6L;Qd7=OPcs8vKJICS2q|99j*CU??T=orMj=5%1 zTb;s4cS-Ho*NB(!Cd(P%XZ;e>V$&@BLr9^i6aE+JZ@lYNDfr@im7}yfDjr1ttDgxg z0L+8T1Zx3@;OESCc#|d04iCRdOR-t$wc3#pS3qaxHPGhf-*-$(Iz!D4ctTb>XAnZ{ zV=&L~B;+mdOIU|?3G}LF1HypZO1$m**Pa-3(&2zF%=RbqBhHUXK(^SlfxhGD=FgCu zhQ*T)jf~m?%k|eUfvER8AggQtLdQoqknf6Ea3`n~6i>(p=Q}AOc(-G)19UQU10n;U z5Vu?AO${KJ|RA=o?&$|HDMxDM=@W8E&#M-sdlGX zWpcwFLOIzkC7rjuO+IT=N4cSo{%%#1empJ~4L|_529Lv{0vG%ZYmhKA0Y+OKqo1b9-x?(s% zcExHEuF`)N`597G>i~(Cw}>dS^IgM~<>}RcuKagMn`vIer*Utn-GL9O8(mGPSCj#r41P-PVG`->)GMJB#S83j z)eIXYNbNA`SP=9qgq3?F+G&2JFLHh^rY!d&_g(ng#&LRcT@|vfy;HMisEl`ln?ANg zeu1Sm=L_Il?Zs)D`sS~-~XP7bQ&yurq`9DNRs~M$ zzAvfJYUACiL6eH5hk&J$ASKe`&WAZrS?dGWkGu`EA6vj6O!TAQOuCt*@*}eOnqe+O z|9tqEp4T0tUDf|m3z7^$<{_tW28Uyja);7{mn6r)3bZZuJmkd0GSjKrNENueOLU>q zga5tuK2O+kVsdBy6GarS$AHsnK`-GH!NX7KTX+|po{GF|#bR&NHeRB>vgi2FoSOf>q*i-Bnld8YZ{Ux; z$6L-*4~$s4)pDY z$qVZHMV)_V=&GA_s0?8?sS7oP{NQM-i?J^dCZO{<3I&pFZOLbUdY;CabAQh`Cc0ViIWvac*; z@?7Oi`S;FB1$-n}b(;;;hw)g}hk{H-% z*z@=Lqy4o@pI@xq{mHI+L;2Rfs~eK4KX=}3I6Uaoet;$D)(Q&y=*B1gjl|0XdPePl zx8tV%ZHSbfE>&PhCuc)TcwbYaruj#MNA_1PMv46>3&D{!4tuz>5ux_NzwhYlk zDl;lW{Ef%t<&`^)ZG6VZ%KuvZGiM4QlK_ck4vD>`G&ZPD8ImC5gZfKrmlKx2T+VbP>kIe~PzGgXiHtYiQ2B8FelC;dSfbdC2LaCL*V1OI|D3^L! zS4p1&5YjQw4{-)$>*PsrhJX%q<$){~cD}KUEz+Z;5r(_4aU;@+VF5ck0S-`7f!ASy zz#Ybu0IWi2Rqz3pD&EwzL2E)8rZ#w@oJ%wF7@}E;ul0`7bn8~_PZ-U*1+p5lQy~QG9o{Q;>OV4dkH*@9je7>?p%;tp zJB*kv`*@+3#`qG7(hfqQ2{}rHdydc%kuCqN9kD#o^&>8u3$TYk+i+Y&I-XCwN<8Xh zYrD_mG!-B4&3<;s58I~THni2}xMd^VN4bO!x;o&HMq>T0 zD6{m6XCZq9ISe13UC`W#;6PgrpLv6QnlLzi8Jxkoqd(0lm|`oA3+51Y>`3QLtaJ3w z3scHjaeLPKF2x+)OXDSylXkDgAdrMc&Z5y7ITWmAeRLGCC>C7#Uii| zQErnFFk{avYh+KO_Vvh4S;)lTWD)i4pV0#LmUV| z5~aty2}gmwLEm=Dpa>#)9?DFHFFu1!TN8a6JKy&bjL3+CCD=ZMfbr)67qELQ`*2)q zC&2(0kjtFrII3g!yDXo>^f)u`m+P&JMT`@H8yQZ{v)y+&UH3if@HD90wlX}IkQ;j) zo0e3MdyqPA)0IZFx1@e$b|vq2JC>N^&>sKYij0>}Zi_!5;>4#JIwOz5KfAvpoWph7 zyG@mMU4xGXZMORwbHS69v@IN;nx3*fWoG(`IDT}wcdXZQ6rQ|vx;ThWT%5GeK4GrZY10Ch!@A<@wkv1$;(L>4qYp-q5P<c50kC+}o&VjyK(vi)ES$G>mw|%~u;Nt}T z9nVF&(Sq}LArFz(W`d`>vmhnU}6hBlaUd`y5NZgF5L{VNzi*#TIJ_+j!_7>$#I*_M6Xbl_L^OVA=y z0C)|_3Ie)S0QUy$oC1|tHkwF604iFU{4mNk#U*lU1UJ;;`#Zp$+3Fn(_w_o=7JI|% zIlh1zoe#G&*Zn11N}DF?b=s-sdU>FJ#+LXMq%WF&CBePudEoR}`L6#aPInsgLsCCE zRonazI|D7Y)`H5!DDz17Z}ZW=>%p5UU7_SQt-*oC76!@OIgOT$;<;E1V1?s9xa00^ zRIJ}(mrH>MJk3*Akl@;k{RDqtnaQm-6?U|OR`lJ0aWxNMkDPPhEirLOUVIwXE1c}G z*Uv44?h!I=j2@i#mJCW@!;iXcH4NcerN=-!CmGf%2@#^uO?`o37Bg_ZSKL2joTFdM zUrzjxIsmf^90vTQ*_uC+PU`QVrz-q)f0b?hOv&boVa zN1-EZA?CP%Njf8XOF1H1Y)cky!4*taL(}z3pm@>%InJllZ(q>*7$4@JutMu^clY52 z`^LI!#FDDD$WPT5tdDBCR89@^Cr@;qnn3Th?zUvUEjBIb9T$ednYxsP+hC`lpAez*k?? zzcE_C`?*}(kKO(9&!1X>AD`D|zh>11z83X8F5f3>=FYNSM-z1#hwDRWHgA5ZfN3ws z<-BL_*cor~dSgE7njF8MtPZI3sKBpF#vH{^qDKqH_JZK!5hwW~yC4Nvt*%`?@@<{)?QmQq;*0W|xTHH42<7Y&e#d4ey0 zFS9UB=SH9R&K`b0Uf=zS?^}0r;#p<(h^lo9OD#xNFS7(-E`e1xN(&x-M|VMeTR{+@ zL@!uhIrYQnVaUL-zE^F%ecQj^ADLO2$KU@%tB}0q8X3)>fwQ?`kV2Icq{z?-sx$Wi zU4a5%BqSazhUUP%p>XU{&=CBC#dZ>-ft0gZcF(WZRF@8X@c;Jf{pMlc@<+(l!DRm{ zmf`pghb2iL-5w-VFcV_C?Y{@JYH z(D$0p+SX{YF=d)>(EoRl{4ig#EWpiyuJdVhI+Z*t)|mb@^F(ZXNTt6ULg!pM;bHII z-$7n97({qDh6GS1jNJE=>w8G*&i>B;-sD#-5!mk#M7r!z>^vUO;p-ht2%YP9KQh#{ zAZC?)VcZVVym*Suqlg5Ol=%z09{50S5?mZf;>ETOscO64K~M2Qh$cfDr4jj${d$|< zPN(gK%}C2&_H^)4A>8VSaupp^^xjW%_{jUWwdm)^oV4uctmnV^Gv!5yH!@= zCY51)Yh-TDC9<8wF6l`qN?ffs3*L$DNlV8PKo|O|DCfKP)0}%Rk-iNUfqKWbDQOeW z1VO?z6VGMz@uQl&ksW&P!4vwXfnU07!=CzWEE@xrx5z+Kw^+k*r6gNVcxYzOiEI~7 zc~UYJ==cH!5bpwHv`lU9);4MJ?X{|NL&?%_>~+FTyxD@X$zu}_ReO3a0i;zY(dIux z#NvipqGI4O=B!`_EJs#s6$|Kn@y2f9eQ z3Te;?;SiQH>h-XQuu+)eb_HY?>+2R6?~)F5@tmu+9GHDol$cp7S{tiVB0`qyeSD6a zvzRhq4%rS7hg?ZefS%d!1Xnq)McwouQlOshZs%Q>2mMQPhT}ZeugkP4 z3K!(k?R3cfGwqF=+{3~oBp{s@&An&0cEM%a>GRb#E3<#0AI83iirg@04s^mHO`768 zF3Jx$uS@kSg{FGVCvx1Xou0UunP->|6a&oOubS&!*V)Zl;XjXJBxY~0Ga?oih-kB0h-cGngv!YiAg(9#SmEg$2 z`H+Horox#;t4eoa6rSn-IqEoUz(b`wEdzQl4*k z+RZ~cN`;g;5CLN``Muj?W}?S*pB9h2;1bWM@F5pM_!B~15Jx{dP^9pU9k)Pd3J}uy zSFK;OeodCs|8lSBQmhArV}6rT^6W$U+a({&ALpGh&B;D&YL8=p9tQVd%G{;YPe&rXe=Osxoh>>J^aphS3QLKnF# zHtn|~f~m-3)GH>j`>-m&*;ds@T&ceVDTg4fV(MbRkI*yVtgHc`KKp{cCvl~`BxIA~ zirZCV7kaJ*KDk=n+JP7;X{Pnqb~%k!4}OtGjVGCECnHQeJwp5pmE5<%vAbtoaExT} zG&^$2+^gYlXUs{BOu8Q@^TP%NkWsEr)xk9OFo_!3cb4#BOa!YD)LOb__qC^W?dq8z z32+E2bntVy9+ctU6$bDN^4ad2lD8P+U;=LhG%TpgQfH_x~HVNt}A`|R{qCA^=7rp_j&EGgw z&D-XSGFClJEbgR=sz&aLUr(Uq>%~*f8qFrdYHN^X0=5CL0z(3=!Mz4(Pym$xIM}yV zQ}tu1sO&R{f4cS^|LoFgmXR9m zqrqq5ZuSSR#&Czdhg8O%?-VuhlXQT)6OzZ}YvyxSh*)D?;|GSX4!92%boTX6Z;9@2 zZwep$-8zT!qx-XF+rV_3arl3(MS^PqDxlWqf|G{&pXVs#I=xq2hffyW1!r?&jLgAz zs=w{TseS9E+@QwUqbY4ihyM0m9r`|Q->ndgRhq>uAJ0o`z6{FT>S9&j243rdLRYIn z{bGvW{0v?V3kM}*HUZ`mE`iL%3R5;AZuAk5_Z~Sm@8OzX&_|_THa+R-c=hRp($Y8+ zT*f;G*@W{0ABkKFTAjTY;FYz^;ud>X|Ji4u08O3WI1}Xl#%mJ!$k4mzSzZ(M%lFE~ zH6HJixNGe@DsKi}+K(a^w>!elwdiGOZPQtRUUk2ON9$V(In@`=)b~ZZpYPjEz1XLR z7Z22!UXC2liY8_$DkPiP^OSe%8iZHN_I9*AOMe&pIrZVPdhVmVfeWPz`Tzc^RP%ch zL02c8U=TB1KN}svdSv^lHP>OR8A^@niNMiEoB+OeN?k;Bwk_dOA%*uzU4MF&tM&DxH@vD&M+*fs~P^*etu{hzrKGXq_Af6^1B|Dz&SQ^L znzlY`se^tRuK)7qNo!hzx;?-9d5vmp@?EwF_B2Vo;rTcH(XZ!qhiW$~=CnWMVS1(w z#1A?(Lpcws4oS#=fttjcd~JBc6NR~DiO^$k7VDS-JJ60=(vw0W^p?W>hZ0pH_IciQ zK`!eruXX4d>r6L){9;3kJo^s`@%D$W zmY@0RepkX%#J8(YXFNObbjH(nrJB;wuO~l$ZGqH9vugWOWNE@PhEi=3@DXq$Ltf06MTAn@{wnYAaihNSC+#!wVg3<2dRnWzX%hkQlFfv{~+7 z7$E9V;zx8D@DuQhx4Iy1l_p>eJ6`%e@gZ zcR}+^Mak&g7X@o`zNhbx4UJwJkQ9J(^K-L02pt-24wCxO+4yzv1bi)QJt-E&a110i zIr}@jr1{Yc&?`tinov`Rv{N9{vUx=4m@JhLXiay>bKp5A#?SGHoZINBEl&6PZ%&z4 zVeV@$NlK+>R`enFg@NPFcikFkSo?MMCR`i&J~GO#ALZ(C8{ZwhiQJrwunUQLVwdNU zN1dcNIjqFSJAsh9X)_V-^mT|?3?5X(OafkZerz@~?wT*qx&eos{(-EZZiW`XYr!jp z-k`qD8t{?MrLZ<`o8_Y+ZE`hY?bLK&tk>86>cm~TL8Eu}h7P+4@NHgpc87ht>;+zb zs3hidQmIWkCJ;$Ni7YRhb|5!ftpHDbuPH(v zW4gdM8#`GA#_Z8ruX&oHfTIQmFc@ey`lZ=kEWg*xMN$(F1F*y{2cF@N9bo^Tba=)N5+2SddDKzEy{E-%;qxq z9svw*wJm|V(dg=Pl=G~ImcW6BynEyIta8~q;ZMyGjX~^h(T}u2rfjO@^2y7gE#Sa{ zY}?S{CI|Zb0;jO)jZTyCb&lS_!_?z0z2tvM`GlLWepI0)05Z*3Yx-&mQ%?huWba{D z#M?0s#4qvxNf#lq6)@#HRmp%+t!M#hZgqRA%O{X32Tg`@9poRS8-BX#IJHlGjya}T z>~T*0+G|+O_ox=_cOK_Hw%ftsA|Fe#fDkwoeUtgqbA^{W_NmL`m@xah-7-)>}4i$S#NL$Zq;7!&1_0!C{k>(>)n1UL+>#YPDEkgLWZufdGkJHq3x*=H$q? z8(|!V%}oA6+L)%9{sHvf?GYRvnTfbLU4zig#bci5o+P+OEhepWTVj($e2_7;yIUknD3=Zn;Q(f|)^>ZucA>$6#CLyJcu$ z9xaL>x7&)3jOUtJ_T?6n4GCey&qJbd*L69d6)cnNK<{noY*rU!w|avU6&CIqg0MRN zG*C&glK|XrK|lJL<^hTfqa()APeELCnxP1_LcRz|6a7G|MGq+*iawu%2DkWdAS3Y+ z)Erm?U*q@@aRM<9x!p{HKee8=RuUxI7+0>Y%(Dn&rEyV?#8sFAL>{sU90IeOqN_-j z3t*Pv6nLkuXUdC1hew&?5V@c?us@biaGH!~g>euTB0t@1r+;i3N0t~-#H;$-wsP$$ zr#IRrj}7{r!H(vJNIujOA)}&#;zG3U8&lRgniBpH9Q^d~?^FzECgKY~YIqMmB+o`9 ziH6ZMVJ-Hx@Gb741cDz{6A1m5QIaom!d6F`n$40UC40b|diDw<+s$1KLoR<8OB&y! ztnyc{F=5~9C?~pL^bF~J*GEu;`#f^K+h=+z9p_$67JGQ38eL5QvJ=#3L*(e{A%pr` zdZiI7KV`NEPg*YV_X55Nj)0oQexM+^x3x(2+xWl9GX1d$7d>z6j6P`Og$_S-MERsY zPeL7@rC~_lqLPtfM|=A-^qsar6ev6&^Gsh2IV#&_@f8Aewp>qnI6FfaK3X(UG*HMI z==K|Z*KvWB*ntqTBptRy@GmSYU_o8y(2_sjM_#M(6P@G9{qtGT?ZZ=l5%YRC zwe09D>m2B~HKgzEn|L^YlpsfFD(%Ryc0K!+K18|BFo4W4lI`A_oNSt`+29HAq-G|d zS#n8Y;Q9CA#tUoJ{k}h{>ps2TRQBVrb00k#{r>K?a%)2vsAQ-dOPp*bOXOX4 zJ;DUa-fl1iV zjkHbXj3mKd+C@7YwT*HdMh#=QfJD>(^!H>$MK3Q{NFBYy%IWeLD6GHRV<~^v5BurB z{`%{b1lkrE4|~A%c;-Ph8tY! z%gEiKCpFP^hkw|-TvD~~5vddMu*C7E8JXJ3q zyu}~wZ*5)IKk;pD|E`aszCY#ly)Op;^pGL8z42~&y;T9G?syM%=L4#J=Sl4Tt~l`0 zKDzGX&|%5Bk!}35EFS4`?A4Df>rK_N>(;s491CdpU;WdrU5bn@ zv*h^rTm5q#pFH*aha87=#WtCRp%ndeTBL@rZ&5&dVB#;88##+Aj|}$K!FmE)zIUwd zepz41Dfme;Onj#jVV&i!vrWHeQTq0&e%PAV;Y_#9qu&+geZ-CB*cYyjB0k25bP@EHVE_ zQiJ2|)?x`xFzOrT4QHa;O0RDBC%*n365nq3b3Py3PkHV1xa}3=wc7W!&qAL>f2xx% za5-dd7*KOH_KMj(d5{zn%kx_A`6TRL;)Uoi?4`JTN>x&c%Y(GHzIW3LLUL1FqcE}a z6UKu{>9@SSbI!TN=l8fSpAq2cn>WKRI=eT>HDhzAQ|hx&YceoIn=%~uH0^u9*)+d^ zL&-~h!{WQ$;$kf{SnL6(+-Rip^=Prj+Kg=9i23dT{R{R7FIZ3-S+d|%Quu;7S%nLD z*`gwI=APNT$@g;0W6x&fM6gnTAx~2R0teIE{EKoQ`DYdc1(4?21?EhX2J%C&L6dHF zL4Lk}gAWCV1r7QZxl-JOSTAp^6&X7O2+zl3lZ*W9_7_(=>?`(mnqK@bGp<!Y&@G?A|gDDW;Z;v$ZG(d7x&BY^K4f5&-ve{ z6Xu%=0t>7eXQtVEtxM{FltraV4u_0Sdiu{*z4aQ>G2D5ECC+C7{&rVj2*?M}Dn*_W zDs`Hu&~4<_LoOR@u~D?&l$dxnvmz_Z_kS6yLcNmBkyqlAqq3s=LazideQ!9AGPYu0 zlCSCV(98HIL6^tyMiX0N5J)beHk*uYAke2ssJb>{pnsZ|=r6_IrQ$cPs(AvwVAK!f zC2uz#1HDsU!yT73+ujhLq4tVfDLDBj0!pju( zouV`w68?)vZ%~p;edK)79v>I*Y04($@2UKSt+>%6V^=n=>4jEDw2V|PtWT`AtN+t* zsu9(yY5uR3-ny}y*Y=U;+BIyx-YbAd4RnLLhmPsbj#tRfOir+A(u@YmMD6R@y}U>N z3_o}tC_nr0rJ44p$*`({sMyzgL*z5@Sg4jQ;FsvGut|nF!;NZS-!bu}?&68AF1xYg z-EaDbdx6baL(1Q!?4RG6;(3*yR41EmXly#dltZ11#A~}-c!_-|?%bhL&b2X7zcYJQ zWy5&r%Wb2fPiO-j?~ZnP)+Dy+d%Rngu@<(NdFZye;<5G@3PPv5M&7|w^V)XH>zm31 zh}uhIkIPwozkZ+TT-m&^%~{LoI_|bsa4xDBBKDmmdJ?|Ck zO8@3GK)ye%+c(8q-T!*FE~WC<@QPNbWyMgJZ92EY{@=-Ve7;BsnlHSlwd1>s8~OF@ zU84EJGlcVdPYyn-FKm4CF`!CQI`QXing8d}>cThFLD7f9yqM}Q;*WhCWwKzsr9gWY z69l-5e+KckT!Ne(T>;S4uF-#~%#&}g|0uZJ{(&9T_jPpk=-=U4yvsxHr2h@9(7zq5 zKrP~Tx*IK9Qd)4|W;UYlW}gPoLec>Vwh+uYb12Cmia{r{R_Wq;=kiaqz8VHMM)cvE zOg#@eEBh{wtr_Z*y0d!BCEPpk@<|+qE=OZ;Y6>w<#u<=yi%I$$$m{2Uo4d9^Pjjxp zwisd&lZZoT1|<>bX>{0v$FV$nw4#1uGLl6pO7|eEeMjnVc=Xfw}NiZ%hAlldaeZWOZisMc6 zOiVuH91vsi($CY5$hXUnOAQsJg zLBxMG5x8Q-epHuq7GkG#5t1NRO{IhY?MC&(q4k>LdIwETeT`~!FILIn-IDjIgtBG} zNPZChPL3taRLr0pR6Mp1Rz%w8$^&g}WqG(U$!utkIK}88&Qridv&9JE2Jw9nM1I#~ zt12PiQ~z{%pzfpXRQ?ZhRq@48Vp=3Il3KVPem7a)LM=lf-dFl?c7J;!k&F5cSxyZv zR7*K@@d**0o2!_`vQgWPNmZZ5)rzD1bFy)%PBNfDNrOz6Wos=z74I$gRKsSbdXxFC zN@6*uDzW^OUr`iu@Pmt+2Wk%gTw8Vh52t-eTgxbXbctX!Z(O!!s`KW(%oi|Kc?&Pp zx1ia^Jj^xYOvJn?!JLo6Q~PBSFYV@P1YgFxdDBPVaL30T_!ksMl}BJ3P}4}U3{S_+ zE*AH3@`(Trc$sI87GZNqvdOT5gWw1C?;hILX4mt&skNiFd2YwUj=kL_1BZt$vF~ud zirN%Ono(1qMGS^Rcf$Q)_K3$I5BM!}By3Q>7iO!Iz|U%bBSW>XF)KB(M3E{N|4N~; z`pCn0g^IZ?hvl9>kQ4jgmo~5Y=KSN|=1t#`6Wz6V{YXy>qJ8us#Wap{S;}qp&6Qmb zYP7uazkvGTIt#amvI?~e=>}SF?a;;PYh;6(t&@k;NBNbCPuvETBYzI~A5{ibh)!`G zW89*hX2uedY+gZ6At8X9#66}%jI}y9=Wj}9;&Ew=`KmZbs+CMkyi%6;9Wo?L8HBdK zGr{n$rlEFzJdY7o`r%J?G!wUSX4n*|QN%{bGyF?pI3DYW#7{DS_+VxN?lP?mmSGpK zcnF*9%@rK4k8k|lzNYHQxV&|}ykb;r44<3>UaI&2PtvVN{KBRzV&8&RCg2SM+Xfr<8|Dc_J{BDnuFn zs8G@jlmjQ#seDk!kn|m)77g9N?c=P3=_NwzJH4j?1a?#gqR^A?uyZ+IaIWl^xJiB^ zu3kyT3avZ9r;y>&rMSSsR^0AE1*TKmjbb8gu%)g=ph6cj6y$v0CSaTG-jJ+7P>_{{?Q1UFCZ*K^hR5oR+pM^+ri`+KB~6(q}CAl^$92 zUpjf__VgRm?xlZA4asmz0B7EaQe^T&2eV!V-Tfjau$&BxBR@TfKMseo45Nc5Q~P@KMq7l8wc~#l&KMF|4?% z_*2oX;yK07i`xo}1=VS^bbV}Jq}{aE=q>Zxre7|yElw^X7ek7c&c9l4I}beVMUroP zT*QnJRDi@g(-Y|S+L_BZLoanqbNb@|a4cj9oThokxULIn^O=*88)%qI3i6tt9h5i! zREU1wtO((}n=#ktB`16=*pOV9yEoMN<5x$ z*K#=GymX6msGxf)D~y&K&^pxyPc%#ycgfa0_Z0o+oK!byVWQ84LPHR2URvbN8C#T6m!MMA!5*NcAY&;xzv1i;dr`rLO=htgJ%+NM9kO-s3f{u|VZ zTIi}kUvT#DR1c-Ds1^o0JUZ6VV%zTLJM>WpgeTnsrE`x1CM@x3)Gp~pBY;ic$a?EBg| zzSAFnfN#Ege(2=w7v-nR7X10Q)7181^2Ee-%VXU-3=LUEDX^VM+vQZxC}7B)%nTa! z4>Q{yzyP|OAsRgZidLt|E;6e6{}?*!zb4x@4zGi4EMaV8#pv!9L}BKhK(Ey27@Jojn&IvaQ||D?)$pV^ZPxH+FsSSR^Q3^fvlkjA+_u2 zlykjScB<5Kc2)jyT|^!ZY*xGlwxJpb-__y@Lvfj4dA~$^u3Iquy$m3ZO`}Y_de=Pm zBkBCeos8Q4H`&iR6RJ+Ngh?8@Zdq@cs$7AG>sK;Ksa{8M3n`IM4$ww(KvW@L)`^+m zl~@e2f9Tp}pRYH>eB#taBz>vg^e&(f{mwh%;X6R`@h^W?=1Lireb)d{H|A}TJq2UukIbT8cUMc6xAt?Nwft&!ZHs7vw&9!I zo31zAtnqKCEv>CH{JvY0kbJ&y(R=T-qW7EL)84lvO@Ah3c;)?FUP z=xDX9nbmxFaK&)^3}`OF6b!caD4TT)NZ_|RG8%)4q7r+ZD(BmT{cjhZ`S&Z0e^a~5 zyFZr{CVu{!pZ_(a@KMH}(!akmtC@LU8jlxoS~5$Z&4){y>IX~D)j-Q?tIn6`Yvu~9 zS|)RMaP_%|h7<+eBR@(kMjOhmjD9Wm9tBr01UD*{4j-U*hPR{2 zgx6d_;`NrT=ed=>;c1JH@D7$>c`wTzbEiwpxP8Byd(uC_xbmcBy}ikA_!&P|jz1|_ zF!H_hNbT{8PZ`qcugS|Au<2Kuk$HPsS}W|E4mYf-UEUsCeu39e$mjo)M;X77`)blI z|Bz@;;k!{*@xy^F#o^s4g&D0o3*4J6%Gk})_T5c~q;Hx$(H>kMb5nW3yf@JYL@~lo z01<}HFIardElN_pmFe^EAn>8jj^j?B23iPT(53v$s9e8_(|=3b^treD5hdyokJ|CE zMI8mgSA%NdiHSes=VfO^iAuxN+nKx4gEKqj_A}v%{29;bI`uW#zlMKCngO>O>B`8W z;=#LRLG6S#)9zK>CL>XGrc()dx24qlXjxoCfgC?Xo-LMi=)SAC;2pY~uoOcH6aoZ; zF9B@<7KTT9#oSl@C4DGhJJt_$o0SL-;HW`|$R0o#g0D~2>b0_Ijut<4O1o!Nqe~oj z1jNi82lgNr7_On`X~giIvx(r_vp2y<=T<-#>H9#P^Heq>G+#|Zc+Q+K+BQR(KeHqm zkAf|UG)yYFi!@{wOj%^=K%K%@Q!W_$Q)V&dq#Dc_XgZ`t0-GxBxzT*3L0WaOVMFU_ z?*E2u#g(%CfLGdj<58#s?YZ$iYj0Da>m}NIuWj@rUJx4B`7bfn(iQQ??1v`DSgu%s zcs88}P1HESR)Uo9Fz6y=A_Rl{0+hkF=_|o&Gyvds6~-V{=Ia#lYrxIY8vHNiPluaG zT5t}hI=Ij6g!^vCjhs>QH)JX19aazijfm02gP;n4&QnyXrU<^Mm+1az2sQ0;GYwK&L^+ zK?ulEP#ly4Iu5-HBtr%PZ-7yN3H_Xbr=R$ zK+7&&bZwyaS;sle`_Yvetm3-npE;Q(9^j>&gqmnWP){@~D2GTB*{&fGVK@ zK674;nq?~Yf%nOqsq3Wy&flhFj=#s3F|lK@_%~uKycP04oi_s|&#?P6+Q?z`7nr*A zBpc0kUNB^Jzn9Mr_>6s<$nJMhmi0_&&veHDm+%l^TRsWgD!L8gDP2J2It$Pga3M$v zq=QEFzCeG?BET(GD!^4$1;T5)p~a9)_+``@&}MLwWL)Uq(O&nX>`>8z3PmNWby0g~ zpU*(xXx-Sxsd9-*sh^DnHW^l9opQ1!zrBouJvc(q}tz!Nkx?2n5Sm00ZnntAT#l(_v|JjgLy^N3^-)`VK_@Cg1J ze-ir5@D)5G*8%;7-+`R|NwBp2IMSynhTz{qp_ld=taBu9?fHO4+f^8f<$6*e)0CV? z+f5#&TqSR%WSPCDc+M00W(BL?VP1{gl1&Zt^wY;#Lz|}k zWGA(CKpG?q6N2HHc9_~QCz(5KgjRo?4ms|1OY^(#c41|Lb45JbepwvIMjKIQrS^eZ zt+CDEjMF$4(KsO62u5c;*ZyWaQpTC*${$m}%8zEtHFdPNpoQ$ih{cv!D3Qhg&?F`i zdyzIx-@#tv^T#VMA~ovv@*NxZ1y96@J<20LIiFerbE*$I=ujBgYEu*NlRfNPNPX}A zhWy2G4P~MIcg71xwAF9-61xEZs}9q_+4ic1*K9);G+UYa4qJTmOkr*Cc*H*G*6XMEt&?s%(ZS@C;9Gvb{? z?#3TkfR2X-0Ao-2Rj#-3+qh2P@48m$e1yJ+)dzC<6P_&?h@qlKi`c$j8$}>-7$VXuQmvML>tO|53Y^!dmK*lLk7!y zu-=?`vB{{%Kb(0*AuYr$g%ay_iGp*;!UN123@kvVG)%c#=Ayr@7h{XiN9eKSP|M5g zUYjQlOPu_@qP)z4S^|SZO@q^xTKOMcWa2vGb;^=uZ9{b?zar$KW-+TFPtaAs7wG*! zDY_L{hRy|6qpkz&jdtpnA^4hM*h6&yY=a5_ZJ#X#ubSD8S}8o7E0 z!CV)G?qcUH|Bm}_2^v!C{6W2z*f<58a~d=qZEe-`rq|DL-?TpKJ0Z*)7Q)gd&(ITR zi!I2Yo3xv#6x=D|6eNONI*T-J6(W=`x}$oBO8wi9q#f<^de=4u_yo{z%fF2Z>)J}{ zp3ET2Q~*l6j$$4Q_(4qt4tINt?BGJw2n7R{U_l*YQ+9y7Z)a zer++GsYzFS)heVhbA{uH^Zqfiq_~+lzOmx^2(k#u7Z;u!GA-u~{i;vkZ|Dr-S9FU9 zXf@&7%x{01@4hW7uYJ3`IPdMj_IoLX;PB#A9ud--#hw;5#+Fi^4Wu+41>(!vTKH&7w$Q!|B zfk_u}8bKd6SJu5>Q`DVuDR=9yiJYlCdf}5& zR5`EOqN=H}rs93qiPA5^!$on1UpY4Do*%z)gzr2ex`;un@3{g0BFa?|MCS%G20pih zxA#_f)o14^DsKM@EHY2O_*b14`YZi=Vus^icm}5Y!>{Z0mbuf_ioE3CA2RZib|mfn zSoBf!L6UUmqf5oo6!Gxd?B~M9I{zU~Zxc^Hez^CKBCl_e%7OQKW@($Vq@b#N7@zOa zS)3VN=kaSvIXmk@@#ccLf|q6Wg)xg2&BVbZp5!5N|DguH^56=gp= zDr;RkPPZIxU)_c2Y~udynd6@AtLhT=e{4r0v%|CUeJ<>%LBw0zdDrgnYp@ z+vHStVcOezErgPx3N=WmLljRRGx5f(qsQ3=G0*wrQJ=cR;@473p*4`kxe0}l{LRF6 zajf8q*p(k30S!pSo!oXsT$cf2+tp2*5BXa^968RcRBth%Ql8TudmvnodOP}>+7;VB zH7mu9q2p9JFthOxaKdnl0Y5_2j*MMXFPeHbhnk)Ne$rMUW1%y!XBeMZPtut&Iu$2C zF=xa#&5vt-p(CM>XOl5Z@dZ=bj5qrmEXwg;BGlB76TlJRIoB(5dh%L0?M!LJYhsAj<4-|U6aHYH7urPJFL3qOc4Blm0t|>!D z>VuHaVP5EMID2d^Yd`UYe+oM{y4DYrXui@vws+Oa$UBP!VXYpSei^n8>D|m{^Gv|4 zqDJGzQwrFz*(G3=3Tdbj7s(cmJ@5Zls%i%zp7kAKJ(a$4-2%k$-^u^vYB6)M+SX+Z)g3tz1_zm3F)=TJ658y6T7uFV= zO3`8y&5vRg)MLgNv#%JnNjL^=YL8iK7J-q`ju_u#cHpYnb_5Xn9(I6+Kz<>@A=%h9 zAQaXYM1&X4+d(QJSBLgMVu$KgK+(G)r-_1w|9T_qKD0;nSPfMR^XK2!8qyohD%)`& z(nANg_YTFJ^n8WIxaMP%?bsxUML1haiEw>@g}4HsYb~yU8H8-Y9T>rmVJP>2s=qoC zaEe0&}4AK?;Ypz@Gz8u`h9GWCPI zQsPneMjY^8 z)Jf)kgv1VaFj9X$w{>~XZ$KiJC1_m<|#{?L?2LAqWe%!(X`xbax;%A z{?V8%ZEXEdrW}ftWNVmGD)qY7)Lmn|-p_+_+M|ke%l;tZr3FLRMe$G;7$28*fsQLA zDma)S&oi5nz?m+J3KIuykx@BJ1`EOLft|%{0If&fR^J3m#0&H}g2B0jLArY0kf#b5 zbyg)vl2j|z0h*scE0{k#*}NF3^F$aS7T!Vz`$Lf{9sS|^7%xFh#0hOK7O%}P{ttjc z`M@rM&m$DNg9uLm0TqsXO88B@NP9xN#P(rTa5~tpI29}zTTJ(1exlIKCrDuwB4HKT zn0U?f8kukEL?@e-v9l<5Ef>;MRxiwNSzn}IwOPhkXK%|~>k`e%^Q>YI`CR9m@;PC( z!;@hX=(f~0%@t~Y!()eYtM?1f|9ouxsNPI}r00-dihGbB-JRkVc97Z`i(hkaAU!EN(DjCiqgw&tgL@n9jz^m@)T0O` za1p`B?bbnUIs2d!j8E|Qj6kFBY#~Zu{TPk0Yeb(j$6`D|K^S+j1!h9BV*Y%1)u@G- zg`hG{AlfX3kqqlJqi=S(h)G8)h@EqRA<6-*ZL!RqujZvIHxot`@hIjr6M0+t8|6IX ziJP4+BK(lQ#-Emc#+(w95Sf#`pn~xT{RTn)++)Ej)irtB>@@^JRZ709T5H-dt3|$> z3Dl`HHF9q}U_9DBzgOUy)3n`jQ{`4#av2qsUy0G#H}p$wJ3_~T`j!v&4=3@Qgg<%$ z$1QvF$4LAi!%N10^zD@(yRXadboftYce-%*^&BkP)Jw=XFnIe%z2H#se1EAmQONHv z8^O-!g5qUygYL7R+iuP|QsIslb|dz4C24r75==*+p#3 z={s2GG-O-tK7=f%@b8z9CpJ}`Pzidrf%nV*09S)oE3JX&#_mnad1Hd;*7|OTn&S=U ziW187zsGaHsiGgWr0TD;UtB(;N-w3Z?&1E7=0WqE8{5mzly}z;mMfYEtN*qvsQb5N zYkhXhL_>P(x8{+yKkf1DM|;F=!@Uh{48Rb1NB8_~84mikX@Z#8+6qvUD$yDNhII_x}O@&s%MTcKjNQb+;oA; zjQK3lZr+OKUroPD?J9A9W(&Pj%X7ac`{%YM*%auK{+3FTp46;K9&Bn$ifTuFFYkI( zYTvu3!Hw_I<2RZ#%pZnLlKPLR{tjNk#wz$W-%*h+3(5H`E^agYF8G!7%1kAH$KYgJ zQqj`C7rvZK2~FW8r>5$X{r~!=9H^va^mSwu=>>b5k&>37YonVad%Ha~)@|*;>)jc1 z>jr#=xI-BwhxwnsZxHPN*()k4I5C}9i`ABOY&1*{glNBw-I`uDr3n2}){m806Juy}9 zyU~sDyc1n*z1YF1B)dMX0xBPt)-Tdl2$M0Xv{)&+nQ=E$1e)4|G|DY!gJ`cVo6_lWP(wom0+ zk59+by%6g$S+pX<26Y5%;?ZWtXkm|V^vVcM<)FSs zm@j%*+ISgRr!L4g|L8^_{GtDc97ZcZwxH!YFYRtss>(&VXJ$lsVP?JN>-1eHeS%Dk zW7h^tgni3tLI>dtv5E%I-P9K zRx$uIjCGVrj^hxv$xV;x@mNjmbCY{bJ65fFZT)g>0c&Pi8~wNME+)Y#-tv%5v>nuH ztAmGyv%S!K)Ow1v$|BUbn2~@!Y}t&<^f^G8H-K2=Z5X$E772H`8T`bZ>EYwu?wB4h z!s!ieM;rN`l%KX(KYGeIPTXRI1%5J#CyFf&vDZ8D9bMf6e9pTu7Jjrk8m1qoT?S_pAT4*lXCwYcBk&cit13vIveHDij`Q`1N8Z)~w1-o8VgoW)0c zGM1+XIYsY_Iuh%W;Ga;P5S(y7VQE5p!pZo=4GrtMmiw=?552xPE@(PH>XYVga4T5g zdpl=KoVYt{-hu9d6q!w+*vuvXrr|u$!rVR*q(# zUTqeM5%+_>M7pnog`SSN+u-`gqx8^a=ev>QRisR>kO??=y5nlb3|VoR74Psa`rnkgC_wkAP!1 zPDY0;`Iz_Y4C80!lV~%tC9;M9n7`!w)T42&>L11qN@JrY@l{~|=#{x0L#GY*M*WEt z&6w?S(>7O*wT(T%qL0;xKS28kEW!>=pH*%Xed$E;`Q_)kH&mdSAR? z8{?tIHuirOvHE4=^xoIUAq;qQgX=}a#*0c=EY)Zxsw{6p9b9*{}^?XRZQ44=J@axWd z`()Sm&p*HWApXcA}iCpX2V8r-J20uO{B-1T@?Heph7kvnZ?gXHw?EtmVI@`L)@aGJN6n z8h+*ZdaD*G=z19 z_w5?wNPa06D$jzSPmO?Y&!>qhx-Wja|-58D-B-Oxdm*+lJ z?*i7V{sXkl*Z^0knt+qwdW6a}iMH43l6$rF=mH)E;&&LJbVTykTKrT0mGY-bhI4Le zL=k9|Zt8BK#iZM2BWs*F z$e*5Gs4-u(G1Na9yVB<~*3a!T?yNn`q|>^E8eo$~Z?LsC|7`oxY{=TylxlT{w3zdY z@Poz1#nEjsa*D0dHZmN3(o_%LOMVWTqdbCaq}v&lvbNz&Ibzao%VHB-%O3O+Ni2tBkIM;9hm*>P5?;KN2pn|1_#|UDVM;@ZvZ3v-vT7vL(SPFA?_zQYqIii1vxurQJS)~^C z?NwbFOj3OnC#oxTed;mtqYFnZ*NLQ z(`Rs=*rS*b@HVtTbss$_89|qgUPBM`*CO@ZAaGds!0aR5I#D+_X0)>Tl;TSHD!gy$ z3nx`wjrZ3cnbY@?1uP%2tqD!#V7zjE%NBsy20l-K=xTAFl|sZxaXZjilm%I-0N^c* zoTwtJdnWVKb$Fs1KoexDlD!chn@Fn{5BU{wx>lAStUb}RqeRy|P`QDx@2e4?nBAah zpUsylG+qya&YToznFF87@D5wz!6|b4itXii> z)PDi~C^Z38rt{QIA5)~?KKvRz_qnU@_-`NH+WcEXCe>WYHl9FVuQ(0k!|9M4Sc&>2 z@|Of0lKdNMXL0I+XB-+ryk9v95$JNuKk8h?jQbvV~G6=%UrOCpeA-XVf&O*>* zuoyf&eUy8Hf3uU(CT(9=zMymB&jIdes@sq#IZ${ksZ^MjgzI~gw5D!2>1*k+q{5nn z6o($%AKJ)hQSn4-#TH3G?PIyFVVh!WbFMU}F-X)|bzX44;NPK^Oz#0&`k8+HS8V_0 z)LXqiY21EcTKd$f%s;Tqs!WRAU=;O^G#mX{eNt-=?3eTcqefrIx6YsJ!+RPkJKMHo z?`YbX25A{gsTnFwL4X=kg4j1c4Lkn%zKgS~pa~mOZ4Iz(TCXIu(Zt2=obmnba>4Gl zodRr|l`y>BOnj!ZcebJ@1*oH59=(_&p3W)`1T6Y{ z8Qz<^3vKu`f`9()gqd$~5xu_y$0!=vOlZB|)Q+SR3H@^fNcRuZ{`R}pM*RbUD`y^sFT_3yJx$){>yCNqAl5u&zm|DX%4SpW zJfm_WU$aKI3$_oLtyZJ1jf$bDzMHC-y>;D0;ta9XEfT#Vxze7Y?Y>uvQv;1H)y zc+@Jt{iU5{JJ{vx2+H%RD%d9*e##q1i1(yX{_zKL6f0|d95!~YRcsV(z8MeN+#C5T z`pY7^ziEIu$IIt6exv&ic$)aA0(^ZF%tG(RMlLT{ zwSLvv#c@%Iem_@dyF{=4pH=QEJi{~Ms`>RLGv=h=RVGsZU66OaAl0moUK8mXf$sE$ z(e=LPY(0GWu4Uc`-&pT&3!{BkEcXnYU6&Ee**LiHNFqPDFb*BGY;92BrWIZOMoWBr ze+F*!obui8wZ!MY#oN5ktZ(+b7+>awjt_8I6L;5T$8xn3+p&jr$M`tX9q?iHCsd?O z#TpwokS{Qv(G+&`&I|Wxv#)*(+Rc#N7VDOA?M;@eT&I@8eL@y)4Z->7RvEbhVkvgO zxHRkX*spH<*o26Y^*iIK%L_Lac)7-(HtAVOSL6n*>p$Q&G8AdEPr|0(24P93n0rjK z7aeh+Y`75qHui7a$@O6g@(90mcY@wUn7fCDq*!0}HKLiiUc%ek-bW{JiqQy55RUF} zj1cZEBu*^6MguPW=3=yT@3IYxOx8vP++MNA=WkGg?-i$;eikH}`>EMLR=(hWsP>U; zwewW;)QoayB3D;114RIhUy~v^D)u!`l#^i*)`J|m%>Da@0*B7HKOFm5fO+KVV&l{$ zPiLQd@9y7eSI~W!y=(XpeM0ul{DVesz8f%Xz8<`fRt7s|wiA^{vcoOGI}nYqw+LU1 zYfwg5B&5Q)6&gouBmK3sv0Araxo!9gF8%t-0Gvlu7IfDJ6CEV3S24RKTIC<`?bf139bRo1taoiXw2ay-3PcoihW-R`)qpVKa3amQV zXRPJ;BHInBleR8B&*`Hj50IXDBu#ZuzxF~U4!OGV6RE!YCzUN&$b`#qmYV@Cc8zAP z&RgAoxz~ATy5~|ttXf6y;Ip-Gp>KIlPkciRzo?^9rs-Ouzt!OgUC`!>xZVLp!TWw< zFO3RF_Tmh(hy1hYQh6A`O45wJB0?hQLMU{h;0wq^SU1moEQUS>hLOK(7dwuRu5^Fb z#8lV4;OqNStwjP3Yz>q`c%2C zZ>!Ons)uG1KhNP((`ahip9N#gvWns6h5+H&_JK)q&prvf@04`MV2G@d|5Cnk7^NH- zoKhdsPUON6D3tYNzr%l@pkzXQq+g&?VO-^5@?z(i-e z=eSe*Wl>UlvE<)&zO1dGTI!HzBi^0D7H#}kBh(}hjT&cUjG(ig4gquOdg}_db+tFt zcNb0Q$H$>VuxrL|%^~0c`WM+&oSeTIJlz>I_r6{!zghNE)SpKkIiEGvoA|q<>&G8L zmoO)%x2}jO?5s#s0&5rO;_90X$ogOU(7Ia9$(D50UH(5aPn1#f9(1CzbyloAF+b(a z7=8|T)Q~1E`o5{OBT4t+d$Qs^^i%W)en#=P*m=6?qH0<1SVy$9m%keHZpwlbBF|*r zm(_6|PAVDa1P=(U{aRoZH&gbGJ0alr^$ptctB2$x{|Zo}Uc%{7_*lg#hEE?Z3~`~c z!}Yq}{x#!{jiqhpe%-5|`f#q>De1P*kZz*vF9hphwb9V)ZG9+4-+BC!QG?0O$z)2g zILe$WUSR%UY7P0SFbxYD$U?kp+W{Gwip%V z?}oj~%Z0S%(6NpA&u#1*g8k!!(XNrY)7Vb^fZ~^I!&D}J>-6ug=i1071V~-!4t-R# z0a^H0fK~lEIj`d>FgHtwF|yM;%$;=gS2iyU#TQ)Q+Al0727f#gfkYo!ym0|1`{k{y%(6H zotr4>Eo$QHMlCj}F&rbPhoE;ApG4bbOktjXD#dP0TaAC7vloB83XPpj6 z?G~PQe5!15D2;39P*7+t!)#cAEmp8qUJWP%3(23wCDmFZ9lA ziQz2FLvKsK1MEz0g2CALuqlu~e1p^k7TmoZw576A>t5#qN*`ThnFtD%>X^ilKc!MG-dU{4!TKE!(mel}WS;vm~( zeRtNu?eE+=&v%+`yDgeY;@i1Cpjh1tSUk7ZSUDHO99CL6>=>5X7gfHY(Z7pfC%#31 zbXgK~QMoNGyXBqb*7{ty3W}>g?!dqt}=W$Knv|F0KX!JCFRx31N)|LjRmw)l~kYUh_X z>G+@;2ne*ZP^1j;?-_ZuhrHSdO zvyuw}fI%SNV^)C=viYCqeag#-wW@`YkREFI@)G9&ZMvOh`lnFif4{om?`Ao2BCBkj zmv^nU&l4uIFV7ug+(xao@TRP`D`(U?oua(A-+^ynmy(36dRC?Dam&OdS!QP=KEpnQ zxT~wYvSl7F#q;v*h!L4Jxc4ZdtD}o_zMYHN-cyBX;^RorsT{_7W%vbGT5}p9vuz9CE_4 zc&BG;!^1kF+9LNZ0W3T0Tj$4inZJYEd}b|UhM7JhXPQ_OvpLnI3?Gn5YTyH-2+!jh zGkfrCyX69qJ?AqK&$hMTnD2A)F-`W`K=|evhPq>8ru`RJ%=J+%)o#Wt?NOxh=$^E86>>}eKco8xI z5P^QG`Dx11m{>2+yLev%fkGz08<`=K)E(NrD11?Q=p)a2e)}l` zyEIiQ*MS$H#tcZXh*Oh%{Z%i>pK;}f7 zEBUPEjF}Cvi1HG8mgWqnS++ta{n9`MYj)`0$Cs(P*Hh)|mPkZbynYB5J8m5FwoD!^ zr(Pa`;2#XQVUu|)%?(3e+)I_T#rCMoFkd2gu|4{c{||tvb%}TYMsDd6y~s!%{O?`r z@b!1?Q$F8nG`ku;qkm1@VGOFRTzBb=0+XiuLXP!EgsiBz6L2;Q=pp$PXMgY)$8z>( zChN=}6oXfQVqU3Ab9~>uAk-S{6`}TD>qd$3#!jpn(#F~Iv_n8SC`(`t`_hJjnpeFC zkK~i!R)6MjQ$L6_+|LH~g5O=1K6wzUw2Dd#zm{1>3b%mzV_=c#lEHZ5k^VE3+q@^P zmw1No`-5dG+6JdxaW#LD$S*7@_kDoq*9VrY`GeQ2BCU1KsmN0=ZbCo?1~V~5@=xS* zzUwANAsxQn|bbCus3{KE@sE9gcvkVnooyp{*I6dBI9A442#uR=REkE4yN z{7~oerjfqCOp%{5An@TIYrq$?z=qFxCpBk^a@AqAB9-}&c4o;8UiDt{4tz@GNKVro zw`?}r#~#2o5{e+_!0)9mRM+~@vZYO$aapaZQpcTJ^G~554lb$G{3YOQFbK}|uI=u#PT;b%$ zVV;^G1A?pd|H4iq;gD3UN}GtEnr7m7k~Hk(#3TH{K0F3qo2F?g+%Z;F`fkv+Q8oUs zGhThP=NY`LCzM3zxiK>bTx?#Ces?@P^~bebYUj?8opp;>Ogr1@xpoQIc^L#Hj50|= z5(8l}98wiTh?&YEHSjN)`gA9lPBi>OYN>$Z_$2@%-?B!iU(F;;-!g+1bN@%m9}1(I zjZV=Q2tll+{61E9(|-1yzaAEQzXfq-emYr>6!maAYvJry&1xF7gF-Ih4v?-6{V}l+ z9y7C@a-?mR-J?e;-Y}suANIS6REsS`*Ew6d_3U}KE9?4bs9mAfV_^WoAx5lUmk=g? zwvIJOS-zv=@uIT&G{3xBf0rK}MwW@=zSN5|1El-Y3jC@GGMqp1pPWB@enii=9zPM3~u-F5I=vCh$;^HJy@WttS@1WpVY1 zGh|*p=+s!Gakd<5rqROKj?gLFNhHx_8B*dJ2Pt+=)`IP#rk&XPryMB_!ZbqR=zqqm zg+u7BiBxp&ND(@7zJakk?~ze{mJ=ehcsI1Y-V~hDnE^c49|`OcWB>;zJwXQfBT(qf zIgor>V@RA1oGa4b)^PBARGhiQ;wCxYISskWZh=li11ke@x5X#mbE7v5H+v7wer&do z{#$oTJk*F)GcyRI$TfrXP3X#m3xQ{R?{o z>grpPN=HljYS$J%;F0V7CO!>an|`FU(F-9vQApfo$|sY(mab%fyKa)qW-YduQvt6w zXBr-(e<}&mXCkvUGC#2D4-eAP+N0!0^G0Q3y^FMK`YOO4eUZr3eWvJ+-h(I?E*sg= zaRC0ibup}@6$Ke@Zvx!v)a#tO(zWNiEOqAH!+N)#JU})#0I-Uer$hI20L;4n!&wa2 zSqDvXU0aZ|wpADitranhMZs4iY7zCoeXuKY^_oH1+wo@6>DEnh-d|6YJf+();^XVU zhoA2HIsM+@yrU$CGgE6yrMJPcXSfX@-XKerGWvdMbez%e%TKGbuQshQO1s$e>EkZh zU`i|Gwm212vXg1<96%F}dYg;a#hxV_xikhWFqqdsk0~x33)F z*S#L~tlf)xI2JE5)@*?htx}pNV8Xni#=r!rf^r$E>Q4L!GQjGm=z>p#Rp_VgJ_?MoJjp zX|`=9gqEV+XD-n)%wco4sM#}j$=1`mh&Bp1PNukwT|F~^=c(SBXyyh@z4QoUzV7ub za{Nl)&p%_GSCTICcYd;%{`2WN=-}V4=-iIOBwvv=O{A8vvY}m;Fv5AO8}vCg(o#I1 zk6;tnCh5q3VJ_fl)uDN+i;X^Na-Ci|S*&MD{?T8O7HW$m#5t1a_Uz{2tXb(u@m#{} zP5l6F9bk~L$#98gqU*qZohyNutKMpkDs$waimCB`rRRreQz=}eG_czV*gRZCT?72& zki)5T2=LuzebrB9=jBT9d}f{Mb&$2os>6h41}T$+DYV%{UgwxV{^&@{REe`i4b>RInlpdF=CAKdV2`tM)*1GnXVc zKex5MEpD++o^C%$|JnnUYBH<4Uc0BUYHCZXQ0md^3pg;gkWepAwHVa}yNM7c{>O;- zJ)hG`=bN79M!~dR5R}w|bimBu1;AUT2c{gU@UBs2e!~IVQ=MnrBF6aM{nK~7!n82w zFhCJ!8KjazMcyVJHGYVDMS$Vch^t7ld4HZBbTQ@i2dq{wV*{oZ#xCGR^W6`uLD}fSP)uRK9_lBLe@(VHni-R=RiMlCVp$uyiZ>_^ zufN8-&{*90W#IUzx#F140~m#^Gs>czBR*u+)81Q4IS6Ns-5W0}r=Wmfr-MP8t#&RL zGk)vpC%Hn*>ekD?cU~CW&F2VeC%xpGrfJ%6?Rp3wvKNzq&M-Yf*w46P@`N)^+HJ+g zD=pag7RG(XBes?AN%vJ@eoHScl&(MOvOV66sf=qQv~ReD0EfNNKXdY(rcwYCCJ2L| zM~zpsibJrK6T`NIsb~*drHz{i@ZR&uZZce$pGr9B8rft!kFdg?5GaFXfrQREHMy>G?p1w8yz=D;oX2vSQdDlQ3~{+Sr|0c z?Kt$pN*iRxymRY&Y=$v(-3&6(9|}3jGy&uyJ{oq;7=Zag9i(ue7FNz9!{>S>Fy;sn z(I#(0FrhyIsfg{9BNMY-ErlCfUZjNf?EZFEu(l$9DyttV3z?_i9*6!jOC`G)7&i6r zWgY^Qz{?T!z$FtVWG4gO;`-(chC|95ihOzL zBrIW=WOy*VXEt|uOiUTpjIQQ;4~-4Q_gfCV=(ig9GPI``I@ZB`KiR~)B+KbDQ8x8E z&wlQYR!#M(Rgk_I^+R5#+P}v{OX^$<{M0%PPj5;#+SxdUFf`DiyBq!oWYk^LS5&Uk zj#gZpW44mjJ4A3*5peyi5bCX3I(K*uBig6*7;5GR_PnY6-9#<$DJw7T{*%}k`t57) zudkbhPt!T_tAD5(NYPrz_Udy+uNwo=g)R0NaO+dzh30m8Y@?CI^?Fk(zb?wCsqTQT zx$e0Bb(1Il5_cu1X|R>Ew_8bERV@d+D-S0|ujh}|#Ew2@)IxK)(E=SMqzB1)p z;yT>=89LFI1em*%%!73$mth7{PvX!1-cH<+|C@NWVj=NJR~3P(euuwfy42W(K}Foc zwit?3!L!vP>!qJMu1u0^BPSo0oEG=wNhFQg&f*7|?GqtCmW|i^m>hqdIN%8=H~24L6S!I% z2~N<(01oQU&sP&JNd2U9qg?|~fl(_}vAOn=adu6S)l5T_LucDAGcunqm((1jfVrxILIEK)JCop^vYfyc9#V)HFbFuMfb$i&d_Ss2OOlPLp9XzMtDjScCERFkTh@K z#4U-o;KYvjmL_(rh)yJ}2~Nyhb~0h9U(8BVhgy%FbYFTo;w~yuv=w02QmA=TJ)q^Z z9RA~CaXBYBVLg$vu^iPOgGCOm znuIM`42Gn6V*zmcEt*XXlnQ0?Nwpd$&_2S$K+$Grkto(?YLe9pw`(?!77DFq7NlFS zUHw_soTV(Nc@XE5S(xnw6P^UQxO1OH@g!PrVl2w;L+4_Y&|B{`2P%@ zRX|i-7lxVco}q{C?rsFd22m8dyZ!9$?$+N{3`|s11f-PiW?;Izn4bB$I=AQM?6uEY z>wTVGWX4(stArAJV zQDo%sUF`q!a=Jd%rwseYi{z-HY{uV%PtZcFRNaB`P`RC=Qcxp$%?9&(C%B4M zdJZ>*K3QltwnNFHN18aiX}}e70=P#V0jO4Ov$@MdAU{Mc*ixo1enZDr$blb!^r$y$ zw71?hX+Qp2sY~ozXI*SshJN9zbE?X{=@wkr>NItVkzn%vj=HMZ3stt<2TZESHm85n zXqSF|COh+?N6`F{FWCI!s%&kOgW}?tJr^Ti-g|gl+cw3VJGcT(5u9*aIDXa30&=nc ziT?@ZQFd6`(LYpk4E8jUAiqk@p7iDbukpnxiR*{e#?U$$K8ttLcR6lLm>?7oaxGz# z&#Gve^FO~T>}`iOTObUeaMV3x`ihnet9dTNo5dycT2-iEgMO_XWwuiy?9R%Hfy-4@ zh9BSoW{=y#MxTiDwX`6+-gtZjbF~~XA^E)9wyZy^En_5NbmN#p&Kc7iRg4R^=X?Zc zp85*x4e&hr5VjAOMcR!g;KtE&!BZg&-7V8v*&|h*?5ecdMpr&?T>?HDjrD#Ve=ny! zXirfi`DWpP@okyA2mS=))&~=h*T}8%Ca6r)|CNs89_u@(+SWD6TG5*Y51_YUDUv?o zMDGL_0()%kMC=}g7+2RlVPGnIy2BeC2TX(CXy5o*{YC2cZS_W{{sG$+@h{*FKsLyT zUjbk{6g_3O7Y(a*@6Ye?ODb79E5PJsz#@=l0V?r&f8GOU=ShIHb z=q1Be+Feu-&D-lTO%iltq||NW&@}{S^p&|=`WW!q4nY0@vv~U1Ho84gld)FKeCtFx z*V0LG>c0fC`mohm9W36hDx!O+){RV7U!$RP6YdbpnbE^w?~yFzx}l|*`k~A4&!Zd1 zbsQ}%h3nk4b}+GH(!Y7Fra#0MQRDl*|N3La-e`eRWJWm(UWLGBUS2&-fxzWx1;AeGMryK)_e8X`+8g>_>%ds2OtO2 z0`(WwMQ*X7YIrWzeq^Rgw?yx98u6T(M?K>+(?#q(3AvF>(ND7KMG#3D^ADqV7(PA024xA&iBO$a$;SzvLQG-*}&*%oMLqwSrZtw#%Aoz)C0_mhMIc z#|J%AJoa|)SCGy&o`4i|JT~SqJk)G?tm2`0mJ))Tr*U)Irh5|bT4M?~^Zosu22P<| zTKYvd>f{57znl8^{5(7AUAvvr(^D(X;TLM384m%VC=hC$;}&d*$42CGFF)WhD$7t! zs!6%T6(q{26Yx-F1$oBrZgVXyVBlOWZEUAbtZZ()RU!hA( zF*sN2E8==<6fwtAOWzCSi)j6UY;hJPDWg^doq11k;gH^q9D$QGfTIn%|qv51~*`lPOx%scc2>;p0p zyIuc>B%UM2p!#jH9aY)I~wBY8kIUY*IHL@eJ z7$b42N33u(LhqsDLCfv3th>fRhS^fR<~;9__B->uDPoKXzCZF9bAEUMF^Kk+xQ>yH zzs|jlzAB_4$YKXXq-Zs`lrK`u<((N=FLY^E%0@aiND}C>kx*%DBVLzO(`fB%6hV@E z$IyPXD?~A~hEl?Jwm&1oP=06$#8ak7w3oFIY%yugN3}5BT;-q|Yj|jwhhn0K94$VM z#Ge68fIvr>dMof2-%*n=3X-kqJt!_|w+Vt;KXX~FA6SK5dzq7mH?xJjQzEkXr1J8Z zLF&~)rYRdg{VQW&s?%)vx(MvomV@X!y$!JcjZH%&i9mSTxGSl}E)*LD+Xj3EuhA@q z92f4ehO%=sM_93q+qL?qKuc(GTiKUW%L|n=e14 zIjzane>LybO@};F$x%I`V4Rp~!?K1xp~HHK$b_y;_|eWqa8{=t720(I|6gYS;#9kj zrnd#o#5bR$?`;uDTsxPWRJ{Wr&wdw_L$AUqs&8-9a{8ocR~6^xd4V_0{2!$t)yI2A zaGUopmtSNouEM$zvRKTut)dOt`aAl-K@A#|q;d+8RQZ;Cvc8Da-a*5C91@_HGtQya zoY~k%d<}j+{}lNmcZ>5zUWpe+k`?TzUmq?4>B6@;7|C8Qo# z%O@>{Vv^=i_PRQ|=YX0$E*Upbuh?h~9K;_2*8TzNw2u=kG{yrOk(mj{P8mUpbH`AA zX`M)R{5<%x)IZ?c)AHy{U_$Y&hhOid9yKp*2&SQn0O zwk|;(f#F;a5$b~0IZ=~*T;AuU6Do?f0l}2mndl%X*{IKNPtjmi#(pSzJk64@>V>aIy0kAjo zCZ&IhPf*MZ-=xHXxjBp?*z_9<>t^T{zME>D|2Es2zcPuR%Zk_=)e~SO)p|YAy>tJn zA-hSy0BWJrSC{I53MW<6CHtbJ2ZYY_{U~kLbm-RX2jH-*b|^o+37(U}KzxcjMc5e8 z<-IJJ7S|AfO)U!;h+P{L7_=h9*wK6j?oP<)cW*)N+`MztrwD5oKEp=mzYWs4iK8OzawN zFF8k@;)TFeB|djQIopY<&woQmNV@?4Z=t0Gy%KwcI9d7r84ihV*P^>gTXWhmztXGV`+NYVFz{>kORd+y zI~ABlQl1jJNsnp%30;kyBADfda+cjH^9o2g>^Z6mr@{XrG!uE~QFIu@)9#5)F#go` zz%p*!WwZB0W>fvv^gs_XyvxufcPwfgVN9@pVe?j@<6D%$L;*$BPI ze}g_e!5&-FZ@?emGV#$GZ%mZ28eC_<8QXQ|70$XQAzVM5TWByc0}ax#sPXoZd-C0b zi}^17Zggg^Y*5m>qc5%hMbD`LWZ&>W1HEQMuAxnso1X$Xh#ulQJqDY@Z8n}6$`noR zjbz4k#?yE$V*}?~wLSCt*0moQ&HB?e^y46iifdjeX zZGAS>k6s`5-2OA}=AjYFhp}4JKV}YSIdiumnI#oBNITihLd(|KeOAjnDSglm7@b^U`9uiU5Fr~x7X3P=pQ3eGBA7dv#`GG| z4&7jV?D3N9>deq?=>BX54c7uaxi0WrMJzf{w-j?ua~k!Sa|gY@`6IFWT_Q62SrO~* z^Y~BMuYNuK@FV`!y-w(_WtoVl72VY5 z+)_M$Oaa7j?(1VF%s8nyfBm3CrOkw$4gG6*3agj70{(E1jL#FjQMDNJY@@J!lu)R~ z>xJ=x`$2^}$wP7umMW%MpNoQYiGn+_-yAlN!aB{|!Forp;O$|2k^bVjXmkdszR{_~ z_$ls!g_-`_?qLiCeB0w9$cTGofSRWWchG|voZ13*!FN5Uud;J!xZSrE!?@bYP~0Ao z*o?AFaIHC0zZAAwv>#W-FC{;d9k)NIZ6GsrwYUrV{cu;)QoAE|YW;sOxcVH%EHA{G zWVaAN`9`~bX^J*bh!C$}=CSK&5%h1o)tq>!Rv!}ioAP^Bp8w!%l2>X!`4b=p&d?~5^%d&m1^9C*3VB#Q9g(C! zAs#AjL02gOCYg%EPuCtCk?LHShm7S)uBpq4G{-{O#+zt>F@gBi_zV}X&jnNqJC!#( zm&l+0zG+CP7zN#ITmpp*tpRUhdxHhS^RP~7I;LBZPgtpWfCKApz?N%$EMf9%ngBth zdn_z7*Jn2K|7m)5wbDj_-7$lc2UY*pj=BAq z$(sJngMF>CmAAHWita+!E6fiX%DGrL-QHPKh}>fY*_D}q#z?)lwo5Tvs^XO~uhLfc zE$`8_+-mo0N^d*TvbOzpS5;@$P*Cq|#;L*YT-h*FuyjZ%h#ZCq1-!p1t7Sc=6aft= z2H%UkFm4DuEIj18fIfg9?>`H>)X`>3Z~AQjHgqT#*IO8?|LOm|Y}xtkf34qsDw_M6 zDkgqM^4iA~x*iGHrH=zGmk_Gj*Yv4^Dwpc`5whCaglBgL+PnR`P3fV zp8R6W(*ibh*^C3mFBvPPk&#{Ozuxf-o9i;xQYwv~;rUzg#QVGSqURP-v-5jyFJ8}j z0$t8|VjC5%vfWlK0o7W{;X3$Jj1m8ykVa;cYe*X%JP3y!k7AZNTt{qoR6*)|?7`+V zDtJY~u(hY)zLYd6dmuORUMtemzHbvnz@Lt5*Wbge1gX%k5C)_x&JEE({*9D5ZNtBC zIpny=;fL!7Og4EZFxpyZaO9_GSC7s#wQ;}V-dg?(bMxxRlxG^UsB<#nHx{}C#LRf< zJU#n7wlR(d_#6rYi;$uIX znC&N(3Yd!~n&*1}0N%c>Fu&k@!p#V{D?EnccO`mDC@Jhp#M=P>a6`z13@K%f+n=di zoa40XkipC};Bf3g@Z+Fj_+`(jD4FwXw72~YG@W=Er6Xh`=aT~vZ=L7E$Goax!XO;1 zEMg_}U{oB07qt;^DKQwZWvYa9uXtJ-bg6OvxP0yGSh)Nu^w?+^q zlE03+p}-39|3Yu`mWOZR3w)u{8e+=$FUT?g8|{hhb(vo_OAMkzB7S|kr?<$qBClL zdM_p-dpm)jbISf`ZmnxVRwOopx|ZB0@1;Afc$duJngQy zQfpqsDr8BJkA0KB3EG=YMISd(R~%cp@Wb6JJhwY^j(vpxTo6bKH^|Y_}^S z1^L3`j*Be&UP>Vdq{zeY@>Y`}a-@gkJWy+GE^C)yX!c}01a z%3tbt$la7Zd0_Jn1jC zIz7;)3_7g-OIj|z0eHcAp*g`W5fv()v*SSNW7E-`VJ?I){K0^y%~KUIh{{jgRmxFO zn;a*vl+ISJ6Q(FjhuoE#a(B)ACque{$NO})Xa7@We|sW%+b218B#^MD&i<7|i7Yb=eNV9l?g)g#MmCjBUSgL<+4 z*}11no?Uox|C#U4)@R*aC(D>DNV7)H7(Q&Q6Ayuwo0g$`pm>}Q{2iJGcm!TJ{@Ktj zSS0^AY~$ZM!Q=jNV!k8_Qq}2L34#(@* zPMh0?oij$3Q5w1H5l=;-M!xu*=#lsn?Xs}HTgL%(l#KoB3LCmHc)EW(y`j&6-O|&_ zfp+HbF1Hm6D?9#)^?m2Lzi8B+LYAcJ9KWM{OicI_C;QRyOmbT0yd`XlI6miNx5~iIUpAo39W}K28WW3=X zqrap77+o>CX=KA#=HOGtgTB>_WwfUw8f9=F5+&&%*z+c`4!c=5?LJu(G%Sj*aGg^+ z-42bVKeZl}EwqDzBMD4It#c5tnJ}ssTlQ%hBp5Z1ZB|q;Ur9pPM|oSh9~oR;@91oP z1N|%iBF`dfl)sh>^uv-W+k}Z7q;GKr#WynS3_T}p6wY=#f+EYBu799tv8@<753g*K z;FEfEj=9Wi_eZiQuXVZy9&jDd0Va;Kdrn(IHx0e3XR}e&52VXl)8$KstF?!@(~xDl zGd|zQ8)G6P_Qq5vHwF*J9rs)rw9Nj73kdN6*{&betq{!?{-s~1!$($*T%@(p`dBXP zdE#plg1ThfSzl*eVq6a@Gvz|6EuGL;HW_lBZ3g}da2mOeP((2YBFHhxjRZ;(6}K?> zJL;|T4%lrh1DFB#u$4ozEF&;q>q{scFyGt{{>0w_Z|XsyygO#07mjR3ua*v=KATce z!H^lK6wD%YGZ}!r;rbbO!<&bv1nea24u~RXy#cr)7Zx&|*oxAjKD+z|zlk}m&P`E| zj<~w_Tvf9MZqc{0LpX1xeG32acZQeNt=8o*E3gVzf}q=15tq8isVomHgn_&B?-N};*;^QCZj{BBG zO|$2ENH8_Tr-&%94n$K&8ap|li43!ZpV&Xj%Wb;AH2yr&{o-p_-GwT2&702Z7CI9? z2$KJ$CmOPN37~w12))g`+x|LSN)08h^ql2Do8Yz%IME1!g!za$aHj1KfTJT>xvE4H zOi(XEuu(XUiK zH|b@AW+|gV)6>z%$!}gUjOc|ku$%$qZP_DRm1YZcuOSa{&iVv}1Z%OE;onIah%!ed z$i<<{@DSW5?`K{Ywfu1xkNiSQ>;LhkC4<${YrN~y3#vS+ofRlK08bRQ;S0Eqlze6= z>H6p%M9Rn^bKKZ(VzEmQZzU$lQtgjw_~xdA0CSMbO^c!Lbqd1@-CNd}fzvwG+Ec3lz59C=VeB$sj*hOF zxO9HOw@T*W>ePDlS~CcB5_|>q40Z^u0yF~q#^*~uiZ1t`W!~=0q~#5t9=gmIjJ#Bu zg&S?lfDETy_JPT}ob2=8VT$uT02z~N#{Y}nBQEqR9}93|_we0_?U#a=x9teu*(vm0 z*`MZce5@G-7i@t1Pre8AKaDf+!T32_==f9fI*s1+L{(+0RBnM6Dc6!;D!+Ry)SVAn zfQXIw;hr6FJUA=#j(>UJM%TuG6{LM3b(lxd4A_ArlHEw^ZT+m&D$VJnNUbccN#`3K zXFMB;uy{ud+Ew}CAQ^=J;OkAtkn-^js58(_s7lv4$b!&y@W*kXFnvl65||x|N94`J zg-w5M8_IhiXvvyRyOngBrHd|ApA1ij&JCMRei-R!&x?KxI~Fk65J!As90bfl-Uf1= z&tn1JPn?{+M%}hkH6F?CPkcfmR)wse`Xo+Uyer+Y&^K#C#)|Z-!Tf~1&XJMjn1LWR zc%A=xo7`7tcK0co*oY6Yn-y*kc|Q3flCXe{+gh}Qd}?xq!?rksQ&rGI7nxTB^^xm8 z&vHke-&1>C-~r5x(61V4LI8^~qg}RYQJVd_MZc40DZE_DV(Am&YG5_#zI~I!e;$KQC#W0ANYZB1HuOx?cfx*$ z`JUz8OT*uKzl_Uvm&ILo+ZtW!xhKNO_j*LDUslw(@6*Ui&%GgXr>8#W@N1|^h+d}! z@MVqx4CY2@Wn4Bt%j{e!tfA;+z;)Tm%Jr>TE@PV zNs060b0cyB9tWOuYV>}MX>|PtJVK7qfzVB&Be1tjEaL3wQB2&}Q)Cl!mFc!PS(FEy z#`E!i4>QBRuq%QrE=yC%w@Ui)^ z+Y&&xgADf6ekZP(gh3t!v&9mLS0!pRoN-?m5*9%~ zI!>X!4*cl*J$k19o~T04cE3xM7nG-PCvY$5n)W;Pn>f(>E-xg4$JrI~k<&pv!+A=4 z#R*0Ca$iHA@bhgV{>Sk-+(q)coV(&Ed4re^iIJ~y+N$YwdTv+};EZXMlbN?QcNr)2^B8;! zk^L8xEL6ecl>g8khOMZ(mJ0K2otW0k+FE1mH2hrJ)m*=YeyZ=3*vvVg;H#oF8*S5! zbU4&bhPeZ{h2>aIq7IJ#1HX`B&5wBJR836IL=WvEdk)>3@r1F1zMrM1`*8L!61jg^ z|F{$}g2y+`;~jw8c$cw`g7cUo!c_R6XtAAEe0uzc11OVsT z*FqEh&;W#AzOL8#oa{4ZNZe0{wyfgw#s)~ zf%L1SBL1Tf}Nk zhBbPmSM#wKA-&YKjPKly;!f{h#|6`9yz9(OvMmB4xLke7s~5N{UV`h0|44Zk6hpr3 znuNPT{EoPX!hy#iX%@LnJMLiGsG6(atdQypl_+bd7Klin*m-;-Yo{WIlZiY2&d`U| z4zM4#?O;a_r-@%MP`n)WoBqH2=bgdIDPtGSE!u|g%d|lpu)2`rtUS!UE&t40 zD_hDJNOJg%qIJA6Nfh_6iO7Lb4zP6r!|Zv1#q48F6FnrP6U)nvC10vXLq?Ty0$N&& ztrdO)hVq~4A9H_cDT4RLv#Lvw$uKkK9TkuB4DE%li`Zf73b50uToRR7+&bwmFj5p_ z$>r7Q?y}m{*^EWX5e82Y&k0vigk-H$3NjWc51HSoI#oucapGElt?QEgt#~U>`fHJB z`vfEBn54QDe5Y?*>6Z$lF06eG_%?k5_Og5rfe+n@f%*N0ZckqX5avRyrK!(M17Qb@ zG&h)WKW4SzqUp14mUy?uhc1;f23tkFgC_3t(U~kW$BFSsl1YauuhDrbXU4F4Dx*{@ zp}*BT(%+btjP+S=kFKy?9C>Rudw32YiB)B{On=kbO8jn4a%P#I;V;;}0vCXo`c2R< zH3JqTw}T%Qk3p~TvcS|43lLZ@K`>vRa=P^@%s;VuEO6tf-is@7cQ#9_NO9sRxSt{$ z@|pw$?UU`YyDvXxtdwrk-4i}G^m3{#RtD5KiC!umouJ%LV=ZJX<)UO-p3*$T8Gt3w z-{NzIGMta}yL(p+91Qw8d@Ia0S{N3@91KKo_ITy-W;ws%ZzK5&tl0nYXJGzuGq7*j zCHNZ7Q9_K+h$)ebf&U7DdLKGTag>57Q}5YL82 zLra5KSdji}bX2!hY9rx;f)6Ihx#lHunCX<#VBMfih3qqKN7UO=k&D5Jh$@&3)`3t! zMaUrNOVn-XMRXQIiMfp_o%q^@2xiIyQX%CSsR+*?ND+H+Patvdo#4LlK!}lX0PfO% z!rqR4De|Cd@zg9xOr8jf4jO^Gft~dW2TSnx#!(7zQh}C`RQ>J z3iE&w4tXAPB6@dF_j)B$!`exKhu0dK34r_5sz~OX7jEQKcMGm zFyxRR44SXCKyTUABRB{LtP1Z-$g?L9UOT_U{&oF^%5_|iScL}OMn`rKz_neoEca+P^+T%J<4+MYv=V|$6N0SQ zl$bATl9ef%m4YzMTRKRi?8{Md+b@a9J%2^(IgN%Tx~W8WK%UP{yZ3&#jR&c|syq1C z{1VV@+9}=Po>fv*`*hx&)@o*LhmiiX|0lzZF`1JhdM*5+QmPobBFH<#KX-%SRV>yN znl#Un78Ykqq295g^mGfr>&2D`=QYR^_Yv^RitXi&-NkM z9#R`-7n0$qHP7*yB~PUOu_5ohtzT%nqQZF8%Jusap z@oXeSkbdIbAzN@2rd`;-Y9v-9@x^Wwp28(b|5CJuH=a$XhCr)}kGI-)7BMfN2qy46 z55I}kVi>9j9CI)hyS?Qh=5=cx_Hq9v{Au=A(j?_FheI}zQw(OK(|?Zkl+SL_Se?sd zcp#j_y9=^Jg$$p`dDC&q_l_W)BC z;V$6`Br`bI@-Xg){!lnnZ*u=;9K)yB1wxlXnG<;E`I>0FK|&=7`8x6>UXJ~G!3Brk z(lqCP8W*=_6U{{l@PRLeEEfF-nK3W|I6d&koXk>8Y)s8D9n+QA1i<^?Y}^OeTKMmWYu)zu?KVdo28&IaI3!G!bfC}umfQ_JPfEri>tOWUj&*2In zPyIGPFDGq^t2;vOtX~$WvkNo3ZCntGPOD9|18mA?APM?zLRghlk zH5QExbPtG2yiKj0{)K$J=ndv`VH(1cw-oN3UXB#UAI2V!dPFq)f+=&*|6$w}9wsO| zRg^2*BRFr)(Sq>*LEXHl_BqjFAD7Ja(G$eG^tVauT!hc$iDbJidneAAj3nQSf;)Qz zE_5@yxOnb>)_a*G=X{bz?E;R_Ng-dPwIME+sNfLj!H9)uNt%tYX1c^7WafTqXimQ8 z$wViw_V5_@eE(=CZ@1e7FA@W>7oi1r178BUcFTYq5E^s|xdn8RSOc8tblEO~`q})1 z>T4)=`E9IrC<6zOn@H!01+I}KsOtblL7C|kk9BfgKH>3>v3gRe<434`x!I#e;_SCW z{Ko5^Fb7NI-%zJ;ZEP@iCO4c%mP_~;eV))@Nf4@mWxNhJomqm79lcJ7qy56oWuVX= zJYV=)(F2gbB-)CSyfCDRkLrEI9VVq@7a(161oEG18$_&d1}G=AP-6C0&Fj&HvdY1$ zLO|a|US#)du3P73?(6nwURfK97v5&$!P{m|JjvWcZC}{m+IF*Ex4mK(w52m`tvIG# zYb)bsV>V+?!%TW~>)7ZJqk2T9^B68S9T<@+-m}iJyX2RK=2=nQ4`CiH-LSy=X?C|O zxtj7H6v6TDh@s@~H=2)r=T>bipZc@(m;M)_roHxKleDd+yL#~3@OnlLqo19~Ucx@Z zVNN7PG($%@ik`Ww>+LCHtC~&^R@Oc3c~-Tpee>@(HLI$wlrF6!KDTcQdp_}&&#rZr zmE7oZ`_k2QuBNXmWAsVaJX1?&5vsY}9{thT(*uce{Sy|<+AI_+2g7S6z+ub4V=N^y;b*H+UohLVv{)9s;j^RfO0Yw{2sn^SFx+k<``RhyC0`3WCBS&ilKCMY^pFSc2mQq5zKZ z9@>Pg8p-a|NWr<_aQ-T|KJQ#D@LPwgY+xcp5PbiiZb6A}9P0 zW5Qr>Iop`DO*SPr#V$DWEbey9G3V^StKK_2mWKXwIu(~d;-+??mu7y1m8R!Hd=i&I zZ-#S`XMCFoCDgS}pPl?Y{GC?$Vx2$%NQWa6dFR@oZRFb_Cn?_HZT5jtbO*oK7^krK zB$uyoLaHvR+M_nK-Rox1A@BC!6JA@xuX$ue$GLIi0$i^o6I}Oa_;^>OG2^y`hvnBf zLKm(=85c(2w-@lJ$~0VHd*rH!<9^%YZn}1+7;j*h-q8g zD|64fK2G=yN(`9J2zFW7_?W=@i$E3i)PY0kPplVsrG~}gGdjG&(J-hrTaK8wgWG|Z zkzufL+$Q*PiW~H)<5fVO<6(0vd5OLb4;oLwZqshXn6+~;@5ejQ72`RmQEfRqMbiO! zsmukDq|v~0{B=M%YYXTe^C@_kwGmRz*$#Okss}fj%0NdbGyvECm*ueEK1~M^#CJ8G z9n>(sb%I*v4hB_DSET&(#q9p=>#?A2kxyysdiMu|A03YHL>Qbl3shni>6?L16%gQW z(M&6af8K!Lk+klDA*EHaSs_&IQ5@BkD_RUTd6ubG7GiCeHv(g|yJ7FGy+}VqCHfZr z7^a!XMCao*2nWODs5n8X*8l5 z!%kVb>9=THXBrz8H}w1&Y3%yb5k1n@CJ{RJ#g0>%o#tQ}#^!B&Y-<2R>>O}#yAPBS zs|<6=#MI>L%4r-`d2gItHvCEwz;PAd7g0r5<;8*`Z67<+ymv$oeB3!7*4c0Xwz;|o zxVTbh%&HDnJ+A*HTHG4S8||&(Y^OcsB3Z@!817BM#B^4m<9z0ovFtfw`d4PwXbwX> z9K_HJf|3Pdv2)E3vdC=~bNnt?|2R)VpbvT*;v}>;IL%0c#tr9eIR6b-QZ&yVEBOi z%g8gdnbz;|ew5*17%e7wjx7Km9P8Al(~rvw8K-!6n43qNSyjEa*xU{TXJv;UXF*R2 z=f?0w4u*Y-(;{kP9aLn`bgzzTU7 z=%(Tn2&xoM@FsA;1_K#%3$g?{m$(&F;K)=oJKP?S5{*p`Xorqcu*(?FTp*!n+{Uwn zI+JX~WZBj>&2+WqwHj74Q*xulER3OzO3q8xC=VE5S~pO>#~>zoL9b zr%~jXXT)FV&)7eR374)g)GMK2_2r{eUK~>61kVr{}j3`}UrxY28dT9f4jR=GK zz`uk1k1I#?2&N$_48P%%DQWPnLH}UBA$c&dn-&_61H-7GcQ9Xr0v@fbK+YD8qEond zTmriTujf<{YJ}X0KEQjzbNyk0+;o$0T%jba>xm&AshCR?mX{D|^(gYz{^<@T{w`OR z@sU>_wlH9U$H5S5@Y}HU5$JGzs3;Wg`!)E2~K;GGMrSw4rN*r`1>XDy!M1YquIMc1)uiHiKHN&OFyViA6(1^QN zM2&Y_;A#Ii_Pc@(Kng>4fwzSA67`{EuhU_)kh|e2vD+iBq}4<(%4>>!Um%Q|Q}iir zb5V87c;R3KadvVrYI3&Up5)11i4ksYdjBrR58mOV>t5qntTzDj)7ymRdOKjRdq2ia z^Cl5$ytfi>_+BB+3n(KW4AxWTgrzy;M67dkkBoD&Mx1e)9g**JF8s42HoVaR5ME(F zE4+$5&j$TpS3MxjQGyw_KjgH^smZI;{k4Ce|CPWi;iN#X z*rk4};-`2L<77@9k_W`0QwsAv1Q4u{S2ybS)~xYzb?%{0lk;`0BR_7T}$LS?l4A zU*YD5XShDX)wu-X8=ZII`yKy>Mv?JAAwsU2Y@E%Tu+6bVj0uDTdtACux=rn6a2~G& zvbAnVjQSt`rlP@qzoOmMqAc<>snnh~RV%6Ym9=DVWjnG@c@S`3-EFw0_0<{1@7t=z z%kVfY)3rjC;gXDmU-h7s9{~+I77Qb@lw4)h*TD_-DOC|5^*GhCb-2i z@C;lY*I9Uqn=L-Yjgze7CP}_?=wfH~ckxVyLF`U@B3U?4Aa&|~B_+2NO20N0Nv<~0 zMDcB*!qYuB_*;j=dD#pWX9K5IY_j z_Zv+4d3}^nlgC@%WR|6Oa#a4k>8gnS&C=WbQ@E18J0oqq^SU#8PBkk!57gJTt^Bj7 z`Fz#4e}w9#e_1tge?<*v{>C>?`m1ge*5B{kTTAYat$x)#Qc>Bx;b&*}nsWah-q*UG zN#Ec0mNhi?oun5H(3RjJSC!ZB2zSabaB$m@S6k=6!up$i?!P77{biU=*HT+6_SO65 z$QR*FzONb^quw2Es{4#+f&Or8d-{7uhqWrZ>s0lQZg_QZw@1~MF7L{S?xz!^(^a)a z4A0heLa%{D`LWSfMKdix4jKF|zS}d0|FLsDE3!RhbYJtofiHh2^<1d0=+OOH+P3A3 zxux!fv3dCU!6w3sAAh4>e6J090j%EkBB09kMP}``l9kQQ-x_)X8|Ki4yMgSZBUAZv z$6gC&((dr=2d**hbk_IJZq92VHSDbg*6jOJQn|Xp^b6b;_hUhC&bLLw>1DDpQ<;f5 zyF7)x;@1gQ+b;#3`2$3|^gUq!_${(0x-6lS^l5jy_vhzr5382IkhEpPo>ezNU)?VdJOYhZgw|FPa5v_v+Fo}sx% zTVXEh+o*MGP32STLWiio*S6z+)ckG#9#XTR99a3_$NpbSeop)4|5N-M@Z(ACitpQ- z=6w@%O#b$)cS7SjaJYQgK-JH;{g|qq{r>g(fwHEGkw2|-n8vod{8b(KQcG8{Vs$TE z`Kpg0U)}dw+S`K_@9erPsB2%xD`>6Y9BjVGUe{E{QZ^Q|kWF7$dz%v2Zq3tJ+UEPC zsus^)Y@1Kx#`e5wx6an8!(G^a^Si(IoanbOMBH5Q3(G8x41dDxVqXjj$3fsfK&eQ% z?k2Kb!a!VQABKMzJp!FGf&iOFu)w4A&33Q2PpkszOY^`u$Xsb{u+9QILrAdC=+&@m z#7yW6N&`56QVl90{sa+l?cfYl80-hE99a&|!CnQn;>G}W*kz!6L>BA?NQ?Hj?I3Nj ze092Fqf+A`wXXH(a{E{0W5_|5OJ=Z_t2W->rk@+^1$iGop}On4Fsi`x=61FV7J6w=(F(N)o84)mbN+f#r zVC0WEqNsgyuf}xFeGs>N?!$zV!t5mZoLR}~b3P~kEqIf>zF#KT{@F{C z*37~r<}6qe$#{A~(o zxmT)W+3nQcWtg<`WjoWpF2klDT(&O#*s`oN>=Ij&ZeDNP#{BFU@yr#ms#(&c6@_k- zau=SSxpgV7=;2cQqGwA#En2sfRXl&`(W2O;(gNqD`(}Wb)=X9|Ih(~;@-FSqlBSf; zOLQqGmyD&|UZTsKw3s%js|YgrT2b7TCyRDZaaw|&GPrp0qPer; z7fmS$Ui4rNXwj89qJ?1vO$!@leO!2ZB4cHjcVyw7oTUqMvx*kJN!JzcOO2W@OI|zo zQPSJ|xrsNXS>wkh-H1Dzkr8`6eR|Bo3`ulqW@Zd7D>61Qdt;no(xZ6f)1(S^>oC5L67jDfrijR|D)iC&N4qp^E>ZWI)uFyh2`5tN&e0{*y{Sq0wV919X7&@2I@5u_IQ<{iW^xU2XN(Jp z9L|wW^d}48J@RXP?KDZ;$@>s2}0 z|Gt?$2#k0PDU2~G@uN%H)kEQ}95+|Tz z17qyrm607olS6ugaRb{1?EBLC9eUvXZ@a?#{^?})zV5Ktgi=fYi!C-Q5SI&tk%g~>HmoYkVC9`iBn{#L2O+K&hMuB<1N*-$PeHLvvF5PcD zAm!hw14-v*`SFGGj`1fJ_r;eiosC~veiH9Q`w{<}UKqch*%1$BEyO=yOXB-D#tB^R zfiWOxXPls;noXq`9ck&3Ze7_k{n~P_K|_VIQA1^&(MlE9D5s{@Xm`V2 zBYr#DNO#cP=)^>$k;TksBkt@ieTM~#I&E16cY)~$dcx@tnXP34#PxK{wY4_o4sNrK z8#~;D!BDcES}t|iGk1kDHFn4OK>r)^<8E7flioB-){wjjYWk~zbcv$BzF zN?&wsl)bb+DL>ToQR&jys%oP7N9~-Jr-oGfv}TyDvX+CMh1PYw-576k-(=qDO6I%b$+e``6OZRBeHTN~rZSp^; zb7#{f?c@GlT6cXgnmHcB>bqUD)z~h6stca(%6(f-DO}&os;y+%tN*ouEvL+>3SwhxUe&FJ&6yQ0c@X&t?$!A*wAtB@;erssG zymn-e{Nw0(95m(%ZYtUm*BQMBR~(IyPmCUxe;w_FzZyLze;~RCw>A1G);78jtsLEn zltyL4=c69LTBB}5vZIDTpQ7@B+fiD;;V6bIC`v4|k3s;dQ7JN6Z>ea$T4g z=_2_WISsiRc?xqZQbgPtNl_$6ULt8lR^T9!JqT)q9=JP#CoGC+<^GC@Wjv0ESvnn| zH@_$1^Q>Eh@2o*Y@GK@GYla>EVQM%$V|>Fhdo(%x(fI4|Lo=7c7nb&htE^DM1ze@@ zKpr?;M=%?8_R+YOR(X)mSX8P-`zKRIMsjP{kHMQV|tpDPJhwse~#yreIsLPIz8S!-W-1p{ok~ zv7EdWWw~5^Q|;^}$Kb51jzxb6rWZ5rsyt2~M>5kEBtOzFuU$zCXKqV-utZF&n9EIF zm~~6FUMNecqI#qtSjEXZSACK2z)Ov)P2a ziMgDD$8#lxu2X}BxqT-JA$81x1G)bd|9BtE=U9S4sDgu8RJkuJHkQ_dvf#uVwGZz(5CNbh=48QB>VDvsTQU-gJ)(A%C%5#4`eK<^0P+G7glwR=Je8+Slcs&>I#O7_T|&p!^& z$@zdt%C1A+&ZeUxvdu9$e_vsbWgV0s`E!l1oKZzu%g|R6{dug?oi(h6%>ilJ=P|U} z^PlPbDVWl2D1hqw7q}V(=ASbR$opcnJ2%nzW=@Prc6Ogh?_YxHM3$9lbEdUv{vS2d z^bDCvM>^QlF@1|EElps$nuaiUOh0GwG2Pq>oe^r2nZdLB{b$w@lr>7p`+LXraL!Zr z-?<1+=e%}LOrDlkP%hp}HRqS-gXTdBO&$G5K4H>9z~57$`b|En%@Q%cpp0g%#&&4N7a7R{`j zEm3JfTho$zwgw~z2L4Sc3QSJd-e#3`aoe$+mTk;DR8V<=cF^`B>b9xkfNfo+s)05Y zky~=Almk$;d;Es$jJ-$ezqrF1Y+c^f^T<7QIk(6(P} z(hTM_D~C9=E(BY)z1=zA=Dq#jc2wZ@jH~vY`pUw?mbG<+F5chZ^UuGVA5X3PqWooyK9|De{6Yu z>aY3bK6kUFZlo!92xFo)Pd2t-Z=5oV$_+0|TfKXV!@6}Od)T9bxY)~G{V)G$R#)O}E= z)DAe6nO#Kn z+EgKVPQJ*yu3`k-V;Iry(Sx9PEFrGBu@MsIK7`Dv1~F^D4XJK>3N2@yEWc)XQW0ro zt!{4}sZF+x&=uKF>(o0jv{Ibg)L*$xD8KbQMjG-N!tLMm7`415NlrD$3i5e}K0prc zk$^*zB(&f-nOCqPByi`r+_oJSs7KrTFqYd1@_Vl?;%LYUK6m#O z+@-y@&{m-*5Dj79V6G8Xkf)J2(C;Wc*_-J562F*_;+&XeaeYjV^iRwg(7Bj9P+7Dc z{7f_mSs#^v#6;ncK9OGVvk`}&ufx}Y&agPiv9L+uMA&bES;P;)mZ(%=Omw7}91W4` zN2|!-(K}?!sBhBVC`UCQ}B z+1Wd_*m-TisB3=tO4mo~Y}ZCjzdK~cyeDG>-21IZ*!!s!-v7Emao|g>-k?d1%aCie z`S4sNbR?&|W<<3#YV<&H&*+=6F<#%B{1h|;@uZ+$6Z|<`BlHP z`b&X|iMvfRjzcrN;u4tQafYl5aVOX>;`VV8dqjw{xGzyRRn1pI9r4FJ2#rH|MkB&k9fpX+r&kNs)U3TCyj>Q+hh#vg~m} zHV~Jv0xC%$LwXaQKxqjgm|WsNaP7oC1SN4FDmZZgeJt@U_FiJ7{MSSaLSEuJu`Thl z!h9k~Ns?%ytdaz%*d%4BY)P_GJ&=^HdM(LD?Ojr%T6)qA_1dKE8e>V@G*^@MYhixB z);9b-r{nqCSa09&6Z&U=ry4x|J!<&tH(*@$8)7o_d)b8jJJS@Cyvs}_dCtr``LwxR z@`(BEWEYEu^jTci^l_yPdH+X$#Pje$6R|K%Hs(A^m#0yC$z}1(yCcpY6M>N+@S61+EGf zdG2FoRvxNmRqm>0Z`@>NRF_N(taH0n7+KX;-RY$LH^)9lzGFPuoSaEvQ!*(i*J84( zJILv%XS@AV?-<+PzOz;n{&y@qHXkr6-+I*KeGt>gYG<StVqv-eGPk zo5BWFz~ORg$`LQsDUqi&gQ85d@i8xS@cTn`H|;;DtGPc*2eCg&n;!c_voH3DdTFe= zYFsQ`>1k}4!kJhwX;17ef@|z%yl$+6yj-j^juGRJ?Ty)rDUR8O{u#3a^)O}!@>LSo)PmZSZ_ozXNPKl+L6YqXX0Ui6gsX!Li{j_4SnQ#3-L7G1~# zMekogE5xIMc5s@*`7oj^|8j(Gk5D`7{EW%;< zY=q}fXvDoiuL%Btam333T*Q%q_3#e^;+1i_Lv}JStV!&$NlTDL(R6lAS!-tl4*Q+@%-u+Nsj7wu~qZ2e& zXlI%;Y!#8MY5wl-dE<$!27SjYSDjCp_cbAzc^a4gJk^@X$kYqU=rS%(KWZVLo@ISA zjb_76Ew;In>TYeD`pg28T4N$eF*FdS=xGa6tkkF}KNR~?z7Vog>~MEe7EnPcAcRhe zB8;1?03J%l%gU1d#p%f`!I$Kn{Ex{ucyY;gyryJJ9zF%hJCpK$otaX*b}sefs$$ws zZgZLv=S4c7wJT#{Md#0VCgTs5QJ0CQWoDgQdjI$7{NZe$8Ka!RiISXKqc*u0hpy(f z^?%QO(i@-qzWZ4&v-4o?%Fl{# z&dc;}&HaOD|CW){@jN}Y>tdQ(&*9X;-n%Jp`YV!+2Njb)4xRlyJ=~duA9YPKA1g`R zJ?@nlIWd=TZt`8ilPQ~o!s*<2)U0Lv&AAtGiVMxZY8DNCy;(;6IziL@b%5de>;1~U zUnT6bzu4SozwFoJf1Tr({rV*w`Bf_B|EiTL$CU$iajD=Pakrs|;*QJRjx#}gkDEq* zh<}fsOb);zvtaVD{2Kgl(G#Li$qt3$VlAcOLYnfYym{3Ff7{iyGRibnQ}VSxC&uft z<6r8p#~(K&CO8>eC#;&dBqW%9N(i(tN}jb;&-i5h?5~+EB`?SBe}$VI_LmGfzAZaN z?kGn%v&-XMpylpvdrRBhcNOpOJX|>M)t2w(GnjY9*COwWUu*7be|%o}rl+3{1MFD7<}+D&c^U7Fk%T03}8-@A=xzPFd(vPWIGcaNT^YxlB2woABf@xyY zoiwrk4wz)mb~nl4pr4Yf+bpHe181a(TkB-aTe^U*&6;3Nz+H$+00!p0DO>K8{|Uq= zKOa<$F99>>GmhnXf0l=OI}lJ_l|-DUrNXNFBgHwl?@H~i6Uuomm8$*a?5*<4$V(;BkfzdVKv3iA zpH-LYHEh)1>NHbz&S~A#R@6SKwOc1l^QK;i#vVf#^`j=LYQg4{Dx;R4lttDSO7XVe z75eSEi68ADgjRb!`6PQ+Y=r$Dw3hufq|h!E4%pAY^zC(^d+bBO5AELqU+o*EU+r1q zU-p5bANF;E4*LUqO$TM(Gl%&#f@8sIqT@@hvC|>WCnqwS>%?5KBj0C+k+m47$mO)_ z)G+HoBu|+ZpxZ;d6pUI zVw73#EdAr;tdyBg3D1n7RAm}bOtMgvYguSYMwTX}EX$EnkmW=9p5;xspGBq|%rd07 zWvNpXvv8Ei?)nsN6& zHHV(dYJR=*YN36v)F1T6YV;3m*VG$gXkHo?X*P}=)5MRNXdD@jP^+JCQn8)tQv5R= zNHUr2z<--Nivt$CG1nJ0QO!#+2n4lN&YBhobE1zyj2UOaa!fF2f|)F+2&5Z^ct{H*L1vUXf_XqK*dnlI$-=q1*ixhFiWRTI)VivC z(E4`S3mf0kZML`)1G~i{z`ne2+WvgOHwUwPZ^ypeNyj5OXPwx8;pG2ieI`RQ%_#q7 zR8#cQ!<_3sO0V+MOiT8QPCex(OVRb4NU8Ug zPd(~;CspKQl=jevpGNSRO8@B1$WZi_&wTFXmc{ox^>?f1`|Qsi1vzMsid><4TV9$+ zLH>;A-GX=CTM94w0!7jODMcCq0mTP54;M=}hnGxko+!a?jwt=QiC#M4cdtz5V^FT+ zJy8CS=j)0Y_mIjIH^r)K*NG~QOHOr|%bS`(=Zm#loe$TIQ^@rvD1-(yWuT#){JQZB z*|W) z)#%!^tgop1M(Es~{a3qgwoyxY zj=j-4tf#3rzePiC;l8@zVx`)}r8QN?vZd-zTC7SUlWqOcIAQ1c#6atC`p9Dyd4G&MqC8;O$ zh@=dv4$fYtAV5)md~9_cHb-rw=#Jo|J#ZevUuN zUdG3=SMdkgRrr1E!+0|`9ACvMme*%}m5*7;lfTLo$e(2#!w1qA@G7)JgsJ5bLgvzD z;{C-`;?V_p((d^?B&!YS35(fd3MMoC3bxZ^MbD`xieZyYiWeqU75^P4Diw}tDvgh7 zDIrFUmB=G5O815jD~%6jDg_TAl{*ISDQ_E8R%sY0Q*j=+qMFw4t%mO>sGsgzRxj)w z(~$KPYVPQX*Glhxs!i-ZuJg3ZTUVhAr5A-OxwX zxf>MLVhzvKE*W~(HXEtbrW?y@9+*gL_L{EMsG13Dy38=Om(9&<(H2p)Z!Nyn%3Chg zUbb|vtF!!3w{D57SF*ZNuW2=0uV-b@plcP-U~J{rK(;b(2(*&apR%g1|73NizRk*| z9%H>$x7)g@?uT`09nHF}&eKM|{-@2+dZEo!eYEY_h6Y>tMq9h)#ss_fP0IHFG{3f| zv>+VBEw>!9TiFf=+YUIw+S?ox+8v$zI^H^Ucg#D*cAAryJA=uWx=xd!-FL}9x}TAK zdtQ-+J#WZ=dq0y8^(BxE`pd|S{sD5+0H2&bXh!)q6hrwi{4eFjNF(LRD35Y?%+UG4 z_;%+r6NjDmPF{5On!4(2GJVAvKXcxBWhTu&!5*#yDjT{o!aQ3g(+ih>~ z0&Gt51eMvg15~EP0?5c=VR#rNxBvdL=>{n(hWU44A+*dUug{m16 z&DB*1bagboK!c9EsyUB!((1>oXjP&!wbM{%bzUP~bJ zLwSgT5eVF5v<@6KUXlSOv(jfKGZKX9qWG#QO*Cc76grsE1$WIR`D13~JX7

    ;E&q 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 literal 0 HcmV?d00001 diff --git a/linphone/share/rings/sweet.wav b/linphone/share/rings/sweet.wav new file mode 100644 index 0000000000000000000000000000000000000000..e5145486db23d6b17ef77b216962477afa9ce8be GIT binary patch literal 745158 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�%onfgi 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%0Ai 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

    OYy4`Xab1`yv-&7ZW_qt1LXM=G$&@ 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

    |{f@xw_Csg(3&%72;Hsc@QvI-eSqc_d>y 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ânf0C*FgM( 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�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�a9BsCOx8DETPK=Z=MK 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%0DN;&I<&!(+cE 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

    0GB0a6g#R_PpBhC^G6*( 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

    ?E0)MH$2CiRsFJ1OKG|mZWpjGct-YXR}gr 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 SMj@jOtq&Q<*fW&ucl|$G)WHM* literal 0 HcmV?d00001 diff --git a/linphone/share/rings/synth.wav b/linphone/share/rings/synth.wav new file mode 100644 index 0000000000000000000000000000000000000000..7142f7a510881d99f85c9ccbe53671ed68d43859 GIT binary patch literal 882732 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%0DuxI%8fG0RK8mHG-d9lukL}GP(Lt=Y!Z|d%( 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�fd-npJ=1q#r=yq-9v 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

    tmn9850vKK8~v&*Ro<# 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%0AKEL@QB$a=U8T`t4#jVXqGvw4vIp5=BvT68 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 z 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

      gnj%kB${JVnI$8`Wf!>>cn&Yh(%nZauBAMyj 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

      R(+`S~@2*GAPS9M9bFOgyg?iwSv#;|hxVN>A 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

      rgBNy&!XLV$~r{K06$ND8I=z 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

      eYeYraWNAu$` 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π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 Zn4Dse!em!72exVwRN3X-=^GZ#{|6C5*4F?4 literal 0 HcmV?d00001 diff --git a/linphone/share/rings/tapping.wav b/linphone/share/rings/tapping.wav new file mode 100644 index 0000000000000000000000000000000000000000..862fd79fbb7090e5e389ebcad72c4984694739fe GIT binary patch literal 771208 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

      H_8+`g}OXqA3!El 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%0A*5?Gp_clDe}i! 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�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%0AG%;YjoR{#w5fM)~axcd!l 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

      itUJt(ksw1%Wj_* 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 {I*;zV=E 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

      f-bZ*CA+m&#l7)&;Zfm^{>lCl_jLDEdzJk^ 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�RjUK_9!j}tqq?F?e(7W4R*2|cTF}kSKp=$C{xs0xl?w%<9-LGty5b; zOZS$;%?q2^E#Q_}t&FxHU^*Nmn+p)_vH?rq64Oj4*m~Ms9`MIThd>}9^c`|IEFZlR zXCmFhuOqLeoo9@t4P`uI{>OU6e8Ez%vD`v-5qmf14{I(mgW;9G&c`I8BEqMHB?NB__$KRx~^90FL2^8y#W0^4fK7xyODW%CGgS7(tU(|pt1 zWS{N$*E+x{ap^re@8M9ppB=WvCP1zNTeg2Aui*~Dcc49_GU^80A_9;8j$T5XLJ~3# zG7ga#qz-yLwS$1dYf1I^C?_xR@n5~Oz5|HH& z`T~(fzV=W*h#9#!ei5<~hapWs+(O@{@|m}AQ;87vZ1!=|ZPI2|2P28JiI_xxPJK%_ zj^73_&%R=(p~qmd5K%-3CV(7_t01QnmWCOAMT`-_0klC?a93cy)nMN4|I2sTBryg& z&)rK5Wd@dejhklbZpri{c=5Jmhs0M3WX`(=riY+0U9<^82J_*|P|NTjGz9OYEM_N? ztLaMwN>LX!le=GnOv3PH0)DG+N!xfLo>FpKG@Ub=$rF5L*HNdFnrLfDb8xAsRIC=( z1A0EzEq*SrH0bl(cg?cCcbu}s^m|o>2Ag`aRMzsh;;D2;6S*zEE0e*kXdL@|7@d9323w+J!;(85Nb$j+S@E|JlHI0J=s3C ztx`5zK0#BZ`NurLbj(rZqy#SbE=0P-3GfGyB=k*eA-RKaggTDCisfL;W}7)A{z9&U zrx%naKIc#5cTarEw{p`t`Mi^yg8=7iFzXks8|@FN3uzS4*vok09qIB z9Pb_ucynE~zKiai_664U&L{RE<|3oYnrvy*TlHz?kLIVwahA2#^Y%P@q08tz>Phh> z0b53Wqo9N@@af=I_#wTy|dyWO#c4#wem|o4vxcSYK*M zG5)RjN0p-6qWP?>R5qyBsvXLHs^RM0>c{Gzx_XUEKgZnSs5BexX+BK&php_$4PwIg zMggn=MnhyE^RN@BFX%LYC$^56!!D+)iM`&LupMm>&6sZCS zNDu*nSa;|Qq!@M^G&{N*yb5$DxXCMvZVc^rF0xJW=X=*!)|eN&Pr8at&kf~HgS}aw zW;kf?<482+S*xA1Ji8sK9)UkKbSaP=ONtGFEQTU6dyy+~?}$5Tx#SYsdX|8n4s z19pUcfRBVIA`2^k=XG6>z(2w&VLazxnM~SHpw3%@OU1$wTaitWIpD*w^RZWf)z5P`z?LlJgOx@mL(t5dZq1&qK~Sy1Ex@F zE*lWq9_CHf1#Z1_Y|t5Kj^%=eBiv9NW(yuh^Ad6NFl#pN0}I0Kl=w$f$6G5fN@|k& zBtjD5NonFleoqcT_?iEN$)R85uo*`38~k)qf6N8cK4>LO3K|6ZFQNiGudcvW&tb

      SZbV4z2%|P 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

      `@ua^QhE`uHZ{@UDt`?6g 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 z%0A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
      H3fQei`nJq58MF-!mq;E^A+D0%^@`Jv43Uo#rg# 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 P)R$%suC{@kQuF@*+W$S? literal 0 HcmV?d00001 diff --git a/linphone/stamp-h.in b/linphone/stamp-h.in new file mode 100644 index 000000000..9788f7023 --- /dev/null +++ b/linphone/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/linphone/support/.cvsignore b/linphone/support/.cvsignore new file mode 100644 index 000000000..6e5ca7ed4 --- /dev/null +++ b/linphone/support/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.deps +.libs +*.lo +*.la diff --git a/linphone/win32/config.h b/linphone/win32/config.h new file mode 100755 index 000000000..171a6b3a2 --- /dev/null +++ b/linphone/win32/config.h @@ -0,0 +1,7 @@ +#ifndef WIN32_CONFIG_H +#define WIN32_CONFIG_H + +#define LINPHONE_VERSION "1.3.0" +#define PACKAGE_PLUGINS_DIR "/" + +#endif diff --git a/linphone/win32/liblinphone.dev b/linphone/win32/liblinphone.dev new file mode 100755 index 000000000..743c965fc --- /dev/null +++ b/linphone/win32/liblinphone.dev @@ -0,0 +1,242 @@ +[Project] +FileName=liblinphone.dev +Name=liblinphone +UnitCount=18 +Type=2 +Ver=3 +IsCpp=1 +Folders= +CommandLine= +CompilerSettings=0000000000100000000000 +PchHead=-1 +PchSource=-1 +ProfilesCount=1 +ProfileIndex=0 + +[Unit1] +FileName=..\coreapi\sdphandler.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\coreapi\authentication.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\coreapi\chat.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\coreapi\enum.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\coreapi\enum.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\coreapi\exevents.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\coreapi\exevents.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\coreapi\friend.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\coreapi\linphonecore.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\coreapi\linphonecore.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\coreapi\lpconfig.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\coreapi\lpconfig.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\coreapi\misc.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\coreapi\presence.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\coreapi\private.h +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\coreapi\proxy.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\coreapi\sdphandler.c +CompileCpp=0 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\coreapi\general_state.c +CompileCpp=1 +Folder=liblinphone +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNrOnRebuild=0 +AutoIncBuildNrOnCompile=0 + +[Profile1] +ProfileName=Default Profile +Type=2 +ObjFiles= +Includes=../oRTP/include;../mediastreamer2/include;../../linphone-deps/include +Libs=../oRTP/build/win32native;../mediastreamer2/build/win32native;../../linphone-deps/lib +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=-Wall -Werror_@@_-D_WIN32_WINNT=0x501_@@_-D_WORKAROUND_MINGW32_BUGS_@@_-DINET6_@@_-DORTP_INET6_@@_-DORTP_STATIC_@@_-DVIDEO_ENABLED_@@_-ggdb_@@_-DOSIP_MT_@@_ +CppCompiler= +Linker= +PreprocDefines= +CompilerSettings=0000000000100000000000 +Icon= +ExeOutput=..\win32 +ObjectOutput=Default Profile +OverrideOutput=0 +OverrideOutputName=liblinphone.lib +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +compilerType=0 + diff --git a/linphone/win32acm/CODECS b/linphone/win32acm/CODECS new file mode 100644 index 000000000..87496f17e --- /dev/null +++ b/linphone/win32acm/CODECS @@ -0,0 +1,59 @@ +USING OTHER CODECS + +To use the library with other ACM-supported codecs besides +TrueSpeech, the following things are required: + + 1. DLL file supporting the codec + 2. correct format tag for the codec + 3. correct WAVEFORMATEX structure for the codec + +For codecs which are supported by mplayer, the easiest +way to get items 1 and 2 is by looking at the audio codec +section of mplayer's codec status table: + http://mplayerhq.hu/DOCS/codecs-status.html +If mplayer says it is using a .acm file to support the +audio codec, then most likely it can be used with this +library. If mplayer is using another method to support +that codec, you should probably consider using that +same method in your Linux program instead of this library, +because it is most likely a native way of supporting the +codec. Using a native codec should allow greater portability +of your code to other architectures besides x86 +and does not require your users to have Windows DLLs available. + +Determining item 3, the correct WAVEFORMATEX structure +for the codec, is the hardest part. If your code is +simply playing files encoded by the codec this is easy. +Your code must register the mapping between format tags +and DLL filenames (items 1 and 2 above) by making repeated +calls to MSACM_RegisterDriver(). Note that you will +often have to call MSACM_RegisterDriver() twice for each +codec, once to register it for the codec's format tag for +decoding, and once to register it with the PCM format tag +for encoding. Then to play a file you read the .wav header +from the beginning of the file and use that to create a +WAVEFORMATEX structure which you pass to the acmStreamOpen() +function. From there on out everything can be the same +as the example program. + +On the other hand, if your user is choosing the codec to +use for some encoding tasks, you do not have a .wav header +to read. The easiest thing to do in this case is probably +to create a .wav file in the desired format under Windows using +the Windows sound recorder. Then examine this file with +a hex editor and determine the appropriate values of the +fields to use in the WAVEFORMATEX structure. Note that +most codecs use extra fields beyond the basic WAVEFORMATEX +structure. test_truespeech.c shows how to create an extended +length WAVEFORMATEX and how to initialize the extra parts +for the TrueSpeech codec. A thorough writeup of the .wav +format headers is at + http://www.borg.com/~jglatt/tech/wave.htm + + +Most codecs will support 16-bit signed linear PCM, but probably +do not support a direct conversion to another proprietary +codec. To convert from one proprietary codec format to +another, typically a conversion to an intermediate 16-bit PCM +form is required. + diff --git a/linphone/win32acm/CREDITS b/linphone/win32acm/CREDITS new file mode 100644 index 000000000..0343fa20c --- /dev/null +++ b/linphone/win32acm/CREDITS @@ -0,0 +1,34 @@ + +This code was extracted from the mplayer +project (http://mplayerhq.hu) and slimmed down to support +only audio codecs. Apparently the mplayer project extracted +it from the Wine project (http://winehq.org). + + +The difficult work to load and use the Windows DLLs and emulate the +Windows ACM interface was done by (at a minimum) the following +individuals from the mplayer and Wine projects +as found in the current body of source code: + +Eugene Kuznetsov (divx@euro.ru) - WIN32 binary loader interface + shamelessly stolen from Wine +Bertho A. Stultiens - Elf-dll loader functions +Felix Buenemann - CPU detection +Alexandre Julliard - modules, pe_resource, lots of wine code +Eric Youndale - pe_image +Erik Bos - pe_image +Martin von Loewis - pe_image, pe_resource +Marcus Meissner - pe_image +Thomas Sandford - pe_resource +Robert J. Amstadt - pe_resource + + +The extraction from mplayer, slimming down, and use for encoding +TrueSpeech was done by the following individuals: + +Robert W. Brewer - test_truespeech.c, win32codec.c, + slimming, and documentation + +Piotr P. Karwasz - initial extraction from + mplayer code and example + loading of TrueSpeech dll diff --git a/linphone/win32acm/Makefile b/linphone/win32acm/Makefile new file mode 100644 index 000000000..5bbf7ee0c --- /dev/null +++ b/linphone/win32acm/Makefile @@ -0,0 +1,55 @@ + +# Generated automatically from Makefile.in by configure. +DEFINES=-DMPLAYER -D__WINE__ -Ddbg_printf=__vprintf \ + -DTRACE=__vprintf # -DDETAILED_OUT + +LIB = libwin32acm.a + +LIB_OBJECTS= ldt_keeper.o pe_image.o module.o \ +ext.o win32.o driver.o pe_resource.o \ +resource.o registry.o elfdll.o afl.o wrapper.o \ +cpudetect.o mp_msg.o win32codec.o + +# gcc-3.0 produces buggy code for acmStreamOpen() with +# "-O3 -fomit-frame-pointer" or "-O2 -fomit-frame-pointer +# -finline-functions -frename-registers" (code is OK with sole -O2), +# the bad code accesses parameters via %ebp without setting up a +# propper %ebp first! +# -fno-omit-frame-pointer works around this gcc-3.0 bug. gcc-2.95.2 is OK. +# Note: -D_FILE_OFFSET_BITS=32 is required to disable using mmap64(), +# as it's broken in glibc 2.1.2 (bad header) and 2.1.3 (bad code) +# put in $(OPT_FLAGS) for super speed +WARN_FLAGS = -Wall +CFLAGS=-I. -U_FILE_OFFSET_BITS -D_REENTRANT $(EXTRA_INC) $(WARN_FLAGS) -fno-omit-frame-pointer -g3 +#CFLAGS=-I. -I.. -O $(WARN_FLAGS) -g #-fno-omit-frame-pointer + +all: test_truespeech + +test_truespeech: test_truespeech.o $(LIB) + gcc -Wall -o test_truespeech test_truespeech.o $(LIB) \ + -lm -lpthread + +clean: + -rm -f test_truespeech *.o $(LIB) + +install: + +distdir: + +dist: + +distclean: clean +maintainer-clean: clean + +.c.o: $@ + $(CC) $(CFLAGS) $(DEFINES) -c $< + +$(LIB): $(LIB_OBJECTS) stubs.s + $(CC) -c ./stubs.s -o stubs.o +ifeq ($(TARGET_OS),OpenBSD) + ./loader_objfix.sh +endif + $(AR) -r $(LIB) $(LIB_OBJECTS) stubs.o + +dep: + echo "dependency not required/supported" diff --git a/linphone/win32acm/README b/linphone/win32acm/README new file mode 100644 index 000000000..268c2784f --- /dev/null +++ b/linphone/win32acm/README @@ -0,0 +1,128 @@ +Windows ACM (Audio Compression Manager) DLL library + + +PURPOSE + +This directory contains support for loading and using Windows ACM +(Audio Compression Manager) codecs from the native Windows DLL files. +Its purpose is to allow Linux programs running on the x86 architecture +to use proprietary Windows audio codecs. This enables Linux +users to interoperate with Windows users without +reverse engineering the codec completely from scratch. +For example, it should be straightforward to write a Linux +program based on this library to allow TrueSpeech encoded +.wav files to be exchanged with Windows users. Indeed, the provided +test program comes close to doing that, but for coding simplicity +it does not use .wav headers. + + +ACKNOWLEDGMENTS + +This code was extracted from the mplayer project (http://mplayerhq.hu), +which apparently extracted it from the Wine project (http://winehq.org). +It was slimmed down to support only the ACM audio codecs and not +video codecs. See the CREDITS file for details. + + +REQUIREMENTS + +To use the included TrueSpeech test program, the following Windows +DLLs are required: + + tsd32.dll + tssoft32.acm + +Other codecs may require other DLL files. A good source of +DLL files is the w32codecs archive, available at + http://mplayerhq.hu/MPlayer/releases/codecs/win32codecs.tar.bz2 +Debian users can install it using "apt-get install w32codecs". +Unfortunately, version 0.9 of w32codecs does not contain tsd32.dll. +You may need to obtain it via other means, such as copying it from +your Windows installation. + + +INSTALLATION + +The code is a library to be used in a larger program. To compile +it separately: + + vi config.h # edit as needed + vi Makefile # edit as needed + make + +This will build the output files libwin32acm.a and test_truespeech. + + +USAGE + +test_truespeech.c contains an example program to demonstrate use of +the ACM under Windows and to test the library with the TrueSpeech +codec. More documentation about using the ACM library functions +under Windows can be found at http://microsoft.com, specifically +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/audcomp_3kc2.asp +Or search for ACM on Microsoft's site. + +test_truespeech exercises the TrueSpeech +codec. It will read the file pcmin.raw in the current directory +and encode it via the TrueSpeech codec and write the result +to truespeechout.raw. It will then decode truespeechout.raw and +and produce the file pcmout.raw. Because TrueSpeech is a lossy +codec, the file pcmin.raw is not byte-for-byte identical to pcmout.raw, +however they should sound very similar. + +The files pcmin.raw and pcmout.raw can be played with the sox +utility "play" under Linux as follows. The options are +required because there is no header information in the file to inform +the player what format the file is in: + + play -f s -r 8000 -c 1 -s w pcmout.raw + +An example pcmin.raw file is included. +The format of the pcmin.raw file is PCM (pulse code modulation) +with 16-bit signed linear samples, mono (1 channel), at 8 KHz sampling rate. +It is basically a .wav file with the WAV headers removed, and can +be generated via the sox utility under Linux using options similar +to the "play" line above (specify a conversion +to .raw format). truespeechout.raw is a raw TrueSpeech file and +is approximately 1/15 the size of the input file. It is normally +not playable directly under Linux, although mplayer and some other +players which load the TrueSpeech DLL like this library does can +convert it to PCM on the fly for playing. + +If you would like to use the library with other ACM codecs besides +TrueSpeech, read the file CODECS for more information. + +win32codec.h and win32codec.c contain a simple wrapper around the +ACM codec functions to aid their use in Linphone. They can be +considered as another example. + + +TIPS FOR DEVELOPERS + +As shown in test_truespeech.c, the same input and output buffers +can be used for each block of data to convert without calling +acmStreamPrepareHeader() and acmStreamUnprepareHeader() over and +over. But if your application is using a different buffer for +each block of data, it is quite allowable to prepare and unprepare +the buffers each time a new block of data is converted. This is +what mplayer does, and it is also done in win32codec.c. Microsoft's +documentation about the ACM API is good, but the test_truespeech.c +example should be quite helpful. + +Microsoft's documentation does not clearly mention +that often a codec used in encoding mode requires +ACM_STREAMOPENF_NONREALTIME to be passed to +acmStreamOpen() or it will fail to open. This +parameter indicates that realtime operation is not required. +In the case of TrueSpeech, although the codec can operate perfectly +well in realtime on a modern PC, it appears the designers were conservative +and acmStreamOpen() will fail if realtime operation is requested. + +When converting from one proprietary codec format to another, +often 16-bit signed linear PCM must be used as an intermediate codec +step. Most codecs will support 16-bit signed linear PCM at a minimum +in addition to their own format. See CODECS for details on +using the library with ACM codecs besides TrueSpeech. + + Robert W. Brewer + 2003-05-31 \ No newline at end of file diff --git a/linphone/win32acm/TODO b/linphone/win32acm/TODO new file mode 100644 index 000000000..deb6f7598 --- /dev/null +++ b/linphone/win32acm/TODO @@ -0,0 +1,29 @@ + +use ./configure script to determine appropriate settings in config.h +and Makefile. + +fix segfault when closing acmStreams. Looks like it could +have something to do with using 2 streams at the same time +and then deallocating them. Appears that acmStreamClose() +attempting to close the driver when it is done is the wrong +thing. Maybe need reference counting of the driver so that +subsequent acmStreamOpen() calls just increment a refcount, +acmStreamClose() decrements it and when it reaches 0 it +closes the driver. Maybe make a simple test program to +open two acmStreams and then close them and see what happens. +Could run it under etrace for extra understanding. For +now the code in win32codec_destroy is commented out so +codecs are not properly destroyed. We can probably live with +a memory leak like that for a while. + +test with other audio codecs besides TrueSpeech. + + + +***** DONE ****** + +document the general procedure needed to get a new codec +working with the library. + +finish CREDITS file + diff --git a/linphone/win32acm/afl.c b/linphone/win32acm/afl.c new file mode 100644 index 000000000..d1024b1a5 --- /dev/null +++ b/linphone/win32acm/afl.c @@ -0,0 +1,753 @@ +/************************************************************************** + + + This file will contain an interface to ACM drivers. + Its content will be based mainly on wine/dlls/msacm32 + actually, for audio decompression only the following functions + are needed: + + acmStreamOpen ( takes formats of src and dest, returns stream handle ) + acmStreamPrepareHeader ( takes stream handler and info on data ) + acmStreamConvert ( the same as PrepareHeader ) + acmStreamUnprepareHeader + acmStreamClose + acmStreamSize + maybe acmStreamReset + + In future I'll also add functions for format enumeration, + but not right now. + + +***************************************************************************/ +#include "config.h" + +#include "wine/winbase.h" +#include "wine/windef.h" +#include "wine/winuser.h" +#include "wine/vfw.h" +#include "wine/winestring.h" +#include "wine/driver.h" +#include "wine/winerror.h" +#include "wine/msacm.h" +#include "wine/msacmdrv.h" +#include "wineacm.h" +#include "ext.h" +#include "driver.h" + +#include +#include +#include +#pragma pack(1) +#define OpenDriverA DrvOpen +#define CloseDriver DrvClose + +static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has) +{ + return (PWINE_ACMSTREAM)has; +} + +/*********************************************************************** + * acmDriverAddA (MSACM32.2) + */ +MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) +{ + if (!phadid) + return MMSYSERR_INVALPARAM; + + /* Check if any unknown flags */ + if (fdwAdd & + ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| + ACM_DRIVERADDF_GLOBAL)) + return MMSYSERR_INVALFLAG; + + /* Check if any incompatible flags */ + if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && + (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) + return MMSYSERR_INVALFLAG; + + /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a + * LoadDriver on it, to be sure we can call SendDriverMessage on the + * hDrvr handle. + */ + *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule); + + /* FIXME: lParam, dwPriority and fdwAdd ignored */ + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverClose (MSACM32.4) + */ +MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose) +{ + PWINE_ACMDRIVER p; + PWINE_ACMDRIVER* tp; + + if (fdwClose) + return MMSYSERR_INVALFLAG; + + p = MSACM_GetDriver(had); + if (!p) + return MMSYSERR_INVALHANDLE; + + for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) { + if (*tp == p) { + *tp = (*tp)->pNextACMDriver; + break; + } + } + + if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList) + CloseDriver(p->hDrvr); + + HeapFree(MSACM_hHeap, 0, p); + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverEnum (MSACM32.7) + */ +MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum) +{ + PWINE_ACMDRIVERID p; + DWORD fdwSupport; + + if (!fnCallback) { + return MMSYSERR_INVALPARAM; + } + + if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) { + return MMSYSERR_INVALFLAG; + } + + for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) { + fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; + if (!p->bEnabled) { + if (fdwEnum & ACM_DRIVERENUMF_DISABLED) + fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; + else + continue; + } + (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport); + } + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverID (MSACM32.8) + */ +MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID) +{ + PWINE_ACMOBJ pao; + + pao = MSACM_GetObj(hao); + if (!pao) + return MMSYSERR_INVALHANDLE; + + if (!phadid) + return MMSYSERR_INVALPARAM; + + if (fdwDriverID) + return MMSYSERR_INVALFLAG; + + *phadid = (HACMDRIVERID) pao->pACMDriverID; + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverMessage (MSACM32.9) + * FIXME + * Not implemented + */ +LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2) +{ + PWINE_ACMDRIVER pad = MSACM_GetDriver(had); + if (!pad) + return MMSYSERR_INVALPARAM; + + /* FIXME: Check if uMsg legal */ + + if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2)) + return MMSYSERR_NOTSUPPORTED; + + return MMSYSERR_NOERROR; +} + + +/*********************************************************************** + * acmDriverOpen (MSACM32.10) + */ +MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) +{ + PWINE_ACMDRIVERID padid; + PWINE_ACMDRIVER pad; + ICOPEN icopen; + HDRVR hdrv; + + + TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen); + + if (!phad) + return MMSYSERR_INVALPARAM; + + padid = MSACM_GetDriverID(hadid); + if (!padid) + return MMSYSERR_INVALHANDLE; + + if (fdwOpen) + return MMSYSERR_INVALFLAG; + + pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER)); + if (!pad) + return MMSYSERR_NOMEM; + + pad->obj.pACMDriverID = padid; + icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c'); + icopen.fccHandler = (long)padid->pszFileName; + icopen.dwSize = sizeof(ICOPEN); + icopen.dwFlags = 0; + + icopen.pV1Reserved = padid->pszFileName; + if (!padid->hInstModule) + pad->hDrvr = OpenDriverA((long)&icopen); + else + pad->hDrvr = padid->hInstModule; + + if (!pad->hDrvr) { + HeapFree(MSACM_hHeap, 0, pad); + return MMSYSERR_ERROR; + } + + pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc"); + + /* insert new pad at beg of list */ + pad->pNextACMDriver = padid->pACMDriverList; + padid->pACMDriverList = pad; + + /* FIXME: Create a WINE_ACMDRIVER32 */ + *phad = (HACMDRIVER)pad; + + return MMSYSERR_NOERROR; +} + +/*********************************************************************** + * acmDriverRemove (MSACM32.12) + */ +MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove) +{ + PWINE_ACMDRIVERID padid; + + padid = MSACM_GetDriverID(hadid); + if (!padid) + return MMSYSERR_INVALHANDLE; + + if (fdwRemove) + return MMSYSERR_INVALFLAG; + + MSACM_UnregisterDriver(padid); + + return MMSYSERR_NOERROR; +} + + + +/**********************************************************************/ + +HANDLE MSACM_hHeap = (HANDLE) NULL; +PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; +PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL; + +/*********************************************************************** + * MSACM_RegisterDriver32() + */ +PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName, + WORD wFormatTag, + HINSTANCE hinstModule) +{ + PWINE_ACMDRIVERID padid; + + TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule); + + padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID)); + padid->pszFileName = (char*)malloc(strlen(pszFileName)+1); + strcpy(padid->pszFileName, pszFileName); +// 1~strdup(pszDriverAlias); + padid->wFormatTag = wFormatTag; + padid->hInstModule = hinstModule; + padid->bEnabled = TRUE; + padid->pACMDriverList = NULL; + padid->pNextACMDriverID = NULL; + padid->pPrevACMDriverID = MSACM_pLastACMDriverID; + if (MSACM_pLastACMDriverID) + MSACM_pLastACMDriverID->pNextACMDriverID = padid; + MSACM_pLastACMDriverID = padid; + if (!MSACM_pFirstACMDriverID) + MSACM_pFirstACMDriverID = padid; + + return padid; +} + + +/*********************************************************************** + * MSACM_UnregisterDriver32() + */ +PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) +{ + PWINE_ACMDRIVERID pNextACMDriverID; + + while (p->pACMDriverList) + acmDriverClose((HACMDRIVER) p->pACMDriverList, 0); + + if (p->pszFileName) + free(p->pszFileName); + + if (p == MSACM_pFirstACMDriverID) + MSACM_pFirstACMDriverID = p->pNextACMDriverID; + if (p == MSACM_pLastACMDriverID) + MSACM_pLastACMDriverID = p->pPrevACMDriverID; + + if (p->pPrevACMDriverID) + p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID; + if (p->pNextACMDriverID) + p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID; + + pNextACMDriverID = p->pNextACMDriverID; + + HeapFree(MSACM_hHeap, 0, p); + + return pNextACMDriverID; +} + +/*********************************************************************** + * MSACM_UnregisterAllDrivers32() + * FIXME + * Where should this function be called? + */ +void MSACM_UnregisterAllDrivers(void) +{ + PWINE_ACMDRIVERID p; + + for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p)); +} + +/*********************************************************************** + * MSACM_GetDriverID32() + */ +PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID) +{ + return (PWINE_ACMDRIVERID)hDriverID; +} + +/*********************************************************************** + * MSACM_GetDriver32() + */ +PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver) +{ + return (PWINE_ACMDRIVER)hDriver; +} + +/*********************************************************************** + * MSACM_GetObj32() + */ +PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj) +{ + return (PWINE_ACMOBJ)hObj; +} + + + +/*********************************************************************** + * acmStreamOpen (MSACM32.40) + */ +MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, + PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen) +{ + PWINE_ACMSTREAM was; + PWINE_ACMDRIVER wad; + MMRESULT ret; + int wfxSrcSize; + int wfxDstSize; + + TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n", + phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); + + TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", + pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, + pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize); + + TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", + pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, + pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize); + +#define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize)) + wfxSrcSize = SIZEOF_WFX(pwfxSrc); + wfxDstSize = SIZEOF_WFX(pwfxDst); +#undef SIZEOF_WFX + + was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0)); + if (was == NULL) + return MMSYSERR_NOMEM; + was->drvInst.cbStruct = sizeof(was->drvInst); + was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was)); + memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize); + // LHACM is checking for 0x1 + // but if this will not help + // was->drvInst.pwfxSrc->wFormatTag = 1; + was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize); + memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize); + if (pwfltr) { + was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize); + memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER)); + } else { + was->drvInst.pwfltr = NULL; + } + was->drvInst.dwCallback = dwCallback; + was->drvInst.dwInstance = dwInstance; + was->drvInst.fdwOpen = fdwOpen; + was->drvInst.fdwDriver = 0L; + was->drvInst.dwDriver = 0L; + was->drvInst.has = (HACMSTREAM)was; + + if (had) { + if (!(wad = MSACM_GetDriver(had))) { + ret = MMSYSERR_INVALPARAM; + goto errCleanUp; + } + + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = 0; /* not to close it in acmStreamClose */ + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + if (ret != MMSYSERR_NOERROR) + goto errCleanUp; + } else { + PWINE_ACMDRIVERID wadi; + short drv_tag; + ret = ACMERR_NOTPOSSIBLE; +/* if(pwfxSrc->wFormatTag==1)//compression + drv_tag=pwfxDst->wFormatTag; + else + if(pwfxDst->wFormatTag==1)//decompression + drv_tag=pwfxSrc->wFormatTag; + else + goto errCleanUp; + + ret=acmDriverOpen2(drv_tag); + if (ret == MMSYSERR_NOERROR) { + if ((wad = MSACM_GetDriver(had)) != 0) { + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = had; + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + if (ret == MMSYSERR_NOERROR) { + if (fdwOpen & ACM_STREAMOPENF_QUERY) { + acmDriverClose(had, 0L); + } + break; + } + } + acmDriverClose(had, 0L);*/ + //if(MSACM_pFirstACMDriverID==NULL) + // MSACM_RegisterAllDrivers(); + + for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) + { + /* Check Format */ + if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue; + + ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L); + if (ret == MMSYSERR_NOERROR) { + if ((wad = MSACM_GetDriver(had)) != 0) { + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = had; + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + //lhacm - crash printf("RETOPEN %d\n", ret); + //ret = 0; + if (ret == MMSYSERR_NOERROR) { + if (fdwOpen & ACM_STREAMOPENF_QUERY) { + acmDriverClose(had, 0L); + } + break; + } + } + // no match, close this acm driver and try next one + acmDriverClose(had, 0L); + } + } + if (ret != MMSYSERR_NOERROR) { + ret = ACMERR_NOTPOSSIBLE; + goto errCleanUp; + } + } + ret = MMSYSERR_NOERROR; + if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { + if (phas) + *phas = (HACMSTREAM)was; + TRACE("=> (%d)\n", ret); + CodecAlloc(); + return ret; + } +errCleanUp: + if (phas) + *phas = (HACMSTREAM)0; + HeapFree(MSACM_hHeap, 0, was); + TRACE("=> (%d)\n", ret); + return ret; +} + + +MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose) +{ + PWINE_ACMSTREAM was; + MMRESULT ret; + + TRACE("(0x%08x, %ld)\n", has, fdwClose); + + if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0); + if (ret == MMSYSERR_NOERROR) { + if (was->hAcmDriver) + acmDriverClose(was->hAcmDriver, 0L); + HeapFree(MSACM_hHeap, 0, was); + CodecRelease(); + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamConvert (MSACM32.38) + */ +MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwConvert) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + + if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) + return ACMERR_UNPREPARED; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + /* check that pointers have not been modified */ + if (padsh->pbPreparedSrc != padsh->pbSrc || + padsh->cbPreparedSrcLength < padsh->cbSrcLength || + padsh->pbPreparedDst != padsh->pbDst || + padsh->cbPreparedDstLength < padsh->cbDstLength) { + return MMSYSERR_INVALPARAM; + } + + padsh->fdwConvert = fdwConvert; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR) { + padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; + } + TRACE("=> (%d)\n", ret); + return ret; +} + + +/*********************************************************************** + * acmStreamPrepareHeader (MSACM32.41) + */ +MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwPrepare) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + if (fdwPrepare) + ret = MMSYSERR_INVALFLAG; + + if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE) + return MMSYSERR_NOERROR; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + padsh->fdwConvert = fdwPrepare; + padsh->padshNext = NULL; + padsh->fdwDriver = padsh->dwDriver = 0L; + + padsh->fdwPrepared = 0; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = 0; + padsh->cbPreparedSrcLength = 0; + padsh->pbPreparedDst = 0; + padsh->cbPreparedDstLength = 0; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { + ret = MMSYSERR_NOERROR; + padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE); + padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED; + padsh->fdwPrepared = padsh->fdwStatus; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = padsh->pbSrc; + padsh->cbPreparedSrcLength = padsh->cbSrcLength; + padsh->pbPreparedDst = padsh->pbDst; + padsh->cbPreparedDstLength = padsh->cbDstLength; + } else { + padsh->fdwPrepared = 0; + padsh->dwPrepared = 0; + padsh->pbPreparedSrc = 0; + padsh->cbPreparedSrcLength = 0; + padsh->pbPreparedDst = 0; + padsh->cbPreparedDstLength = 0; + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamReset (MSACM32.42) + */ +MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + + TRACE("(0x%08x, %ld)\n", has, fdwReset); + + if (fdwReset) { + ret = MMSYSERR_INVALFLAG; + } else if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) { + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0); + } + TRACE("=> (%d)\n", ret); + return ret; +} + +/*********************************************************************** + * acmStreamSize (MSACM32.43) + */ +MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, + LPDWORD pdwOutputBytes, DWORD fdwSize) +{ + PWINE_ACMSTREAM was; + ACMDRVSTREAMSIZE adss; + MMRESULT ret; + + TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize); + + if ((was = ACM_GetStream(has)) == NULL) { + return MMSYSERR_INVALHANDLE; + } + if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) { + return MMSYSERR_INVALFLAG; + } + + *pdwOutputBytes = 0L; + + switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { + case ACM_STREAMSIZEF_DESTINATION: + adss.cbDstLength = cbInput; + adss.cbSrcLength = 0; + break; + case ACM_STREAMSIZEF_SOURCE: + adss.cbSrcLength = cbInput; + adss.cbDstLength = 0; + break; + default: + return MMSYSERR_INVALFLAG; + } + + adss.cbStruct = sizeof(adss); + adss.fdwSize = fdwSize; + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, + (DWORD)&was->drvInst, (DWORD)&adss); + if (ret == MMSYSERR_NOERROR) { + switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { + case ACM_STREAMSIZEF_DESTINATION: + *pdwOutputBytes = adss.cbSrcLength; + break; + case ACM_STREAMSIZEF_SOURCE: + *pdwOutputBytes = adss.cbDstLength; + break; + } + } + TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes); + return ret; +} + +/*********************************************************************** + * acmStreamUnprepareHeader (MSACM32.44) + */ +MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, + DWORD fdwUnprepare) +{ + PWINE_ACMSTREAM was; + MMRESULT ret = MMSYSERR_NOERROR; + PACMDRVSTREAMHEADER padsh; + + TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare); + + if ((was = ACM_GetStream(has)) == NULL) + return MMSYSERR_INVALHANDLE; + if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) + return MMSYSERR_INVALPARAM; + + if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) + return ACMERR_UNPREPARED; + + /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same + * size. some fields are private to msacm internals, and are exposed + * in ACMSTREAMHEADER in the dwReservedDriver array + */ + padsh = (PACMDRVSTREAMHEADER)pash; + + /* check that pointers have not been modified */ + if (padsh->pbPreparedSrc != padsh->pbSrc || + padsh->cbPreparedSrcLength < padsh->cbSrcLength || + padsh->pbPreparedDst != padsh->pbDst || + padsh->cbPreparedDstLength < padsh->cbDstLength) { + return MMSYSERR_INVALPARAM; + } + + padsh->fdwConvert = fdwUnprepare; + + ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh); + if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { + ret = MMSYSERR_NOERROR; + padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED); + } + TRACE("=> (%d)\n", ret); + return ret; +} diff --git a/linphone/win32acm/com.h b/linphone/win32acm/com.h new file mode 100644 index 000000000..39cbdcb49 --- /dev/null +++ b/linphone/win32acm/com.h @@ -0,0 +1,84 @@ +#ifndef AVIFILE_COM_H +#define AVIFILE_COM_H + +#ifdef HAVE_CONFIG_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#else +#include +#endif + +/** + * Internal functions and structures for COM emulation code. + */ + +#ifndef WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +void* CoTaskMemAlloc(unsigned long cb); +void CoTaskMemFree(void* cb); + +#ifndef GUID_TYPE +#define GUID_TYPE +typedef struct +{ + uint32_t f1; + uint16_t f2; + uint16_t f3; + uint8_t f4[8]; +} GUID; +#endif + +extern const GUID IID_IUnknown; +extern const GUID IID_IClassFactory; + +typedef long (*GETCLASSOBJECT) (GUID* clsid, const GUID* iid, void** ppv); +int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs); +int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs); + +#ifndef STDCALL +#define STDCALL __attribute__((__stdcall__)) +#endif + +struct IUnknown; +struct IClassFactory; +struct IUnknown_vt +{ + long STDCALL (*QueryInterface)(struct IUnknown* _this, const GUID* iid, void** ppv); + long STDCALL (*AddRef)(struct IUnknown* _this) ; + long STDCALL (*Release)(struct IUnknown* _this) ; +} ; + +typedef struct IUnknown +{ + struct IUnknown_vt* vt; +} IUnknown; + +struct IClassFactory_vt +{ + long STDCALL (*QueryInterface)(struct IUnknown* _this, const GUID* iid, void** ppv); + long STDCALL (*AddRef)(struct IUnknown* _this) ; + long STDCALL (*Release)(struct IUnknown* _this) ; + long STDCALL (*CreateInstance)(struct IClassFactory* _this, struct IUnknown* pUnkOuter, const GUID* riid, void** ppvObject); +}; + +struct IClassFactory +{ + struct IClassFactory_vt* vt; +}; + +long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, + long dwClsContext, const GUID* riid, void** ppv); + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* WIN32 */ + +#endif /* AVIFILE_COM_H */ diff --git a/linphone/win32acm/config.h b/linphone/win32acm/config.h new file mode 100644 index 000000000..a62e43548 --- /dev/null +++ b/linphone/win32acm/config.h @@ -0,0 +1,51 @@ +/* configuration options for the win32 ACM loader library. + * Please edit these to correspond to what your setup requires. + * So far it has only been tested on x86 Debian Linux (Sid). + * If you discover you need to make changes, refer to config.h.bak + * which is the original bloated version of this file which may + * offer some hints. We are trying to slim this code down as much as + * possible which is why that file is deprecated. + */ + +/* Define this if your system has the "malloc.h" header file */ +#define HAVE_MALLOC_H 1 + + +/* Define this if you have the elf dynamic linker -ldl library */ +#define HAVE_LIBDL 1 + + +/* Define this if your system has the "sys/mman.h" header file */ +#define HAVE_SYS_MMAN_H 1 + +/* Define this if your system has vsscanf */ +#define HAVE_VSSCANF 1 + +/* Define this if you have the kstat kernel statistics library */ +#undef HAVE_LIBKSTAT + +/* nanosleep support */ +#define HAVE_NANOSLEEP 1 + +/* Win32 DLL support */ +#define WIN32_PATH "/usr/local/lib/win32" + +/* enables / disables QTX codecs */ +#define USE_QTX_CODECS 1 + + +/* Extension defines */ +#define ARCH_X86 1 + +#define HAVE_3DNOW 1 // only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.) +#define HAVE_3DNOWEX 1 // only define if you have 3DNOWEX (AMD Athlon, etc.) +#define HAVE_MMX 1 // only define if you have MMX (newer x86 chips, not P54C/PPro) +#define HAVE_MMX2 1 // only define if you have MMX2 (Athlon/PIII/4/CelII) +#define HAVE_SSE 1 // only define if you have SSE (Intel Pentium III/4 or Celeron II) +#undef HAVE_SSE2 // only define if you have SSE2 (Intel Pentium 4) +#undef HAVE_ALTIVEC // only define if you have Altivec (G4) + +#ifdef HAVE_MMX +#define USE_MMX_IDCT 1 +#endif + diff --git a/linphone/win32acm/config.h.bak b/linphone/win32acm/config.h.bak new file mode 100644 index 000000000..96d95b981 --- /dev/null +++ b/linphone/win32acm/config.h.bak @@ -0,0 +1,465 @@ +/* -------- This file has been automatically generated by configure --------- + Note: Any changes in it will be lost when you run configure again. */ + +/* use GNU internationalization */ +#define USE_I18N 1 + +/* use setlocale() function */ +#define USE_SETLOCALE 1 + +/* Runtime CPU detection */ +#undef RUNTIME_CPUDETECT + +/* Dynamic a/v plugins */ +#undef DYNAMIC_PLUGINS + +/* "restrict" keyword */ +#define restrict __restrict + +#define PREFIX "/usr/local" + +/* define this to use simple idct with patched libavcodec */ +#define SIMPLE_IDCT 1 + +#define USE_OSD 1 +#define USE_SUB 1 + +/* enable/disable SIGHANDLER */ +#define ENABLE_SIGHANDLER 1 + +/* Toggles debugging informations */ +#undef MP_DEBUG + +/* Indicates that Ogle's libdvdread is available for DVD playback */ +#define USE_DVDREAD 1 + +/* Indicates that dvdread is from libmpdvdkit */ +#define USE_MPDVDKIT 2 + +/* Additional options for libmpdvdkit*/ +#undef DVD_STRUCT_IN_DVD_H +#define DVD_STRUCT_IN_LINUX_CDROM_H 1 +#undef DVD_STRUCT_IN_SYS_CDIO_H +#undef DVD_STRUCT_IN_SYS_DVDIO_H +#undef DVD_STRUCT_IN_BSDI_DVDIOCTL_DVD_H +#undef HAVE_BSD_DVD_STRUCT +#define HAVE_LINUX_DVD_STRUCT 1 +#undef HAVE_OPENBSD_DVD_STRUCT +#undef DARWIN_DVD_IOCTL +#undef SOLARIS_USCSI +#undef HPUX_SCTL_IO +#define HAVE_STDDEF_H 1 + +/* Common data directory (for fonts, etc) */ +#define DATADIR "/usr/local/share/mplayer" +#define CONFDIR "/usr/local/etc/mplayer" +#define LIBDIR "/usr/local/lib" + +/* Define this to compile stream-caching support, it can be enabled via + -cache */ +#define USE_STREAM_CACHE 1 + +/* Define to include support for XviD/Divx4Linux/OpenDivx */ +#define USE_DIVX + +/* Define to use the new XviD/DivX4Linux library instead of open source OpenDivX */ +/* You have to change DECORE_LIBS in config.mak, too! */ +#define NEW_DECORE 1 + +/* Define if you are using DivX5Linux Decore library */ +#define DECORE_DIVX5 1 + +/* Define if you are using XviD library */ +#define HAVE_XVID 1 +#undef DECORE_XVID +#undef ENCORE_XVID + +/* Define to include support for libdv-0.9.5 */ +#undef HAVE_LIBDV095 + +/* If build mencoder */ +#define HAVE_MENCODER + +/* Indicates if XviD/Divx4linux encore is available + Note: for mencoder */ +#define HAVE_DIVX4ENCORE 1 + +/* Indicates if libmp3lame is available + Note: for mencoder */ +#define HAVE_MP3LAME 393 + +/* Define libmp1e for realtime mpeg encoding (for DXR3 and DVB cards) */ +#undef USE_MP1E + +/* Define this to enable avg. byte/sec-based AVI sync method by default: + (use -bps or -nobps commandline option for run-time method selection) + -bps gives better sync for vbr mp3 audio, it is now default */ +#define AVI_SYNC_BPS 1 + +/* Undefine this if you do not want to select mono audio (left or right) + with a stereo MPEG layer 2/3 audio stream. The command line option + -stereo has three possible values (0 for stereo, 1 for left-only, 2 for + right-only), with 0 being the default. + */ +#define USE_FAKE_MONO 1 + +/* Undefine this if your sound card driver has no working select(). + If you have kernel Oops, player hangups, or just no audio, you should + try to recompile MPlayer with this option disabled! */ +#define HAVE_AUDIO_SELECT 1 + +/* define this to use iconv(3) function to codepage conversions */ +#define USE_ICONV 1 + +/* define this to use RTC (/dev/rtc) for video timers (LINUX only) */ +#define HAVE_RTC 1 + +/* set up max. outburst. use 65536 for ALSA 0.5, for others 16384 is enough */ +#define MAX_OUTBURST 65536 + +/* set up audio OUTBURST. Do not change this! */ +#define OUTBURST 512 + +/* Define this if your system has the header file for the OSS sound interface */ +#define HAVE_SYS_SOUNDCARD_H 1 + +/* Define this if your system has the header file for the OSS sound interface + * in /usr/include */ +#undef HAVE_SOUNDCARD_H + +/* Define this if your system has the sysinfo header */ +#define HAVE_SYS_SYSINFO_H 1 + +/* Define this if your system uses ftello() for off_t seeking */ + +#define HAVE_FTELLO 1 +#ifndef HAVE_FTELLO +# define ftello(a) ftell(a) +#endif + +/* Define this if your system has the "malloc.h" header file */ +#define HAVE_MALLOC_H 1 + +/* memalign is mapped to malloc if unsupported */ +#define HAVE_MEMALIGN 1 +#ifndef HAVE_MEMALIGN +# define memalign(a,b) malloc(b) +#endif + +/* Define this if your system has the "alloca.h" header file */ +#define HAVE_ALLOCA_H 1 + +/* Define this if your system has the "sys/mman.h" header file */ +#define HAVE_SYS_MMAN_H 1 + +/* Define this if you have the elf dynamic linker -ldl library */ +#define HAVE_LIBDL 1 + +/* Define this if you have the kstat kernel statistics library */ +#undef HAVE_LIBKSTAT + +/* Define this if you have zlib */ +#define HAVE_ZLIB 1 + +/* Define this if you have shm support */ +#define HAVE_SHM 1 + +/* Define this if your system has scandir & alphasort */ +#define HAVE_SCANDIR 1 + +/* Define this if your system has strsep */ +#define HAVE_STRSEP 1 + +/* Define this if your system has vsscanf */ +#define HAVE_VSSCANF 1 + +/* LIRC (remote control, see www.lirc.org) support: */ +#undef HAVE_LIRC + +/* DeCSS support using libcss */ +#undef HAVE_LIBCSS + +/* DVD navigation support using libdvdnav */ +#undef USE_DVDNAV + + +/* Define this to enable MPEG 1/2 image postprocessing (requires a FAST CPU!) */ +#define MPEG12_POSTPROC 1 + +/* Define this to enable image postprocessing in libavcodec (requires a FAST CPU!) */ +#define FF_POSTPROCESS 1 + +/* Define to include support for OpenDivx postprocessing */ +#undef HAVE_ODIVX_POSTPROCESS + +/* Win32 DLL support */ +#define USE_WIN32DLL 1 +#define WIN32_PATH "/usr/local/lib/win32" + +/* DirectShow support */ +#define USE_DIRECTSHOW 1 + +/* Mac OS X specific features */ +#undef MACOSX + +/* Build our Win32-loader */ +#define WIN32_LOADER 1 + +/* ffmpeg's libavcodec support (requires libavcodec source) */ +#define USE_LIBAVCODEC 1 +#undef USE_LIBAVCODEC_SO + +/* risky codecs */ +#define CONFIG_RISKY 1 + +/* Use libavcodec's decoders */ +#define CONFIG_DECODERS 1 +/* Use libavcodec's encoders */ +#define CONFIG_ENCODERS 1 + +/* Use codec libs included in mplayer CVS / source dist: */ +#define USE_MP3LIB +#define USE_LIBA52 +#define USE_LIBMPEG2 + +/* Use the SVQ1 decoder in libmpcodecs - we don't want/need it with libavcodec */ +#ifndef USE_LIBAVCODEC +#define USE_SVQ1 +#endif + +/* Use libfame encoder filter */ +#undef USE_LIBFAME + +/* XAnim DLL support */ +#undef USE_XANIM +/* Default search path */ +#undef XACODEC_PATH + +/* RealPlayer DLL support */ +#define USE_REALCODECS 1 +/* Default search path */ +#define REALCODEC_PATH "/usr/lib/RealPlayer8/Codecs" + +/* LIVE.COM Streaming Media library support */ +#undef STREAMING_LIVE_DOT_COM + +/* Use 3dnow/mmxext/sse/mmx optimized fast memcpy() [maybe buggy... signal 4]*/ +#define USE_FASTMEMCPY 1 + +/* Use unrarlib for Vobsubs */ +#define USE_UNRARLIB 1 + +/* gui support, please do not edit this option */ +#undef HAVE_NEW_GUI + +/* Audio output drivers */ +#define USE_OSS_AUDIO 1 +#define PATH_DEV_DSP "/dev/dsp" +#define PATH_DEV_MIXER "/dev/mixer" +#undef HAVE_ALSA5 +#undef HAVE_ALSA9 + +#define USE_ESD 1 +#undef HAVE_SYS_ASOUNDLIB_H +#undef HAVE_ALSA_ASOUNDLIB_H +#undef USE_SUN_AUDIO +#undef USE_SGI_AUDIO +#undef HAVE_WIN32WAVEOUT +#undef HAVE_NAS + +/* Enable fast OSD/SUB renderer (looks ugly, but uses less CPU power) */ +#undef FAST_OSD +#undef FAST_OSD_TABLE + +/* Enable TV Interface support */ +#define USE_TV 1 + +/* Enable EDL support */ +#define USE_EDL + +/* Enable Video 4 Linux TV interface support */ +#undef HAVE_TV_V4L + +/* Enable *BSD BrookTree TV interface support */ +#undef HAVE_TV_BSDBT848 + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +#define ARCH_X86 1 + +/* Define this for Cygwin build for win32 */ + + +/* Define this to any prefered value from 386 up to infinity with step 100 */ +#define __CPU__ 686 + +#define MP_WORDSIZE 32 + +#define TARGET_LINUX 1 + +#define HAVE_VCD 1 + +#ifdef sun +#define DEFAULT_CDROM_DEVICE "/vol/dev/aliases/cdrom0" +#define DEFAULT_DVD_DEVICE DEFAULT_CDROM_DEVICE +#elif defined(HPUX) +#define DEFAULT_CDROM_DEVICE "/dev/cdrom" +#define DEFAULT_DVD_DEVICE "/dev/dvd" +#elif defined(WIN32) +#define DEFAULT_CDROM_DEVICE "D:" +#define DEFAULT_DVD_DEVICE "D:" +#elif defined(SYS_DARWIN) +#define DEFAULT_CDROM_DEVICE "/dev/rdiskN" +#define DEFAULT_DVD_DEVICE DEFAULT_CDROM_DEVICE +#else +#define DEFAULT_CDROM_DEVICE "/dev/cdrom" +#define DEFAULT_DVD_DEVICE "/dev/dvd" +#endif + + +/*---------------------------------------------------------------------------- +** +** NOTE: Instead of modifying these definitions here, use the +** --enable/--disable options of the ./configure script! +** See ./configure --help for details. +** +*---------------------------------------------------------------------------*/ + +/* C99 lrintf function available */ +#define HAVE_LRINTF 1 + +/* nanosleep support */ +#define HAVE_NANOSLEEP 1 + +/* termcap flag for getch2.c */ +#define USE_TERMCAP 1 + +/* termios flag for getch2.c */ +#define HAVE_TERMIOS 1 +#undef HAVE_TERMIOS_H +#define HAVE_SYS_TERMIOS_H 1 + +/* enable PNG support */ +#define HAVE_PNG 1 + +/* enable JPEG support */ +#define HAVE_JPEG 1 + +/* enable GIF support */ +#define HAVE_GIF 1 +#define HAVE_GIF_4 1 +#undef HAVE_GIF_TVT_HACK + +/* enable FreeType support */ +#define HAVE_FREETYPE + +/* liblzo support */ +#undef USE_LIBLZO + +/* libmad support */ +#define USE_LIBMAD 1 + +/* enable OggVorbis support */ +#undef HAVE_OGGVORBIS + +/* enable Tremor as vorbis decoder */ +#undef TREMOR + +/* enable FAAD (AAC) support */ +#undef HAVE_FAAD + + +/* enable streaming */ +#define STREAMING 1 + +/* define this to use inet_aton() instead of inet_pton() */ +#undef USE_ATON + +/* enables / disables cdparanoia support */ +#undef HAVE_CDDA + +/* enables / disables VIDIX usage */ +#define CONFIG_VIDIX 1 + +/* enables / disables new input joystick support */ +#undef HAVE_JOYSTICK + +/* enables / disables new config */ +#define NEW_CONFIG 1 + +/* enables / disables QTX codecs */ +#define USE_QTX_CODECS 1 + +/* enables / disables osd menu */ +#undef HAVE_MENU + +/* enables / disables subtitles sorting */ +#define USE_SORTSUB 1 + +/* XMMS input plugin support */ +#undef HAVE_XMMS +#define XMMS_INPUT_PLUGIN_DIR "" + +/* Extension defines */ +#define HAVE_3DNOW 1 // only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.) +#define HAVE_3DNOWEX 1 // only define if you have 3DNOWEX (AMD Athlon, etc.) +#define HAVE_MMX 1 // only define if you have MMX (newer x86 chips, not P54C/PPro) +#define HAVE_MMX2 1 // only define if you have MMX2 (Athlon/PIII/4/CelII) +#define HAVE_SSE 1 // only define if you have SSE (Intel Pentium III/4 or Celeron II) +#undef HAVE_SSE2 // only define if you have SSE2 (Intel Pentium 4) +#undef HAVE_ALTIVEC // only define if you have Altivec (G4) + +#ifdef HAVE_MMX +#define USE_MMX_IDCT 1 +#endif + +#undef HAVE_MLIB // Sun mediaLib, available only on solaris + +/* libmpeg2 uses a different feature test macro for mediaLib */ +#ifdef HAVE_MLIB +#define LIBMPEG2_MLIB 1 +#endif + +/* libvo options */ +#define SCREEN_SIZE_X 1 +#define SCREEN_SIZE_Y 1 +#define HAVE_X11 1 +#define HAVE_XV 1 +#define HAVE_XF86VM 1 +#define HAVE_XINERAMA 1 +#define HAVE_GL 1 +#define HAVE_DGA 1 +#define HAVE_DGA2 1 +#undef HAVE_SDL +/* defined for SDLlib with keyrepeat bugs (before 1.2.1) */ + +#undef HAVE_DIRECTX +#undef HAVE_GGI +#undef HAVE_3DFX +#undef HAVE_TDFXFB +#undef HAVE_DIRECTFB + +#undef HAVE_ZR +#undef HAVE_BL +#undef HAVE_MGA +#undef HAVE_XMGA + +#undef HAVE_FBDEV +#undef USE_CONVERT2FB +#undef HAVE_DXR2 +#undef HAVE_DXR3 +#undef HAVE_DVB +#undef HAVE_SVGALIB +#define HAVE_VESA 1 +#define HAVE_XDPMS 1 +#undef HAVE_AA + +/* used by GUI: */ + + +#if defined(HAVE_GL) || defined(HAVE_X11) || defined(HAVE_XV) +#define X11_FULLSCREEN 1 +#endif + diff --git a/linphone/win32acm/cpudetect.c b/linphone/win32acm/cpudetect.c new file mode 100644 index 000000000..401dadc10 --- /dev/null +++ b/linphone/win32acm/cpudetect.c @@ -0,0 +1,506 @@ +#include "config.h" +#include "cpudetect.h" +#include "mp_msg.h" + +CpuCaps gCpuCaps; + +#ifdef HAVE_MALLOC_H +#include +#endif +#include + +#ifdef ARCH_X86 + +#include +#include + +#ifdef __NetBSD__ +#include +#include +#include +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +#ifdef __linux__ +#include +#endif + +//#define X86_FXSR_MAGIC +/* Thanks to the FreeBSD project for some of this cpuid code, and + * help understanding how to use it. Thanks to the Mesa + * team for SSE support detection and more cpu detect code. + */ + +/* I believe this code works. However, it has only been used on a PII and PIII */ + +static void check_os_katmai_support( void ); + +#if 1 +// return TRUE if cpuid supported +static int has_cpuid() +{ + int a, c; + +// code from libavcodec: + __asm__ __volatile__ ( + /* See if CPUID instruction is supported ... */ + /* ... Get copies of EFLAGS into eax and ecx */ + "pushf\n\t" + "popl %0\n\t" + "movl %0, %1\n\t" + + /* ... Toggle the ID bit in one copy and store */ + /* to the EFLAGS reg */ + "xorl $0x200000, %0\n\t" + "push %0\n\t" + "popf\n\t" + + /* ... Get the (hopefully modified) EFLAGS */ + "pushf\n\t" + "popl %0\n\t" + : "=a" (a), "=c" (c) + : + : "cc" + ); + + return (a!=c); +} +#endif + +static void +do_cpuid(unsigned int ax, unsigned int *p) +{ +#if 0 + __asm __volatile( + "cpuid;" + : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax) + ); +#else +// code from libavcodec: + __asm __volatile + ("movl %%ebx, %%esi\n\t" + "cpuid\n\t" + "xchgl %%ebx, %%esi" + : "=a" (p[0]), "=S" (p[1]), + "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); +#endif + +} + +void GetCpuCaps( CpuCaps *caps) +{ + unsigned int regs[4]; + unsigned int regs2[4]; + + memset(caps, 0, sizeof(*caps)); + caps->isX86=1; + caps->cl_size=32; /* default */ + if (!has_cpuid()) { + mp_msg(MSGT_CPUDETECT,MSGL_WARN,"CPUID not supported!??? (maybe an old 486?)\n"); + return; + } + do_cpuid(0x00000000, regs); // get _max_ cpuid level and vendor name + mp_msg(MSGT_CPUDETECT,MSGL_V,"CPU vendor name: %.4s%.4s%.4s max cpuid level: %d\n", + (char*) (regs+1),(char*) (regs+3),(char*) (regs+2), regs[0]); + if (regs[0]>=0x00000001) + { + char *tmpstr; + unsigned cl_size; + + do_cpuid(0x00000001, regs2); + + tmpstr=GetCpuFriendlyName(regs, regs2); + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"CPU: %s ",tmpstr); + free(tmpstr); + + caps->cpuType=(regs2[0] >> 8)&0xf; + if(caps->cpuType==0xf){ + // use extended family (P4, IA64) + caps->cpuType=8+((regs2[0]>>20)&255); + } + caps->cpuStepping=regs2[0] & 0xf; + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"(Family: %d, Stepping: %d)\n", + caps->cpuType, caps->cpuStepping); + + // general feature flags: + caps->hasMMX = (regs2[3] & (1 << 23 )) >> 23; // 0x0800000 + caps->hasSSE = (regs2[3] & (1 << 25 )) >> 25; // 0x2000000 + caps->hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; // 0x4000000 + caps->hasMMX2 = caps->hasSSE; // SSE cpus supports mmxext too + cl_size = ((regs2[1] >> 8) & 0xFF)*8; + if(cl_size) caps->cl_size = cl_size; + } + do_cpuid(0x80000000, regs); + if (regs[0]>=0x80000001) { + mp_msg(MSGT_CPUDETECT,MSGL_V,"extended cpuid-level: %d\n",regs[0]&0x7FFFFFFF); + do_cpuid(0x80000001, regs2); + caps->hasMMX |= (regs2[3] & (1 << 23 )) >> 23; // 0x0800000 + caps->hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; // 0x400000 + caps->has3DNow = (regs2[3] & (1 << 31 )) >> 31; //0x80000000 + caps->has3DNowExt = (regs2[3] & (1 << 30 )) >> 30; + } + if(regs[0]>=0x80000006) + { + do_cpuid(0x80000006, regs2); + mp_msg(MSGT_CPUDETECT,MSGL_V,"extended cache-info: %d\n",regs2[2]&0x7FFFFFFF); + caps->cl_size = regs2[2] & 0xFF; + } + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"Detected cache-line size is %u bytes\n",caps->cl_size); +#if 0 + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"cpudetect: MMX=%d MMX2=%d SSE=%d SSE2=%d 3DNow=%d 3DNowExt=%d\n", + gCpuCaps.hasMMX, + gCpuCaps.hasMMX2, + gCpuCaps.hasSSE, + gCpuCaps.hasSSE2, + gCpuCaps.has3DNow, + gCpuCaps.has3DNowExt ); +#endif + + /* FIXME: Does SSE2 need more OS support, too? */ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) + if (caps->hasSSE) + check_os_katmai_support(); + if (!caps->hasSSE) + caps->hasSSE2 = 0; +#else + caps->hasSSE=0; + caps->hasSSE2 = 0; +#endif +// caps->has3DNow=1; +// caps->hasMMX2 = 0; +// caps->hasMMX = 0; + +#ifndef HAVE_MMX + if(caps->hasMMX) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"MMX supported but disabled\n"); + caps->hasMMX=0; +#endif +#ifndef HAVE_MMX2 + if(caps->hasMMX2) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"MMX2 supported but disabled\n"); + caps->hasMMX2=0; +#endif +#ifndef HAVE_SSE + if(caps->hasSSE) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"SSE supported but disabled\n"); + caps->hasSSE=0; +#endif +#ifndef HAVE_SSE2 + if(caps->hasSSE2) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"SSE2 supported but disabled\n"); + caps->hasSSE2=0; +#endif +#ifndef HAVE_3DNOW + if(caps->has3DNow) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"3DNow supported but disabled\n"); + caps->has3DNow=0; +#endif +#ifndef HAVE_3DNOWEX + if(caps->has3DNowExt) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"3DNowExt supported but disabled\n"); + caps->has3DNowExt=0; +#endif +} + + +#define CPUID_EXTFAMILY ((regs2[0] >> 20)&0xFF) /* 27..20 */ +#define CPUID_EXTMODEL ((regs2[0] >> 16)&0x0F) /* 19..16 */ +#define CPUID_TYPE ((regs2[0] >> 12)&0x04) /* 13..12 */ +#define CPUID_FAMILY ((regs2[0] >> 8)&0x0F) /* 11..08 */ +#define CPUID_MODEL ((regs2[0] >> 4)&0x0F) /* 07..04 */ +#define CPUID_STEPPING ((regs2[0] >> 0)&0x0F) /* 03..00 */ + +char *GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]){ +#include "cputable.h" /* get cpuname and cpuvendors */ + char vendor[17]; + char *retname; + int i; + + if (NULL==(retname=(char*)malloc(256))) { + mp_msg(MSGT_CPUDETECT,MSGL_FATAL,"Error: GetCpuFriendlyName() not enough memory\n"); + exit(1); + } + + sprintf(vendor,"%.4s%.4s%.4s",(char*)(regs+1),(char*)(regs+3),(char*)(regs+2)); + + for(i=0; imagic != 0xffff ) { + /* Our signal context has the extended FPU state, so reset the + * divide-by-zero exception mask and clear the divide-by-zero + * exception bit. + */ + sc.fpstate->mxcsr |= 0x00000200; + sc.fpstate->mxcsr &= 0xfffffffb; + } else { + /* If we ever get here, we're completely hosed. + */ + mp_msg(MSGT_CPUDETECT,MSGL_V, "\n\n" ); + mp_msg(MSGT_CPUDETECT,MSGL_V, "SSE enabling test failed badly!" ); + } +} +#endif /* __linux__ && _POSIX_SOURCE && X86_FXSR_MAGIC */ + +/* If we're running on a processor that can do SSE, let's see if we + * are allowed to or not. This will catch 2.4.0 or later kernels that + * haven't been configured for a Pentium III but are running on one, + * and RedHat patched 2.2 kernels that have broken exception handling + * support for user space apps that do SSE. + */ +static void check_os_katmai_support( void ) +{ +#if defined(__FreeBSD__) + int has_sse=0, ret; + size_t len=sizeof(has_sse); + + ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0); + if (ret || !has_sse) + gCpuCaps.hasSSE=0; + +#elif defined(__NetBSD__) +#if __NetBSD_Version__ >= 105250000 + int has_sse, has_sse2, ret, mib[2]; + size_t varlen; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_SSE; + varlen = sizeof(has_sse); + + mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " ); + ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0); + if (ret < 0 || !has_sse) { + gCpuCaps.hasSSE=0; + mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); + } else { + gCpuCaps.hasSSE=1; + mp_msg(MSGT_CPUDETECT,MSGL_V, "yes!\n" ); + } + + mib[1] = CPU_SSE2; + varlen = sizeof(has_sse2); + mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE2... " ); + ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0); + if (ret < 0 || !has_sse2) { + gCpuCaps.hasSSE2=0; + mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); + } else { + gCpuCaps.hasSSE2=1; + mp_msg(MSGT_CPUDETECT,MSGL_V, "yes!\n" ); + } +#else + gCpuCaps.hasSSE = 0; + mp_msg(MSGT_CPUDETECT,MSGL_WARN, "No OS support for SSE, disabling to be safe.\n" ); +#endif +#elif defined(__linux__) +#if defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) + struct sigaction saved_sigill; + struct sigaction saved_sigfpe; + + /* Save the original signal handlers. + */ + sigaction( SIGILL, NULL, &saved_sigill ); + sigaction( SIGFPE, NULL, &saved_sigfpe ); + + signal( SIGILL, (void (*)(int))sigill_handler_sse ); + signal( SIGFPE, (void (*)(int))sigfpe_handler_sse ); + + /* Emulate test for OSFXSR in CR4. The OS will set this bit if it + * supports the extended FPU save and restore required for SSE. If + * we execute an SSE instruction on a PIII and get a SIGILL, the OS + * doesn't support Streaming SIMD Exceptions, even if the processor + * does. + */ + if ( gCpuCaps.hasSSE ) { + mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " ); + +// __asm __volatile ("xorps %%xmm0, %%xmm0"); + __asm __volatile ("xorps %xmm0, %xmm0"); + + if ( gCpuCaps.hasSSE ) { + mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" ); + } else { + mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); + } + } + + /* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if + * it supports unmasked SIMD FPU exceptions. If we unmask the + * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS + * doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE + * as expected, we're okay but we need to clean up after it. + * + * Are we being too stringent in our requirement that the OS support + * unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by + * setting CR4.OSFXSR but don't support unmasked exceptions. Win98 + * doesn't even support them. We at least know the user-space SSE + * support is good in kernels that do support unmasked exceptions, + * and therefore to be safe I'm going to leave this test in here. + */ + if ( gCpuCaps.hasSSE ) { + mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE unmasked exceptions... " ); + +// test_os_katmai_exception_support(); + + if ( gCpuCaps.hasSSE ) { + mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" ); + } else { + mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); + } + } + + /* Restore the original signal handlers. + */ + sigaction( SIGILL, &saved_sigill, NULL ); + sigaction( SIGFPE, &saved_sigfpe, NULL ); + + /* If we've gotten to here and the XMM CPUID bit is still set, we're + * safe to go ahead and hook out the SSE code throughout Mesa. + */ + if ( gCpuCaps.hasSSE ) { + mp_msg(MSGT_CPUDETECT,MSGL_V, "Tests of OS support for SSE passed.\n" ); + } else { + mp_msg(MSGT_CPUDETECT,MSGL_V, "Tests of OS support for SSE failed!\n" ); + } +#else + /* We can't use POSIX signal handling to test the availability of + * SSE, so we disable it by default. + */ + mp_msg(MSGT_CPUDETECT,MSGL_WARN, "Cannot test OS support for SSE, disabling to be safe.\n" ); + gCpuCaps.hasSSE=0; +#endif /* _POSIX_SOURCE && X86_FXSR_MAGIC */ +#else + /* Do nothing on other platforms for now. + */ + mp_msg(MSGT_CPUDETECT,MSGL_WARN, "Cannot test OS support for SSE, leaving disabled.\n" ); + gCpuCaps.hasSSE=0; +#endif /* __linux__ */ +} +#else /* ARCH_X86 */ + +#ifdef SYS_DARWIN +#include +#else +#include +#include + +static sigjmp_buf jmpbuf; +static volatile sig_atomic_t canjump = 0; + +static void sigill_handler (int sig) +{ + if (!canjump) { + signal (sig, SIG_DFL); + raise (sig); + } + + canjump = 0; + siglongjmp (jmpbuf, 1); +} +#endif + +void GetCpuCaps( CpuCaps *caps) +{ + caps->cpuType=0; + caps->cpuStepping=0; + caps->hasMMX=0; + caps->hasMMX2=0; + caps->has3DNow=0; + caps->has3DNowExt=0; + caps->hasSSE=0; + caps->hasSSE2=0; + caps->isX86=0; + caps->hasAltiVec = 0; +#ifdef HAVE_ALTIVEC +#ifdef SYS_DARWIN +/* + rip-off from ffmpeg altivec detection code. + this code also appears on Apple's AltiVec pages. + */ + { + int sels[2] = {CTL_HW, HW_VECTORUNIT}; + int has_vu = 0; + size_t len = sizeof(has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) + if (has_vu != 0) + caps->hasAltiVec = 1; + } +#else /* SYS_DARWIN */ +/* no Darwin, do it the brute-force way */ +/* this is borrowed from the libmpeg2 library */ + { + signal (SIGILL, sigill_handler); + if (sigsetjmp (jmpbuf, 1)) { + signal (SIGILL, SIG_DFL); + } else { + canjump = 1; + + asm volatile ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + signal (SIGILL, SIG_DFL); + caps->hasAltiVec = 1; + } + } +#endif /* SYS_DARWIN */ + mp_msg(MSGT_CPUDETECT,MSGL_INFO,"AltiVec %sfound\n", (caps->hasAltiVec ? "" : "not ")); +#endif /* HAVE_ALTIVEC */ +} +#endif /* !ARCH_X86 */ diff --git a/linphone/win32acm/cpudetect.h b/linphone/win32acm/cpudetect.h new file mode 100644 index 000000000..c68013ba7 --- /dev/null +++ b/linphone/win32acm/cpudetect.h @@ -0,0 +1,31 @@ +#ifndef CPUDETECT_H +#define CPUDETECT_H + +#define CPUTYPE_I386 3 +#define CPUTYPE_I486 4 +#define CPUTYPE_I586 5 +#define CPUTYPE_I686 6 + +typedef struct cpucaps_s { + int cpuType; + int cpuStepping; + int hasMMX; + int hasMMX2; + int has3DNow; + int has3DNowExt; + int hasSSE; + int hasSSE2; + int isX86; + unsigned cl_size; /* size of cache line */ + int hasAltiVec; +} CpuCaps; + +extern CpuCaps gCpuCaps; + +void GetCpuCaps(CpuCaps *caps); + +/* returned value is malloc()'ed so free() it after use */ +char *GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]); + +#endif /* !CPUDETECT_H */ + diff --git a/linphone/win32acm/cputable.h b/linphone/win32acm/cputable.h new file mode 100644 index 000000000..0c52fa306 --- /dev/null +++ b/linphone/win32acm/cputable.h @@ -0,0 +1,474 @@ +/* cputable.h - Maps CPUID to real CPU name. + * Copyleft 2001 by Felix Buenemann + * This file comes under the GNU GPL, see www.fsf.org for more info! + */ + +#define MAX_VENDORS 8 /* Number of CPU Vendors */ + +//#define N_UNKNOWN "unknown" +//#define N_UNKNOWNEXT "unknown extended model" +#define N_UNKNOWN "" +#define N_UNKNOWNEXT "" + +#define F_UNKNOWN { \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN, \ +N_UNKNOWN \ +} + +static const char *cpuname + /* Vendor */ [MAX_VENDORS] + /* Family */ [16] + /* Model */ [16] + ={ + /* Intel Corporation, "GenuineIntel" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 i386 */ F_UNKNOWN, /* XXX new 386 chips may support CPUID! */ + /* 4 i486 */ { + /* 0 */ "i486DX-25/33", /* only few of these */ + /* 1 */ "i486DX-50", /* support CPUID! */ + /* 2 */ "i486SX", + /* 3 */ "i486DX2", /* CPUID only on new chips! */ + /* 4 */ "i486SL", + /* 5 */ "i486SX2", + /* 6 */ N_UNKNOWN, + /* 7 */ "i486DX2/write-back", /* returns 3 in write-through mode */ + /* 8 */ "i486DX4", + /* 9 */ "i486DX4/write-back", + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWNEXT + }, + /* 5 i586 */ { + /* 0 */ "Pentium P5 A-step", + /* 1 */ "Pentium P5", + /* 2 */ "Pentium P54C", + /* 3 */ "Pentium OverDrive P24T", + /* 4 */ "Pentium MMX P55C", + /* 5 */ N_UNKNOWN, /* XXX DX4 OverDrive? */ + /* 6 */ N_UNKNOWN, /* XXX P5 OverDrive? */ + /* 7 */ "Pentium P54C (new)", + /* 8 */ "Pentium MMX P55C (new)", + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWNEXT + }, + /* 6 i686 */ { + /* 0 */ "PentiumPro A-step", + /* 1 */ "PentiumPro", + /* 2 */ N_UNKNOWN, + /* 3 */ "Pentium II Klamath/Pentium II OverDrive", + /* 4 */ N_UNKNOWN, /* XXX P55CT - OverDrive for P54? */ + /* 5 */ "Celeron Covington/Pentium II Deschutes,Tonga/Pentium II Xeon", + /* 6 */ "Celeron A Mendocino/Pentium II Dixon", + /* 7 */ "Pentium III Katmai/Pentium III Xeon Tanner", + /* 8 */ "Celeron 2/Pentium III Coppermine,Geyserville", + /* 9 */ N_UNKNOWN, + /* A */ "Pentium III Xeon Cascades", + /* B */ "Celeron 2/Pentium III Tualatin", + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWNEXT + }, + /* 7 IA-64 */ { /* FIXME */ + /* 0 */ N_UNKNOWN, + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWNEXT + }, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F extended family (P4/new IA-64)*/ { + /* 0 */ "Pentium 4 Willamette", + /* 1 */ "Pentium 4 Xeon Foster", /*?*/ + /* XXX 0.13µm P4 Northwood ??? */ + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWNEXT + } + }, + /* United Microelectronics Corporation, "UMC UMC UMC " */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 486 (U5) */ { + /* 0 */ N_UNKNOWN, + /* 1 */ "486DX U5D", + /* 2 */ "486SX U5S", + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 5 */ F_UNKNOWN, + /* 6 */ F_UNKNOWN, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* Advanced Micro Devices, "AuthenticAMD" (very rare: "AMD ISBETTER") */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 486/5x86 */ { + /* 0 */ N_UNKNOWN, + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ "486DX2", + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ "486DX2/write-back", + /* 8 */ "486DX4/5x86", + /* 9 */ "486DX4/write-back", + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* E */ "5x86", + /* F */ "5x86/write-back" + }, + /* 5 K5/K6 */ { + /* 0 */ "K5 SSA5 (PR75,PR90,PR100)", + /* 1 */ "K5 5k86 (PR120,PR133)", + /* 2 */ "K5 5k86 (PR166)", + /* 3 */ "K5 5k86 (PR200)", + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ "K6", + /* 7 */ "K6 Little Foot", + /* 8 */ "K6-2", + /* 9 */ "K6-III Chomper", + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ "K6-2+/K6-III+ Sharptooth", + /* E */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 6 K7 */ { + /* 0 */ N_UNKNOWN, /* Argon? */ + /* 1 */ "Athlon K7", + /* 2 */ "Athlon K75 Pluto,Orion", + /* 3 */ "Duron SF Spitfire", + /* 4 */ "Athlon TB Thunderbird", + /* 5 */ N_UNKNOWN, + /* 6 */ "Athlon 4 PM Palomino/Athlon MP Multiprocessor/Athlon XP eXtreme Performance", + /* 7 */ "Duron MG Morgan", + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* Cyrix Corp./VIA Inc., "CyrixInstead" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 5x86 */ { + /* 0 */ N_UNKNOWN, + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ "MediaGX", + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ "5x86", /* CPUID maybe only on newer chips */ + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 5 M1 */ { + /* 0 */ "M1 test-sample", /*?*/ + /* 1 */ N_UNKNOWN, + /* 2 */ "6x86 M1", + /* 3 */ N_UNKNOWN, + /* 4 */ "GXm", + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 6 M2 */ { + /* 0 */ "6x86MX M2/M-II", + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ "Cyrix III Joshua (M2 core)", + /* 6 */ "Cyrix III Samuel (WinChip C5A core)", + /* 7 */ "C3 Samuel 2 (WinChip C5B core)", + /* 8 */ N_UNKNOWN, /* XXX Samuel 3/Ezra? */ + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* NexGen Inc., "NexGenDriven" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 */ F_UNKNOWN, + /* 5 Nx586 */ { + /* 0 */ "Nx586/Nx586FPU", /* only newer ones support CPUID! */ + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 6 */ F_UNKNOWN, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* IDT/Centaur/VIA, "CentaurHauls" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 */ F_UNKNOWN, + /* 5 IDT C6 WinChip */ { + /* 0 */ N_UNKNOWN, + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ "WinChip C6", + /* 5 */ N_UNKNOWN, + /* 6 */ "Samuel", + /* 7 */ N_UNKNOWN, + /* 8 */ "WinChip 2 C6+,W2,W2A,W2B", + /* 9 */ "WinChip 3 W3", + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + + }, + /* 6 */ F_UNKNOWN, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* Rise, "RiseRiseRise" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 */ F_UNKNOWN, + /* 5 mP6 */ { + /* 0 */ "mP6 iDragon 6401,6441 Kirin", + /* 1 */ "mP6 iDragon 6510 Lynx", + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ N_UNKNOWN, + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ "mP6 iDragon II", + /* 9 */ "mP6 iDragon II (new)", + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 6 */ F_UNKNOWN, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + }, + /* Transmeta, "GenuineTMx86" */ { + /* 0 */ F_UNKNOWN, + /* 1 */ F_UNKNOWN, + /* 2 */ F_UNKNOWN, + /* 3 */ F_UNKNOWN, + /* 4 */ F_UNKNOWN, + /* 5 Crusoe */ { + /* 0 */ N_UNKNOWN, + /* 1 */ N_UNKNOWN, + /* 2 */ N_UNKNOWN, + /* 3 */ N_UNKNOWN, + /* 4 */ "Crusoe TM3x00,TM5x00", + /* 5 */ N_UNKNOWN, + /* 6 */ N_UNKNOWN, + /* 7 */ N_UNKNOWN, + /* 8 */ N_UNKNOWN, + /* 9 */ N_UNKNOWN, + /* A */ N_UNKNOWN, + /* B */ N_UNKNOWN, + /* E */ N_UNKNOWN, + /* C */ N_UNKNOWN, + /* D */ N_UNKNOWN, + /* F */ N_UNKNOWN + }, + /* 6 */ F_UNKNOWN, + /* 7 */ F_UNKNOWN, + /* 8 */ F_UNKNOWN, + /* 9 */ F_UNKNOWN, + /* A */ F_UNKNOWN, + /* B */ F_UNKNOWN, + /* C */ F_UNKNOWN, + /* D */ F_UNKNOWN, + /* E */ F_UNKNOWN, + /* F */ F_UNKNOWN + } +}; + +#undef N_UNKNOWNEXT +#undef N_UNKNOWN +#undef F_UNKNOWN + +static const struct { + char string[13]; + char name[48]; +} cpuvendors[MAX_VENDORS] ={ + {"GenuineIntel","Intel"}, + {"UMC UMC UMC ","United Microelectronics Corporation"}, + {"AuthenticAMD","Advanced Micro Devices"}, + {"CyrixInstead","Cyrix/VIA"}, + {"NexGenDriven","NexGen"}, + {"CentaurHauls","IDT/Centaur/VIA"}, + {"RiseRiseRise","Rise"}, + {"GenuineTMx86","Transmeta"} +}; + diff --git a/linphone/win32acm/driver.c b/linphone/win32acm/driver.c new file mode 100644 index 000000000..7f41288b2 --- /dev/null +++ b/linphone/win32acm/driver.c @@ -0,0 +1,178 @@ +#include "config.h" + +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#ifdef __FreeBSD__ +#include +#endif + +#include "win32.h" +#include "wine/driver.h" +#include "wine/pe_image.h" +#include "wine/winreg.h" +#include "wine/vfw.h" +#include "registry.h" +#include "ldt_keeper.h" +#include "driver.h" +#include "ext.h" + +extern char* def_path; + +#if 1 + +/* + * STORE_ALL/REST_ALL seems like an attempt to workaround problems due to + * WINAPI/no-WINAPI bustage. + * + * There should be no need for the STORE_ALL/REST_ALL hack once all + * function definitions agree with their prototypes (WINAPI-wise) and + * we make sure, that we do not call these functions without a proper + * prototype in scope. + */ + +#define STORE_ALL +#define REST_ALL +#else +// this asm code is no longer needed +#define STORE_ALL \ + __asm__ __volatile__ ( \ + "push %%ebx\n\t" \ + "push %%ecx\n\t" \ + "push %%edx\n\t" \ + "push %%esi\n\t" \ + "push %%edi\n\t"::) + +#define REST_ALL \ + __asm__ __volatile__ ( \ + "pop %%edi\n\t" \ + "pop %%esi\n\t" \ + "pop %%edx\n\t" \ + "pop %%ecx\n\t" \ + "pop %%ebx\n\t"::) +#endif + +static int needs_free=0; +void SetCodecPath(const char* path) +{ + if(needs_free)free(def_path); + if(path==0) + { + def_path=WIN32_PATH; + needs_free=0; + return; + } + def_path = (char*) malloc(strlen(path)+1); + strcpy(def_path, path); + needs_free=1; +} + +static DWORD dwDrvID = 0; + +LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT message, + LPARAM lParam1, LPARAM lParam2) +{ + DRVR* module=(DRVR*)hDriver; + int result; +#ifndef __svr4__ + char qw[300]; +#endif +#ifdef DETAILED_OUT + printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2); +#endif + if (!module || !module->hDriverModule || !module->DriverProc) return -1; +#ifndef __svr4__ + __asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw)); +#endif + + Setup_FS_Segment(); + + STORE_ALL; + result=module->DriverProc(module->dwDriverID, hDriver, message, lParam1, lParam2); + REST_ALL; + +#ifndef __svr4__ + __asm__ __volatile__ ("frstor (%0)\n\t": :"r"(&qw)); +#endif + +#ifdef DETAILED_OUT + printf("\t\tResult: %X\n", result); +#endif + return result; +} + +void DrvClose(HDRVR hDriver) +{ + if (hDriver) + { + DRVR* d = (DRVR*)hDriver; + if (d->hDriverModule) + { + Setup_FS_Segment(); + if (d->DriverProc) + { + SendDriverMessage(hDriver, DRV_CLOSE, 0, 0); + d->dwDriverID = 0; + SendDriverMessage(hDriver, DRV_FREE, 0, 0); + } + FreeLibrary(d->hDriverModule); + } + free(d); + } + CodecRelease(); +} + +//DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2) +HDRVR DrvOpen(LPARAM lParam2) +{ + NPDRVR hDriver; + int i; + char unknown[0x124]; + const char* filename = (const char*) ((ICOPEN*) lParam2)->pV1Reserved; + +#ifdef MPLAYER + Setup_LDT_Keeper(); + printf("Loading codec DLL: '%s'\n",filename); +#endif + + hDriver = (NPDRVR) malloc(sizeof(DRVR)); + if (!hDriver) + return ((HDRVR) 0); + memset((void*)hDriver, 0, sizeof(DRVR)); + + CodecAlloc(); + Setup_FS_Segment(); + + hDriver->hDriverModule = LoadLibraryA(filename); + if (!hDriver->hDriverModule) + { + printf("Can't open library %s\n", filename); + DrvClose((HDRVR)hDriver); + return ((HDRVR) 0); + } + + hDriver->DriverProc = (DRIVERPROC) GetProcAddress(hDriver->hDriverModule, + "DriverProc"); + if (!hDriver->DriverProc) + { + printf("Library %s is not a valid VfW/ACM codec\n", filename); + DrvClose((HDRVR)hDriver); + return ((HDRVR) 0); + } + + TRACE("DriverProc == %X\n", hDriver->DriverProc); + SendDriverMessage((HDRVR)hDriver, DRV_LOAD, 0, 0); + TRACE("DRV_LOAD Ok!\n"); + SendDriverMessage((HDRVR)hDriver, DRV_ENABLE, 0, 0); + TRACE("DRV_ENABLE Ok!\n"); + hDriver->dwDriverID = ++dwDrvID; // generate new id + + // open driver and remmeber proper DriverID + hDriver->dwDriverID = SendDriverMessage((HDRVR)hDriver, DRV_OPEN, (LPARAM) unknown, lParam2); + TRACE("DRV_OPEN Ok!(%X)\n", hDriver->dwDriverID); + + printf("Loaded DLL driver %s\n", filename); + return (HDRVR)hDriver; +} diff --git a/linphone/win32acm/driver.h b/linphone/win32acm/driver.h new file mode 100644 index 000000000..751f0379e --- /dev/null +++ b/linphone/win32acm/driver.h @@ -0,0 +1,22 @@ +#ifndef loader_driver_h +#define loader_driver_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wine/windef.h" +#include "wine/driver.h" + +void SetCodecPath(const char* path); +void CodecAlloc(void); +void CodecRelease(void); + +HDRVR DrvOpen(LPARAM lParam2); +void DrvClose(HDRVR hdrvr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/linphone/win32acm/elfdll.c b/linphone/win32acm/elfdll.c new file mode 100644 index 000000000..c393c4e29 --- /dev/null +++ b/linphone/win32acm/elfdll.c @@ -0,0 +1,292 @@ +/* + * Elf-dll loader functions + * + * Copyright 1999 Bertho A. Stultiens + */ +#include "config.h" + +#ifdef HAVE_LIBDL + +#include "wine/windef.h" +#include "wine/module.h" +#include "wine/heap.h" +#include "wine/elfdll.h" +#include "wine/debugtools.h" +#include "wine/winerror.h" + +//DEFAULT_DEBUG_CHANNEL(elfdll) + +#include +#include +#include +#include +#include + + +//WINE_MODREF *local_wm=NULL; +extern modref_list* local_wm; + + +/*------------------ HACKS -----------------*/ +extern DWORD fixup_imports(WINE_MODREF *wm); +extern void dump_exports(HMODULE hModule); +/*---------------- END HACKS ---------------*/ + +//char *extra_ld_library_path = "/usr/lib/win32"; +extern char* def_path; + +struct elfdll_image +{ + HMODULE pe_module_start; + DWORD pe_module_size; +}; + + +/**************************************************************************** + * ELFDLL_dlopen + * + * Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf + * manually because libdl.so caches the environment and does not accept our + * changes. + */ +void *ELFDLL_dlopen(const char *libname, int flags) +{ + char buffer[256]; + int namelen; + void *handle; + char *ldpath; + + /* First try the default path search of dlopen() */ + handle = dlopen(libname, flags); + if(handle) + return handle; + + /* Now try to construct searches through our extra search-path */ + namelen = strlen(libname); + ldpath = def_path; + while(ldpath && *ldpath) + { + int len; + char *cptr; + char *from; + + from = ldpath; + cptr = strchr(ldpath, ':'); + if(!cptr) + { + len = strlen(ldpath); + ldpath = NULL; + } + else + { + len = cptr - ldpath; + ldpath = cptr + 1; + } + + if(len + namelen + 1 >= sizeof(buffer)) + { + ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n"); + return NULL; + } + + strncpy(buffer, from, len); + if(len) + { + buffer[len] = '/'; + strcpy(buffer + len + 1, libname); + } + else + strcpy(buffer + len, libname); + + TRACE("Trying dlopen('%s', %d)\n", buffer, flags); + + handle = dlopen(buffer, flags); + if(handle) + return handle; + } + return NULL; +} + + +/**************************************************************************** + * get_sobasename (internal) + * + */ +static LPSTR get_sobasename(LPCSTR path, LPSTR name) +{ + char *cptr; + + /* Strip the path from the library name */ + if((cptr = strrchr(path, '/'))) + { + char *cp = strrchr(cptr+1, '\\'); + if(cp && cp > cptr) + cptr = cp; + } + else + cptr = strrchr(path, '\\'); + + if(!cptr) + cptr = (char *)path; /* No '/' nor '\\' in path */ + else + cptr++; + + strcpy(name, cptr); + cptr = strrchr(name, '.'); + if(cptr) + *cptr = '\0'; /* Strip extension */ + + /* Convert to lower case. + * This must be done manually because it is not sure that + * other modules are accessible. + */ + for(cptr = name; *cptr; cptr++) + *cptr = tolower(*cptr); + + return name; +} + + +/**************************************************************************** + * ELFDLL_CreateModref (internal) + * + * INPUT + * hModule - the header from the elf-dll's data-segment + * path - requested path from original call + * + * OUTPUT + * A WINE_MODREF pointer to the new object + * + * BUGS + * - Does not handle errors due to dependencies correctly + * - path can be wrong + */ +#define RVA(base, va) (((DWORD)base) + ((DWORD)va)) + +static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path) +{ +// IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); + IMAGE_DATA_DIRECTORY *dir; + IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; + WINE_MODREF *wm; + int len; + HANDLE procheap = GetProcessHeap(); + + wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm)); + if(!wm) + return NULL; + + wm->module = hModule; + wm->type = MODULE32_ELF; /* FIXME */ + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; +// if(dir->Size) +// wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress); + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; +// if(dir->Size) +// pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress); + +// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; +// if(dir->Size) +// wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress); + + + wm->filename = (char*) malloc(strlen(path)+1); + strcpy(wm->filename, path); + wm->modname = strrchr( wm->filename, '\\' ); + if (!wm->modname) wm->modname = wm->filename; + else wm->modname++; +/* + len = GetShortPathNameA( wm->filename, NULL, 0 ); + wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 ); + GetShortPathNameA( wm->filename, wm->short_filename, len+1 ); + wm->short_modname = strrchr( wm->short_filename, '\\' ); + if (!wm->short_modname) wm->short_modname = wm->short_filename; + else wm->short_modname++; +*/ + /* Link MODREF into process list */ + +// EnterCriticalSection( &PROCESS_Current()->crit_section ); + + if(local_wm) + { + local_wm->next = (modref_list*) malloc(sizeof(modref_list)); + local_wm->next->prev=local_wm; + local_wm->next->next=NULL; + local_wm->next->wm=wm; + local_wm=local_wm->next; + } + else + { + local_wm = (modref_list*) malloc(sizeof(modref_list)); + local_wm->next=local_wm->prev=NULL; + local_wm->wm=wm; + } + +// LeaveCriticalSection( &PROCESS_Current()->crit_section ); + return wm; +} + +/**************************************************************************** + * ELFDLL_LoadLibraryExA (internal) + * + * Implementation of elf-dll loading for PE modules + */ +WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags) +{ + LPVOID dlhandle; + struct elfdll_image *image; + char name[129]; + char soname[129]; + WINE_MODREF *wm; + + get_sobasename(path, name); + strcpy(soname, name); + strcat(soname, ".so"); + + /* Try to open the elf-dll */ + dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY); + if(!dlhandle) + { + WARN("Could not load %s (%s)\n", soname, dlerror()); + SetLastError( ERROR_FILE_NOT_FOUND ); + return NULL; + } + + /* Get the 'dllname_elfdll_image' variable */ +/* strcpy(soname, name); + strcat(soname, "_elfdll_image"); + image = (struct elfdll_image *)dlsym(dlhandle, soname); + if(!image) + { + ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror()); + dlclose(dlhandle); + SetLastError( ERROR_BAD_FORMAT ); + return NULL; + } + +*/ + wm = ELFDLL_CreateModref((int)dlhandle, path); + if(!wm) + { + ERR("Could not create WINE_MODREF for %s\n", path); + dlclose(dlhandle); + SetLastError( ERROR_OUTOFMEMORY ); + return NULL; + } + + return wm; +} + + +/**************************************************************************** + * ELFDLL_UnloadLibrary (internal) + * + * Unload an elf-dll completely from memory and deallocate the modref + */ +void ELFDLL_UnloadLibrary(WINE_MODREF *wm) +{ +} + +#endif /*HAVE_LIBDL*/ diff --git a/linphone/win32acm/ext.c b/linphone/win32acm/ext.c new file mode 100644 index 000000000..638b0cb48 --- /dev/null +++ b/linphone/win32acm/ext.c @@ -0,0 +1,606 @@ +/******************************************************** + * + * + * Stub functions for Wine module + * + * + ********************************************************/ +#include "config.h" +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "wine/windef.h" +#include "wine/winbase.h" +#include "wine/debugtools.h" +#include "wine/heap.h" +#include "ext.h" + +#if 0 +//REMOVE SIMPLIFY +static void* mymalloc(unsigned int size) +{ + printf("malloc %d\n", size); + return malloc(size); +} + +#undef malloc +#define malloc mymalloc +#endif + +int dbg_header_err( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_warn( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_fixme( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_header_trace( const char *dbg_channel, const char *func ) +{ + return 0; +} +int dbg_vprintf( const char *format, va_list args ) +{ + return 0; +} +int __vprintf( const char *format, ... ) +{ +#ifdef DETAILED_OUT + va_list va; + va_start(va, format); + vprintf(format, va); + va_end(va); +#endif + return 0; +} + +HANDLE WINAPI GetProcessHeap(void) +{ + return 1; +} + +LPVOID WINAPI HeapAlloc(HANDLE heap, DWORD flags, DWORD size) +{ + static int i = 5; + void* m = (flags & 0x8) ? calloc(size, 1) : malloc(size); + //printf("HeapAlloc %p %d (%d)\n", m, size, flags); + //if (--i == 0) + // abort(); + return m; +} + +WIN_BOOL WINAPI HeapFree(HANDLE heap, DWORD flags, LPVOID mem) +{ + if (mem) free(mem); + //printf("HeapFree %p\n", mem); + //if (!mem) + // abort(); + return 1; +} + +static int last_error; + +DWORD WINAPI GetLastError(void) +{ + return last_error; +} + +VOID WINAPI SetLastError(DWORD error) +{ + last_error=error; +} + +WIN_BOOL WINAPI ReadFile(HANDLE handle, LPVOID mem, DWORD size, LPDWORD result, LPOVERLAPPED flags) +{ + *result=read(handle, mem, size); + return *result; +} +INT WINAPI lstrcmpiA(LPCSTR c1, LPCSTR c2) +{ + return strcasecmp(c1,c2); +} +LPSTR WINAPI lstrcpynA(LPSTR dest, LPCSTR src, INT num) +{ + return strncpy(dest,src,num); +} +INT WINAPI lstrlenA(LPCSTR s) +{ + return strlen(s); +} +INT WINAPI lstrlenW(LPCWSTR s) +{ + int l; + if(!s) + return 0; + l=0; + while(s[l]) + l++; + return l; +} +LPSTR WINAPI lstrcpynWtoA(LPSTR dest, LPCWSTR src, INT count) +{ + LPSTR result = dest; + int moved=0; + if((dest==0) || (src==0)) + return 0; + while(moved0) + { + if (((*s1 | *s2) & 0xff00) || toupper((char)*s1) != toupper((char)*s2)) + { + + if(*s1<*s2) + return -1; + else + if(*s1>*s2) + return 1; + else + if(*s1==0) + return 0; + } + s1++; + s2++; + n--; + } + return 0; +} + +WIN_BOOL WINAPI IsBadReadPtr(LPCVOID data, UINT size) +{ + if(size==0) + return 0; + if(data==NULL) + return 1; + return 0; +} +LPSTR HEAP_strdupA(HANDLE heap, DWORD flags, LPCSTR string) +{ +// return strdup(string); + char* answ = (char*) malloc(strlen(string) + 1); + strcpy(answ, string); + return answ; +} +LPWSTR HEAP_strdupAtoW(HANDLE heap, DWORD flags, LPCSTR string) +{ + int size, i; + WCHAR* answer; + if(string==0) + return 0; + size=strlen(string); + answer = (WCHAR*) malloc(sizeof(WCHAR) * (size + 1)); + for(i=0; i<=size; i++) + answer[i]=(short)string[i]; + return answer; +} +LPSTR HEAP_strdupWtoA(HANDLE heap, DWORD flags, LPCWSTR string) +{ + int size, i; + char* answer; + if(string==0) + return 0; + size=0; + while(string[size]) + size++; + answer = (char*) malloc(size + 2); + for(i=0; i<=size; i++) + answer[i]=(char)string[i]; + return answer; +} + +/*********************************************************************** + * FILE_dommap + */ + +//#define MAP_PRIVATE +//#define MAP_SHARED +#undef MAP_ANON +LPVOID FILE_dommap( int unix_handle, LPVOID start, + DWORD size_high, DWORD size_low, + DWORD offset_high, DWORD offset_low, + int prot, int flags ) +{ + int fd = -1; + int pos; + LPVOID ret; + + if (size_high || offset_high) + printf("offsets larger than 4Gb not supported\n"); + + if (unix_handle == -1) + { +#ifdef MAP_ANON +// printf("Anonymous\n"); + flags |= MAP_ANON; +#else + static int fdzero = -1; + + if (fdzero == -1) + { + if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) + { + perror( "Cannot open /dev/zero for READ. Check permissions! error: " ); + exit(1); + } + } + fd = fdzero; +#endif /* MAP_ANON */ + /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ +#ifdef MAP_SHARED + flags &= ~MAP_SHARED; +#endif +#ifdef MAP_PRIVATE + flags |= MAP_PRIVATE; +#endif + } + else fd = unix_handle; +// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot); +// if ((ret = mmap( start, size_low, prot, +// flags, fd, offset_low )) != (LPVOID)-1) + if ((ret = mmap( start, size_low, prot, + MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1) + { +// printf("address %08x\n", *(int*)ret); +// printf("%x\n", ret); + return ret; + } + +// printf("mmap %d\n", errno); + + /* mmap() failed; if this is because the file offset is not */ + /* page-aligned (EINVAL), or because the underlying filesystem */ + /* does not support mmap() (ENOEXEC), we do it by hand. */ + + if (unix_handle == -1) return ret; + if ((errno != ENOEXEC) && (errno != EINVAL)) return ret; + if (prot & PROT_WRITE) + { + /* We cannot fake shared write mappings */ +#ifdef MAP_SHARED + if (flags & MAP_SHARED) return ret; +#endif +#ifdef MAP_PRIVATE + if (!(flags & MAP_PRIVATE)) return ret; +#endif + } +/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ + /* Reserve the memory with an anonymous mmap */ + ret = FILE_dommap( -1, start, size_high, size_low, 0, 0, + PROT_READ | PROT_WRITE, flags ); + if (ret == (LPVOID)-1) +// { +// perror( + return ret; + /* Now read in the file */ + if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1) + { + FILE_munmap( ret, size_high, size_low ); +// printf("lseek\n"); + return (LPVOID)-1; + } + read( fd, ret, size_low ); + lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ + mprotect( ret, size_low, prot ); /* Set the right protection */ +// printf("address %08x\n", *(int*)ret); + return ret; +} + + +/*********************************************************************** + * FILE_munmap + */ +int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) +{ + if (size_high) + printf("offsets larger than 4Gb not supported\n"); + return munmap( start, size_low ); +} +static int mapping_size=0; + +struct file_mapping_s; +typedef struct file_mapping_s +{ + int mapping_size; + char* name; + LPVOID handle; + struct file_mapping_s* next; + struct file_mapping_s* prev; +}file_mapping; +static file_mapping* fm=0; + + + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 + +HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr, + DWORD flProtect, + DWORD dwMaxHigh, DWORD dwMaxLow, + LPCSTR name) +{ + int hFile = (int)handle; + unsigned int len; + LPVOID answer; + int anon=0; + int mmap_access=0; + if(hFile<0) + { + anon=1; + hFile=open("/dev/zero", O_RDWR); + if(hFile<0){ + perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); + return 0; + } + } + if(!anon) + { + len=lseek(hFile, 0, SEEK_END); + lseek(hFile, 0, SEEK_SET); + } + else len=dwMaxLow; + + if(flProtect & PAGE_READONLY) + mmap_access |=PROT_READ; + else + mmap_access |=PROT_READ|PROT_WRITE; + + answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0); + if(anon) + close(hFile); + if(answer!=(LPVOID)-1) + { + if(fm==0) + { + fm = (file_mapping*) malloc(sizeof(file_mapping)); + fm->prev=NULL; + } + else + { + fm->next = (file_mapping*) malloc(sizeof(file_mapping)); + fm->next->prev=fm; + fm=fm->next; + } + fm->next=NULL; + fm->handle=answer; + if(name) + { + fm->name = (char*) malloc(strlen(name)+1); + strcpy(fm->name, name); + } + else + fm->name=NULL; + fm->mapping_size=len; + + if(anon) + close(hFile); + return (HANDLE)answer; + } + return (HANDLE)0; +} +WIN_BOOL WINAPI UnmapViewOfFile(LPVOID handle) +{ + file_mapping* p; + int result; + if(fm==0) + return 0; + for(p=fm; p; p=p->next) + { + if(p->handle==handle) + { + result=munmap((void*)handle, p->mapping_size); + if(p->next)p->next->prev=p->prev; + if(p->prev)p->prev->next=p->next; + if(p->name) + free(p->name); + if(p==fm) + fm=p->prev; + free(p); + return result; + } + } + return 0; +} +//static int va_size=0; +struct virt_alloc_s; +typedef struct virt_alloc_s +{ + int mapping_size; + char* address; + struct virt_alloc_s* next; + struct virt_alloc_s* prev; + int state; +}virt_alloc; +static virt_alloc* vm=0; +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 + +LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protection) +{ + void* answer; + int fd=open("/dev/zero", O_RDWR); + if(fd<0){ + perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); + return NULL; + } + size=(size+0xffff)&(~0xffff); + //printf("VirtualAlloc(0x%08X, %d)\n", address, size); + if(address!=0) + { + //check whether we can allow to allocate this + virt_alloc* str=vm; + while(str) + { + if((unsigned)address>=(unsigned)str->address+str->mapping_size) + { + str=str->prev; + continue; + } + if((unsigned)address+size<(unsigned)str->address) + { + str=str->prev; + continue; + } + if(str->state==0) + { +#warning FIXME + if(((unsigned)address+size<(unsigned)str->address+str->mapping_size) && (type & MEM_COMMIT)) + { + close(fd); + return address; //returning previously reserved memory + } + return NULL; + } + close(fd); + return NULL; + } + answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE, fd, 0); + } + else + answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, fd, 0); +// answer=FILE_dommap(-1, address, 0, size, 0, 0, +// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); + close(fd); + if(answer==(void*)-1) + { + printf("Error no %d\n", errno); + printf("VirtualAlloc(0x%p, %ld) failed\n", address, size); + return NULL; + } + else + { + virt_alloc *new_vm = (virt_alloc*) malloc(sizeof(virt_alloc)); + new_vm->mapping_size=size; + new_vm->address=(char*)answer; + new_vm->prev=vm; + if(type == MEM_RESERVE) + new_vm->state=0; + else + new_vm->state=1; + if(vm) + vm->next=new_vm; + vm=new_vm; + vm->next=0; + //if(va_size!=0) + // printf("Multiple VirtualAlloc!\n"); + //printf("answer=0x%08x\n", answer); + return answer; + } +} +WIN_BOOL WINAPI VirtualFree(LPVOID address, SIZE_T dwSize, DWORD dwFreeType)//not sure +{ + virt_alloc* str=vm; + int answer; + while(str) + { + if(address!=str->address) + { + str=str->prev; + continue; + } + //printf("VirtualFree(0x%08X, %d - %d)\n", str->address, dwSize, str->mapping_size); + answer=munmap(str->address, str->mapping_size); + if(str->next)str->next->prev=str->prev; + if(str->prev)str->prev->next=str->next; + if(vm==str)vm=str->prev; + free(str); + return 0; + } + return -1; +} + +INT WINAPI WideCharToMultiByte(UINT codepage, DWORD flags, LPCWSTR src, + INT srclen,LPSTR dest, INT destlen, LPCSTR defch, WIN_BOOL* used_defch) +{ + int i; + if(src==0) + return 0; + if ((srclen==-1)&&(dest==0)) return 0; + if(srclen==-1){srclen=0; while(src[srclen++]);} +// for(i=0; iprev) + { + if(p->name==0) + continue; + if(strcmp(p->name, name)==0) + return (HANDLE)p->handle; + } + return 0; +} diff --git a/linphone/win32acm/ext.h b/linphone/win32acm/ext.h new file mode 100644 index 000000000..579e85bec --- /dev/null +++ b/linphone/win32acm/ext.h @@ -0,0 +1,14 @@ +#ifndef loader_ext_h +#define loader_ext_h + +#include "wine/windef.h" + +extern LPVOID FILE_dommap( int unix_handle, LPVOID start, + DWORD size_high, DWORD size_low, + DWORD offset_high, DWORD offset_low, + int prot, int flags ); +extern int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ); +extern int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n); +extern int __vprintf( const char *format, ... ); + +#endif diff --git a/linphone/win32acm/ldt_keeper.c b/linphone/win32acm/ldt_keeper.c new file mode 100644 index 000000000..c4459844f --- /dev/null +++ b/linphone/win32acm/ldt_keeper.c @@ -0,0 +1,259 @@ +/** + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This file MUST be in main library because LDT must + * be modified before program creates first thread + * - avifile includes this file from C++ code + * and initializes it at the start of player! + * it might sound like a hack and it really is - but + * as aviplay is deconding video with more than just one + * thread currently it's necessary to do it this way + * this might change in the future + */ + +/* applied some modification to make make our xine friend more happy */ +#include "ldt_keeper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#include +// 2.5.xx+ calls this user_desc: +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47) +#define modify_ldt_ldt_s user_desc +#endif +/* prototype it here, so we won't depend on kernel headers */ +#ifdef __cplusplus +extern "C" { +#endif +int modify_ldt(int func, void *ptr, unsigned long bytecount); +#ifdef __cplusplus +} +#endif +#else +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#include +#include +#endif + +#ifdef __svr4__ +#include +#include + +/* solaris x86: add missing prototype for sysi86() */ +#ifdef __cplusplus +extern "C" { +#endif +int sysi86(int, void*); +#ifdef __cplusplus +} +#endif + +#ifndef NUMSYSLDTS /* SunOS 2.5.1 does not define NUMSYSLDTS */ +#define NUMSYSLDTS 6 /* Let's hope the SunOS 5.8 value is OK */ +#endif + +#define TEB_SEL_IDX NUMSYSLDTS +#endif + +#define LDT_ENTRIES 8192 +#define LDT_ENTRY_SIZE 8 +#pragma pack(4) +struct modify_ldt_ldt_s { + unsigned int entry_number; + unsigned long base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +}; + +#define MODIFY_LDT_CONTENTS_DATA 0 +#define MODIFY_LDT_CONTENTS_STACK 1 +#define MODIFY_LDT_CONTENTS_CODE 2 +#endif + + +/* user level (privilege level: 3) ldt (1<<2) segment selector */ +#define LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3) + +/* i got this value from wine sources, it's the first free LDT entry */ +#ifndef TEB_SEL_IDX +#define TEB_SEL_IDX 17 +#endif + +#define TEB_SEL LDT_SEL(TEB_SEL_IDX) + +/** + * here is a small logical problem with Restore for multithreaded programs - + * in C++ we use static class for this... + */ + +#ifdef __cplusplus +extern "C" +#endif +void Setup_FS_Segment(void) +{ + __asm__ __volatile__( + "movl %0,%%eax; movw %%ax, %%fs" : : "i" (TEB_SEL) + ); +} + +/* we don't need this - use modify_ldt instead */ +#if 0 +#ifdef __linux__ +/* XXX: why is this routine from libc redefined here? */ +/* NOTE: the redefined version ignores the count param, count is hardcoded as 16 */ +static int LDT_Modify( int func, struct modify_ldt_ldt_s *ptr, + unsigned long count ) +{ + int res; +#ifdef __PIC__ + __asm__ __volatile__( "pushl %%ebx\n\t" + "movl %2,%%ebx\n\t" + "int $0x80\n\t" + "popl %%ebx" + : "=a" (res) + : "0" (__NR_modify_ldt), + "r" (func), + "c" (ptr), + "d"(16)//sizeof(*ptr) from kernel point of view + :"esi" ); +#else + __asm__ __volatile__("int $0x80" + : "=a" (res) + : "0" (__NR_modify_ldt), + "b" (func), + "c" (ptr), + "d"(16) + :"esi"); +#endif /* __PIC__ */ + if (res >= 0) return res; + errno = -res; + return -1; +} +#endif +#endif + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) +{ + *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | + (content->limit & 0x0ffff); + *buffer = (content->base_addr & 0xff000000) | + ((content->base_addr & 0x00ff0000)>>16) | + (content->limit & 0xf0000) | + (content->contents << 10) | + ((content->read_exec_only == 0) << 9) | + ((content->seg_32bit != 0) << 22) | + ((content->limit_in_pages != 0) << 23) | + 0xf000; +} +#endif + +void* fs_seg=0; + +ldt_fs_t* Setup_LDT_Keeper(void) +{ + struct modify_ldt_ldt_s array; + int ret; + ldt_fs_t* ldt_fs = (ldt_fs_t*) malloc(sizeof(ldt_fs_t)); + + if (!ldt_fs) + return NULL; + + ldt_fs->fd = open("/dev/zero", O_RDWR); + if(ldt_fs->fd<0){ + perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: "); + return NULL; + } + fs_seg= + ldt_fs->fs_seg = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, + ldt_fs->fd, 0); + if (ldt_fs->fs_seg == (void*)-1) + { + perror("ERROR: Couldn't allocate memory for fs segment"); + close(ldt_fs->fd); + free(ldt_fs); + return NULL; + } + *(void**)((char*)ldt_fs->fs_seg+0x18) = ldt_fs->fs_seg; + array.base_addr=(int)ldt_fs->fs_seg; + array.entry_number=TEB_SEL_IDX; + array.limit=array.base_addr+getpagesize()-1; + array.seg_32bit=1; + array.read_exec_only=0; + array.seg_not_present=0; + array.contents=MODIFY_LDT_CONTENTS_DATA; + array.limit_in_pages=0; +#ifdef __linux__ + //ret=LDT_Modify(0x1, &array, sizeof(struct modify_ldt_ldt_s)); + ret=modify_ldt(0x1, &array, sizeof(struct modify_ldt_ldt_s)); + if(ret<0) + { + perror("install_fs"); + printf("Couldn't install fs segment, expect segfault\n"); + } +#endif /*linux*/ + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + { + unsigned long d[2]; + + LDT_EntryToBytes( d, &array ); + ret = i386_set_ldt(array.entry_number, (union descriptor *)d, 1); + if (ret < 0) + { + perror("install_fs"); + printf("Couldn't install fs segment, expect segfault\n"); + printf("Did you reconfigure the kernel with \"options USER_LDT\"?\n"); + } + } +#endif /* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */ + +#if defined(__svr4__) + { + struct ssd ssd; + ssd.sel = TEB_SEL; + ssd.bo = array.base_addr; + ssd.ls = array.limit - array.base_addr; + ssd.acc1 = ((array.read_exec_only == 0) << 1) | + (array.contents << 2) | + 0xf0; /* P(resent) | DPL3 | S */ + ssd.acc2 = 0x4; /* byte limit, 32-bit segment */ + if (sysi86(SI86DSCR, &ssd) < 0) { + perror("sysi86(SI86DSCR)"); + printf("Couldn't install fs segment, expect segfault\n"); + } + } +#endif + + Setup_FS_Segment(); + + ldt_fs->prev_struct = (char*)malloc(sizeof(char) * 8); + *(void**)array.base_addr = ldt_fs->prev_struct; + + return ldt_fs; +} + +void Restore_LDT_Keeper(ldt_fs_t* ldt_fs) +{ + if (ldt_fs == NULL || ldt_fs->fs_seg == 0) + return; + if (ldt_fs->prev_struct) + free(ldt_fs->prev_struct); + munmap((char*)ldt_fs->fs_seg, getpagesize()); + ldt_fs->fs_seg = 0; + close(ldt_fs->fd); + free(ldt_fs); +} diff --git a/linphone/win32acm/ldt_keeper.h b/linphone/win32acm/ldt_keeper.h new file mode 100644 index 000000000..d36ebb892 --- /dev/null +++ b/linphone/win32acm/ldt_keeper.h @@ -0,0 +1,22 @@ +#ifndef LDT_KEEPER_H +#define LDT_KEEPER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct { + void* fs_seg; + char* prev_struct; + int fd; +} ldt_fs_t; + +void Setup_FS_Segment(void); +ldt_fs_t* Setup_LDT_Keeper(void); +void Restore_LDT_Keeper(ldt_fs_t* ldt_fs); +#ifdef __cplusplus +} +#endif + +#endif /* LDT_KEEPER_H */ diff --git a/linphone/win32acm/loader.h b/linphone/win32acm/loader.h new file mode 100644 index 000000000..62549c3f3 --- /dev/null +++ b/linphone/win32acm/loader.h @@ -0,0 +1,35 @@ +/******************************************************** + + Win32 binary loader interface + Copyright 2000 Eugene Kuznetsov (divx@euro.ru) + Shamelessly stolen from Wine project + +*********************************************************/ + +#ifndef _LOADER_H +#define _LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wine/windef.h" +#include "wine/driver.h" +#include "wine/mmreg.h" +/*#include "wine/vfw.h" */ +#include "wine/msacm.h" + +unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename); +int _GetPrivateProfileStringA(const char* appname, const char* keyname, + const char* def_val, char* dest, unsigned int len, const char* filename); +int _WritePrivateProfileStringA(const char* appname, const char* keyname, + const char* string, const char* filename); + +INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, + LPSTR buffer, INT buflen ); + +#ifdef __cplusplus +} +#endif +#endif /* __LOADER_H */ + diff --git a/linphone/win32acm/loader_objfix.sh b/linphone/win32acm/loader_objfix.sh new file mode 100755 index 000000000..99eb27a7f --- /dev/null +++ b/linphone/win32acm/loader_objfix.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# This script fixes up symbol mangling in GNU as code of stubs.s. +# This file is licensed under the GPL, more info at http://www.fsf.org/ +for i in "export_names" \ + "printf" \ + "exp_EH_prolog" \ + "unk_exp1" +do +echo "fixing: $i=_$i" +objcopy --redefine-sym "$i=_$i" stubs.o +done diff --git a/linphone/win32acm/module.c b/linphone/win32acm/module.c new file mode 100644 index 000000000..089d8dde7 --- /dev/null +++ b/linphone/win32acm/module.c @@ -0,0 +1,993 @@ +/* + * Modules + * + * Copyright 1995 Alexandre Julliard + */ + +// define for quicktime calls debugging and/or MacOS-level emulation: +#define EMU_QTX_API + +// define for quicktime debugging (verbose logging): +//#define DEBUG_QTX_API + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/windef.h" +#include "wine/winerror.h" +#include "wine/heap.h" +#include "wine/module.h" +#include "wine/pe_image.h" +#include "wine/debugtools.h" + +#undef HAVE_LIBDL + +#ifdef HAVE_LIBDL +#include +#include "wine/elfdll.h" +#endif +#include "win32.h" +#include "driver.h" + +#ifdef EMU_QTX_API +#include "wrapper.h" +static int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); +static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); +#endif + +//#undef TRACE +//#define TRACE printf + +//WINE_MODREF *local_wm=NULL; +modref_list* local_wm=NULL; + +HANDLE SegptrHeap; + +WINE_MODREF* MODULE_FindModule(LPCSTR m) +{ + modref_list* list=local_wm; + TRACE("FindModule: Module %s request\n", m); + if(list==NULL) + return NULL; +// while(strcmp(m, list->wm->filename)) + while(!strstr(list->wm->filename, m)) + { + TRACE("%s: %x\n", list->wm->filename, list->wm->module); + list=list->prev; + if(list==NULL) + return NULL; + } + TRACE("Resolved to %s\n", list->wm->filename); + return list->wm; +} + +static void MODULE_RemoveFromList(WINE_MODREF *mod) +{ + modref_list* list=local_wm; + if(list==0) + return; + if(mod==0) + return; + if((list->prev==NULL)&&(list->next==NULL)) + { + free(list); + local_wm=NULL; +// uninstall_fs(); + return; + } + for(;list;list=list->prev) + { + if(list->wm==mod) + { + if(list->prev) + list->prev->next=list->next; + if(list->next) + list->next->prev=list->prev; + if(list==local_wm) + local_wm=list->prev; + free(list); + return; + } + } + +} + +WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m) +{ + modref_list* list=local_wm; + TRACE("LookupHMODULE: Module %X request\n", m); + if(list==NULL) + { + TRACE("LookupHMODULE failed\n"); + return NULL; + } + while(m!=list->wm->module) + { +// printf("Checking list %X wm %X module %X\n", +// list, list->wm, list->wm->module); + list=list->prev; + if(list==NULL) + { + TRACE("LookupHMODULE failed\n"); + return NULL; + } + } + TRACE("LookupHMODULE hit %p\n", list->wm); + return list->wm; +} + +/************************************************************************* + * MODULE_InitDll + */ +static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) +{ + WIN_BOOL retv = TRUE; + + static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH", + "THREAD_ATTACH", "THREAD_DETACH" }; + assert( wm ); + + + /* Skip calls for modules loaded with special load flags */ + + if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) + || ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) ) + return TRUE; + + + TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved ); + + /* Call the initialization routine */ + switch ( wm->type ) + { + case MODULE32_PE: + retv = PE_InitDLL( wm, type, lpReserved ); + break; + + case MODULE32_ELF: + /* no need to do that, dlopen() already does */ + break; + + default: + ERR("wine_modref type %d not handled.\n", wm->type ); + retv = FALSE; + break; + } + + /* The state of the module list may have changed due to the call + to PE_InitDLL. We cannot assume that this module has not been + deleted. */ + TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv ); + + return retv; +} + +/************************************************************************* + * MODULE_DllProcessAttach + * + * Send the process attach notification to all DLLs the given module + * depends on (recursively). This is somewhat complicated due to the fact that + * + * - we have to respect the module dependencies, i.e. modules implicitly + * referenced by another module have to be initialized before the module + * itself can be initialized + * + * - the initialization routine of a DLL can itself call LoadLibrary, + * thereby introducing a whole new set of dependencies (even involving + * the 'old' modules) at any time during the whole process + * + * (Note that this routine can be recursively entered not only directly + * from itself, but also via LoadLibrary from one of the called initialization + * routines.) + * + * Furthermore, we need to rearrange the main WINE_MODREF list to allow + * the process *detach* notifications to be sent in the correct order. + * This must not only take into account module dependencies, but also + * 'hidden' dependencies created by modules calling LoadLibrary in their + * attach notification routine. + * + * The strategy is rather simple: we move a WINE_MODREF to the head of the + * list after the attach notification has returned. This implies that the + * detach notifications are called in the reverse of the sequence the attach + * notifications *returned*. + * + * NOTE: Assumes that the process critical section is held! + * + */ +static WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ) +{ + WIN_BOOL retv = TRUE; + int i; + assert( wm ); + + /* prevent infinite recursion in case of cyclical dependencies */ + if ( ( wm->flags & WINE_MODREF_MARKER ) + || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) ) + return retv; + + TRACE("(%s,%p) - START\n", wm->modname, lpReserved ); + + /* Tag current MODREF to prevent recursive loop */ + wm->flags |= WINE_MODREF_MARKER; + + /* Recursively attach all DLLs this one depends on */ +/* for ( i = 0; retv && i < wm->nDeps; i++ ) + if ( wm->deps[i] ) + retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved ); +*/ + /* Call DLL entry point */ + + //local_wm=wm; + if(local_wm) + { + local_wm->next = (modref_list*) malloc(sizeof(modref_list)); + local_wm->next->prev=local_wm; + local_wm->next->next=NULL; + local_wm->next->wm=wm; + local_wm=local_wm->next; + } + else + { + local_wm = (modref_list*)malloc(sizeof(modref_list)); + local_wm->next=local_wm->prev=NULL; + local_wm->wm=wm; + } + /* Remove recursion flag */ + wm->flags &= ~WINE_MODREF_MARKER; + + if ( retv ) + { + retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved ); + if ( retv ) + wm->flags |= WINE_MODREF_PROCESS_ATTACHED; + } + + + TRACE("(%s,%p) - END\n", wm->modname, lpReserved ); + + return retv; +} + +/************************************************************************* + * MODULE_DllProcessDetach + * + * Send DLL process detach notifications. See the comment about calling + * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag + * is set, only DLLs with zero refcount are notified. + */ +static void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved ) +{ + // WINE_MODREF *wm=local_wm; + modref_list* l = local_wm; + wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED; + MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved ); +/* while (l) + { + modref_list* f = l; + l = l->next; + free(f); + } + local_wm = 0;*/ +} + +/*********************************************************************** + * MODULE_LoadLibraryExA (internal) + * + * Load a PE style module according to the load order. + * + * The HFILE parameter is not used and marked reserved in the SDK. I can + * only guess that it should force a file to be mapped, but I rather + * ignore the parameter because it would be extremely difficult to + * integrate this with different types of module represenations. + * + */ +static WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) +{ + DWORD err = GetLastError(); + WINE_MODREF *pwm; + int i; +// module_loadorder_t *plo; + + SetLastError( ERROR_FILE_NOT_FOUND ); + TRACE("Trying native dll '%s'\n", libname); + pwm = PE_LoadLibraryExA(libname, flags); +#ifdef HAVE_LIBDL + if(!pwm) + { + TRACE("Trying ELF dll '%s'\n", libname); + pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags); + } +#endif +// printf("0x%08x\n", pwm); +// break; + if(pwm) + { + /* Initialize DLL just loaded */ + TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module); + /* Set the refCount here so that an attach failure will */ + /* decrement the dependencies through the MODULE_FreeLibrary call. */ + pwm->refCount++; + + SetLastError( err ); /* restore last error */ + return pwm; + } + + + WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError()); + return NULL; +} + +/*********************************************************************** + * MODULE_FreeLibrary + * + * NOTE: Assumes that the process critical section is held! + */ +static WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) +{ + TRACE("(%s) - START\n", wm->modname ); + + /* Recursively decrement reference counts */ + //MODULE_DecRefCount( wm ); + + /* Call process detach notifications */ + MODULE_DllProcessDetach( wm, FALSE, NULL ); + + PE_UnloadLibrary(wm); + + TRACE("END\n"); + + return TRUE; +} + +/*********************************************************************** + * LoadLibraryExA (KERNEL32) + */ +HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) +{ + WINE_MODREF *wm = 0; + char* listpath[] = { "", "", "/usr/lib/win32", "/usr/local/lib/win32", 0 }; + extern char* def_path; + char path[512]; + char checked[2000]; + int i = -1; + + checked[0] = 0; + if(!libname) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + wm=MODULE_FindModule(libname); + if(wm) return wm->module; + +// if(fs_installed==0) +// install_fs(); + + while (wm == 0 && listpath[++i]) + { + if (i < 2) + { + if (i == 0) + /* check just original file name */ + strncpy(path, libname, 511); + else + /* check default user path */ + strncpy(path, def_path, 300); + } + else if (strcmp(def_path, listpath[i])) + /* path from the list */ + strncpy(path, listpath[i], 300); + else + continue; + + if (i > 0) + { + strcat(path, "/"); + strncat(path, libname, 100); + } + path[511] = 0; + wm = MODULE_LoadLibraryExA( path, hfile, flags ); + + if (!wm) + { + if (checked[0]) + strcat(checked, ", "); + strcat(checked, path); + checked[1500] = 0; + + } + } + if ( wm ) + { + if ( !MODULE_DllProcessAttach( wm, NULL ) ) + { + WARN_(module)("Attach failed for module '%s', \n", libname); + MODULE_FreeLibrary(wm); + SetLastError(ERROR_DLL_INIT_FAILED); + MODULE_RemoveFromList(wm); + wm = NULL; + } + } + + if (!wm) + printf("Win32 LoadLibrary failed to load: %s\n", checked); + + if (strstr(libname,"QuickTime.qts") && wm) + { + void** ptr; + void *dispatch_addr; + int i; + +// dispatch_addr = GetProcAddress(wm->module, "theQuickTimeDispatcher", TRUE); + dispatch_addr = PE_FindExportedFunction(wm, "theQuickTimeDispatcher", TRUE); + if (dispatch_addr == (void *)0x62924c30) + { + fprintf(stderr, "QuickTime5 DLLs found\n"); + ptr = (void **)0x62b75ca4; // dispatch_ptr + for (i=0;i<5;i++) ((char*)0x6299e842)[i]=0x90; // make_new_region ? + for (i=0;i<28;i++) ((char*)0x6299e86d)[i]=0x90; // call__call_CreateCompatibleDC ? + for (i=0;i<5;i++) ((char*)0x6299e898)[i]=0x90; // jmp_to_call_loadbitmap ? + for (i=0;i<9;i++) ((char*)0x6299e8ac)[i]=0x90; // call__calls_OLE_shit ? + for (i=0;i<106;i++) ((char*)0x62a61b10)[i]=0x90; // disable threads +#if 0 + /* CreateThread callers */ + for (i=0;i<5;i++) ((char*)0x629487c5)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x6294b275)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x629a24b1)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x629afc5a)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x62af799c)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x62af7efe)[i]=0x90; + for (i=0;i<5;i++) ((char*)0x62afa33e)[i]=0x90; +#endif + +#if 0 + /* TerminateQTML fix */ + for (i=0;i<47;i++) ((char*)0x62afa3b8)[i]=0x90; // terminate thread + for (i=0;i<47;i++) ((char*)0x62af7f78)[i]=0x90; // terminate thread + for (i=0;i<77;i++) ((char*)0x629a13d5)[i]=0x90; + ((char *)0x6288e0ae)[0] = 0xc3; // font/dc remover + for (i=0;i<24;i++) ((char*)0x6287a1ad)[i]=0x90; // destroy window +#endif + } else if (dispatch_addr == (void *)0x6693b330) + { + fprintf(stderr, "QuickTime6 DLLs found\n"); + ptr = (void **)0x66bb9524; // dispatcher_ptr + for (i=0;i<5;i++) ((char *)0x66a730cc)[i]=0x90; // make_new_region + for (i=0;i<28;i++) ((char *)0x66a730f7)[i]=0x90; // call__call_CreateCompatibleDC + for (i=0;i<5;i++) ((char *)0x66a73122)[i]=0x90; // jmp_to_call_loadbitmap + for (i=0;i<9;i++) ((char *)0x66a73131)[i]=0x90; // call__calls_OLE_shit + for (i=0;i<96;i++) ((char *)0x66aac852)[i]=0x90; // disable threads + } else + { + fprintf(stderr, "Unsupported QuickTime version (%p)\n", + dispatch_addr); + return 0; + } + + fprintf(stderr,"QuickTime.qts patched!!! old entry=%p\n",ptr[0]); + +#ifdef EMU_QTX_API + report_entry = report_func; + report_ret = report_func_ret; + wrapper_target=ptr[0]; + ptr[0]=wrapper; +#endif + } + + return wm ? wm->module : 0; +} + + +/*********************************************************************** + * LoadLibraryA (KERNEL32) + */ +HMODULE WINAPI LoadLibraryA(LPCSTR libname) { + return LoadLibraryExA(libname,0,0); +} + +/*********************************************************************** + * FreeLibrary + */ +WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) +{ + WIN_BOOL retv = FALSE; + WINE_MODREF *wm; + + wm=MODULE32_LookupHMODULE(hLibModule); + + if ( !wm || !hLibModule ) + { + SetLastError( ERROR_INVALID_HANDLE ); + return 0; + } + else + retv = MODULE_FreeLibrary( wm ); + + MODULE_RemoveFromList(wm); + + /* garbage... */ + if (local_wm == NULL) my_garbagecollection(); + + return retv; +} + +/*********************************************************************** + * MODULE_DecRefCount + * + * NOTE: Assumes that the process critical section is held! + */ +static void MODULE_DecRefCount( WINE_MODREF *wm ) +{ + int i; + + if ( wm->flags & WINE_MODREF_MARKER ) + return; + + if ( wm->refCount <= 0 ) + return; + + --wm->refCount; + TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount ); + + if ( wm->refCount == 0 ) + { + wm->flags |= WINE_MODREF_MARKER; + + for ( i = 0; i < wm->nDeps; i++ ) + if ( wm->deps[i] ) + MODULE_DecRefCount( wm->deps[i] ); + + wm->flags &= ~WINE_MODREF_MARKER; + } +} + +/*********************************************************************** + * GetProcAddress (KERNEL32.257) + */ +FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) +{ + return MODULE_GetProcAddress( hModule, function, TRUE ); +} + +#ifdef DEBUG_QTX_API + +struct ComponentParameters { + unsigned char flags; /* call modifiers: sync/async, deferred, immed, etc */ + unsigned char paramSize; /* size in bytes of actual parameters passed to this call */ + short what; /* routine selector, negative for Component management calls */ + long params[1]; /* actual parameters for the indicated routine */ +}; +typedef struct ComponentParameters ComponentParameters; + +static char* component_func(int what){ +switch(what){ +case -1: return "kComponentOpenSelect"; +case -2: return "kComponentCloseSelect"; +case -3: return "kComponentCanDoSelect"; +case -4: return "kComponentVersionSelect"; +case -5: return "kComponentRegisterSelect"; +case -6: return "kComponentTargetSelect"; +case -7: return "kComponentUnregisterSelect"; +} +return "???"; +} + +static char* component_func_type(int type,int what){ +if(type==1) switch(what){ +case 0: return "kImageCodecGetCodecInfoSelect"; +case 1: return "kImageCodecGetCompressionTimeSelect"; +case 5: return "kImageCodecPreDecompressSelect"; +case 6: return "kImageCodecBandDecompressSelect"; +case 0x12: return "kImageCodecDisposeMemorySelect"; +case 0x10: return "kImageCodecIsImageDescriptionEquivalentSelect"; +case 0x14: return "kImageCodecNewImageBufferMemorySelect"; +case 0x28: return "kImageCodecRequestGammaLevelSelect"; +} +return "???"; +} + + +static int c_level=0; + +static int dump_component(char* name,int type,void* _orig, ComponentParameters *params,void** glob){ + int ( *orig)(ComponentParameters *params, void** glob) = _orig; + int ret,i; + + if(params->what<0) + fprintf(stderr,"%*sComponentCall: %s flags=0x%X size=%d what=%d %s\n",3*c_level,"",name,params->flags, params->paramSize, params->what, component_func(params->what)); + else + fprintf(stderr,"%*sComponentCall: %s flags=0x%X size=%d what=0x%X %s\n",3*c_level,"",name,params->flags, params->paramSize, params->what, component_func_type(type,params->what)); + + for(i=0;iparamSize/4;i++) + fprintf(stderr,"%*s param[%d] = 0x%X\n",3*c_level,"",i,params->params[i]); + + ++c_level; + ret=orig(params,glob); + --c_level; + + if(ret>=0x1000) + fprintf(stderr,"%*s return=0x%X\n",3*c_level,"",ret); + else + fprintf(stderr,"%*s return=%d\n",3*c_level,"",ret); + return ret; +} + +#define DECL_COMPONENT(sname,name,type) \ + static void* real_ ## sname = NULL; \ + static int fake_ ## sname(ComponentParameters *params,void** glob){ \ + return dump_component(name,type,real_ ## sname, params, glob); \ + } + +#include "qt_comp.h" + +#undef DECL_COMPONENT + +#include "qt_fv.h" + +#endif + +#ifdef EMU_QTX_API + +static u_int32_t ret_array[4096]; +static int ret_i=0; + +static int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) +{ +#ifdef DEBUG_QTX_API + int i; + int* dptr; + void* pwrapper=NULL; + void* pptr=NULL; + char* pname=NULL; + int plen=-1; + // find the code: + + dptr=0x62b67ae0;dptr+=2*((reg->eax>>16)&255); +// printf("FUNC: flag=%d ptr=%p\n",dptr[0],dptr[1]); + if(dptr[0]&255){ + dptr=dptr[1];dptr+=4*(reg->eax&65535); +// printf("FUNC: ptr2=%p eax=%p edx=%p\n",dptr[1],dptr[0],dptr[2]); + pwrapper=dptr[1]; pptr=dptr[0]; plen=dptr[2]; + } else { + pwrapper=0x62924910; + switch(dptr[1]){ + case 0x629248d0: + dptr=0x62b672c0;dptr+=2*(reg->eax&65535); +// printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); + pptr=dptr[0]; plen=dptr[1]; + break; + case 0x62924e40: + dptr=0x62b67c70;dptr+=2*(reg->eax&65535); +// printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); + pptr=dptr[0]; plen=dptr[1]; + break; + case 0x62924e60: + dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535); +// printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); + pptr=dptr[0]; plen=dptr[1]; + break; + case 0x62924e80: + dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535); +// printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); + pptr=dptr[0]; plen=dptr[1]; + break; + default: + printf("FUNC: unknown ptr & psize!\n"); + pwrapper=dptr[1]; + } + } + + for(i=0;qt_fv_list[i].name;i++){ + if(qt_fv_list[i].id==reg->eax){ + pname=qt_fv_list[i].name; + break; + } + } + + printf("FUNC[%X/%s]: wrapper=%p func=%p len=%d\n",reg->eax, + pname?pname:"???",pwrapper,pptr,plen); + + printf("FUNC: caller=%p ebx=%p\n",((u_int32_t *)stack_base)[0],reg->ebx); + + if(pname) + printf("%*sENTER(%d): %s(",ret_i*2,"",ret_i,pname); + else + printf("%*sENTER(%d): %X(",ret_i*2,"",ret_i,reg->eax); + for (i=0;i=0x20 && fcc[0]<128 && + fcc[1]>=0x20 && fcc[1]<128 && + fcc[2]>=0x20 && fcc[2]<128 && + fcc[3]>=0x20 && fcc[3]<128) printf("='%c%c%c%c'",fcc[3],fcc[2],fcc[1],fcc[0]); + else if(val>=8 && val<65536) printf("=%d",val); + } + printf(")\n"); + fflush(stdout); + +#endif + +#if 1 + // emulate some functions: + switch(reg->eax){ + // memory management: + case 0x150011: //NewPtrClear + case 0x150012: //NewPtrSysClear + reg->eax=(u_int32_t)malloc(((u_int32_t *)stack_base)[1]); + memset((void *)reg->eax,0,((u_int32_t *)stack_base)[1]); +#ifdef DEBUG_QTX_API + printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); +#endif + return 1; + case 0x15000F: //NewPtr + case 0x150010: //NewPtrSys + reg->eax=(u_int32_t)malloc(((u_int32_t *)stack_base)[1]); +#ifdef DEBUG_QTX_API + printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); +#endif + return 1; + case 0x15002f: //DisposePtr + if(((u_int32_t *)stack_base)[1]>=0x60000000) + printf("WARNING! Invalid Ptr handle!\n"); + else + free((void *)((u_int32_t *)stack_base)[1]); + reg->eax=0; +#ifdef DEBUG_QTX_API + printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); +#endif + return 1; + // mutexes: + case 0x1d0033: //QTMLCreateMutex + reg->eax=0xdeadbabe; +#ifdef DEBUG_QTX_API + printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); +#endif + return 1; + case 0x1d0034: //QTMLDestroyMutex + case 0x1d0035: //QTMLGrabMutex + case 0x1d0036: //QTMLReturnMutex + case 0x1d003d: //QTMLTryGrabMutex + reg->eax=0; +#ifdef DEBUG_QTX_API + printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); +#endif + return 1; + } +#endif + +#if 0 + switch(reg->eax){ +// case 0x00010000: +// printf("FUNC: ImageCodecInitialize/ImageCodecGetCodecInfo(ci=%p,&icap=%p)\n",((u_int32_t *)stack_base)[1],((u_int32_t *)stack_base)[4]); +// break; + case 0x00010003: + printf("FUNC: CountComponents(&desc=%p)\n",((u_int32_t *)stack_base)[1]); + break; + case 0x00010004: + printf("FUNC: FindNextComponent(prev=%p,&desc=%p)\n",((u_int32_t *)stack_base)[1],((u_int32_t *)stack_base)[2]); + break; + case 0x00010007: + printf("FUNC: OpenComponent(prev=%p)\n",((u_int32_t *)stack_base)[1]); + break; + case 0x0003008b: + printf("FUNC: QTNewGWorldFromPtr(&pts=%p,fourcc=%.4s,&rect=%p,x1=%p,x2=%p,x3=%p,plane=%p,stride=%d)\n", + ((u_int32_t *)stack_base)[1], + &(((u_int32_t *)stack_base)[2]), + ((u_int32_t *)stack_base)[3], + ((u_int32_t *)stack_base)[4], + ((u_int32_t *)stack_base)[5], + ((u_int32_t *)stack_base)[6], + ((u_int32_t *)stack_base)[7], + ((u_int32_t *)stack_base)[8]); + break; + case 0x001c0018: + printf("FUNC: GetGWorldPixMap(gworld=%p)\n",((u_int32_t *)stack_base)[1]); + break; + case 0x00110001: + printf("FUNC: Gestalt(fourcc=%.4s, &ret=%p)\n",&(((u_int32_t *)stack_base)[1]),((u_int32_t *)stack_base)[2]); + break; + default: { + int i; + for(i=0;qt_fv_list[i].name;i++){ + if(qt_fv_list[i].id==reg->eax){ + printf("FUNC: %s\n",qt_fv_list[i].name); + break; + } + } + } + } + + // print stack/reg information + printf("ENTER(%d) stack = %d bytes @ %p\n" + "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n" + "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n" + "flags = 0x%08x\n", ret_i, + stack_size, stack_base, + reg->eax, reg->edx, reg->ebx, reg->ecx, + reg->esp, reg->ebp, reg->esi, reg->edi, + *flags); +#endif + + // save ret addr: + ret_array[ret_i]=((u_int32_t *)stack_base)[0]; + ++ret_i; + +#if 0 + // print first 7 longs in the stack (return address, arg[1], arg[2] ... ) + printf("stack[] = { "); + for (i=0;i<7;i++) { + printf("%08x ", ((u_int32_t *)stack_base)[i]); + } + printf("}\n\n"); +#endif + +// // mess with function parameters +// ((u_int32_t *)stack_base)[1] = 0x66554433; + +// // mess with return address... +// reg->eax = 0x11223344; + return 0; +} + +static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) +{ + int i; + short err; + + // restore ret addr: + --ret_i; + ((u_int32_t *)stack_base)[0]=ret_array[ret_i]; + +#ifdef DEBUG_QTX_API + +#if 1 + printf("%*sLEAVE(%d): 0x%X",ret_i*2,"",ret_i, reg->eax); + err=reg->eax; + if(err && (reg->eax>>16)==0) printf(" = %d",err); + printf("\n"); + fflush(stdout); +#else + // print stack/reg information + printf("LEAVE(%d) stack = %d bytes @ %p\n" + "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n" + "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n" + "flags = 0x%08x\n", ret_i, + stack_size, stack_base, + reg->eax, reg->edx, reg->ebx, reg->ecx, + reg->esp, reg->ebp, reg->esi, reg->edi, + *flags); +#endif + +#if 0 + // print first 7 longs in the stack (return address, arg[1], arg[2] ... ) + printf("stack[] = { "); + for (i=0;i<7;i++) { + printf("%08x ", ((u_int32_t *)stack_base)[i]); + } + printf("}\n\n"); +#endif + +#endif + +// // mess with function parameters +// ((u_int32_t *)stack_base)[1] = 0x66554433; + +// // mess with return address... +// reg->eax = 0x11223344; + return 0; +} + +#endif + +/*********************************************************************** + * MODULE_GetProcAddress (internal) + */ +FARPROC MODULE_GetProcAddress( + HMODULE hModule, /* [in] current module handle */ + LPCSTR function, /* [in] function to be looked up */ + WIN_BOOL snoop ) +{ + WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); +// WINE_MODREF *wm=local_wm; + FARPROC retproc; + +#ifdef DEBUG_QTX_API + if (HIWORD(function)) + fprintf(stderr,"XXX GetProcAddress(%08lx,%s)\n",(DWORD)hModule,function); + else + fprintf(stderr,"XXX GetProcAddress(%08lx,%p)\n",(DWORD)hModule,function); +#endif + +// TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function); +// else +// TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function); + + if (!wm) { + SetLastError(ERROR_INVALID_HANDLE); + return (FARPROC)0; + } + switch (wm->type) + { + case MODULE32_PE: + retproc = PE_FindExportedFunction( wm, function, snoop ); + if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); + break; +#ifdef HAVE_LIBDL + case MODULE32_ELF: + retproc = (FARPROC) dlsym( (void*) wm->module, function); + if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); + return retproc; +#endif + default: + ERR("wine_modref type %d not handled.\n",wm->type); + SetLastError(ERROR_INVALID_HANDLE); + return (FARPROC)0; + } + +#ifdef EMU_QTX_API + if (HIWORD(function) && retproc){ + +#ifdef DEBUG_QTX_API +#define DECL_COMPONENT(sname,name,type) \ + if(!strcmp(function,name)){ \ + fprintf(stderr,name "dispatcher catched -> %p\n",retproc); \ + real_ ## sname = retproc; retproc = fake_ ## sname; \ + } +#include "qt_comp.h" +#undef DECL_COMPONENT +#endif + + if(!strcmp(function,"theQuickTimeDispatcher") +// || !strcmp(function,"_CallComponentFunctionWithStorage") +// || !strcmp(function,"_CallComponent") + ){ + fprintf(stderr,"theQuickTimeDispatcher catched -> %p\n",retproc); + report_entry = report_func; + report_ret = report_func_ret; + wrapper_target=retproc; + retproc=(FARPROC)wrapper; + } + + } +#endif + + return retproc; +} + +static int acounter = 0; +void CodecAlloc(void) +{ + acounter++; + //printf("**************CODEC ALLOC %d\n", acounter); +} + +void CodecRelease(void) +{ + acounter--; + //printf("**************CODEC RELEASE %d\n", acounter); + if (acounter == 0) + { + for (;;) + { + modref_list* list = local_wm; + if (!local_wm) + break; + //printf("CODECRELEASE %p\n", list); + MODULE_FreeLibrary(list->wm); + MODULE_RemoveFromList(list->wm); + if (local_wm == NULL) + my_garbagecollection(); + } + } +} diff --git a/linphone/win32acm/mp_msg.c b/linphone/win32acm/mp_msg.c new file mode 100644 index 000000000..fdf6d363e --- /dev/null +++ b/linphone/win32acm/mp_msg.c @@ -0,0 +1,174 @@ + +//#define MSG_USE_COLORS + +#include +#include +#include + +#include "config.h" + +#if defined(FOR_MENCODER) || defined(CODECS2HTML) +#undef ENABLE_GUI_CODE +#elif defined(HAVE_NEW_GUI) +#define ENABLE_GUI_CODE HAVE_NEW_GUI +#else +#undef ENABLE_GUI_CODE +#endif + +#if ENABLE_GUI_CODE +#include "Gui/mplayer/widgets.h" +extern void gtkMessageBox( int type,char * str ); +extern int use_gui; +#endif +#include "mp_msg.h" + +/* maximum message length of mp_msg */ +#define MSGSIZE_MAX 3072 + +static int mp_msg_levels[MSGT_MAX]; // verbose level of this module + +#if 1 + +void mp_msg_init(){ +#ifdef USE_I18N + fprintf(stdout, "Using GNU internationalization\n"); + fprintf(stdout, "Original domain: %s\n", textdomain(NULL)); + fprintf(stdout, "Original dirname: %s\n", bindtextdomain(textdomain(NULL),NULL)); + setlocale(LC_ALL, ""); /* set from the environment variables */ + bindtextdomain("mplayer", PREFIX"/share/locale"); + textdomain("mplayer"); + fprintf(stdout, "Current domain: %s\n", textdomain(NULL)); + fprintf(stdout, "Current dirname: %s\n", bindtextdomain(textdomain(NULL),NULL)); +#endif + mp_msg_set_level(MSGL_STATUS); +} + +void mp_msg_set_level(int verbose){ + int i; + for(i=0;imp_msg_levels[x>>8]) return; // do not display + va_start(va, format); + vsnprintf(tmp, MSGSIZE_MAX, mp_gettext(format), va); + va_end(va); + tmp[MSGSIZE_MAX-1] = 0; + +#if ENABLE_GUI_CODE + if(use_gui) + { + switch(x & 255) + { + case MSGL_FATAL: + gtkMessageBox(GTK_MB_FATAL|GTK_MB_SIMPLE, tmp); + break; + case MSGL_ERR: + gtkMessageBox(GTK_MB_ERROR|GTK_MB_SIMPLE, tmp); + break; +#if 0 +// WARNING! Do NOT enable this! There are too many non-critical messages with +// MSGL_WARN, for example: broken SPU packets, codec's bit error messages, +// etc etc, they should not raise up a new window every time. + case MSGL_WARN: + gtkMessageBox(GTK_MB_WARNING|GTK_MB_SIMPLE, tmp); + break; +#endif + } + } +#endif + +#ifdef MSG_USE_COLORS +#if 1 + { int c; + static int flag=1; + if(flag) + for(c=0;c<16;c++) + printf("\033[%d;3%dm*** COLOR TEST %d ***\n",(c>7),c&7,c); + flag=0; + } +#endif + { unsigned char v_colors[10]={9,9,11,14,15,7,6,5,5,5}; + int c=v_colors[(x & 255)]; + fprintf(((x & 255) <= MSGL_WARN)?stderr:stdout, "\033[%d;3%dm",(c>7),c&7); + } +#endif + if ((x & 255) <= MSGL_WARN){ + fprintf(stderr, "%s", tmp);fflush(stderr); + } else { + printf("%s", tmp);fflush(stdout); + } + +#else + va_list va; + if((x&255)>mp_msg_levels[x>>8]) return; // do not display + va_start(va, format); +#if ENABLE_GUI_CODE + if(use_gui){ + char tmp[16*80]; + vsnprintf( tmp,8*80,format,va ); tmp[8*80-1]=0; + switch( x&255 ) { + case MSGL_FATAL: + fprintf( stderr,"%s",tmp ); + fflush(stderr); + gtkMessageBox( GTK_MB_FATAL|GTK_MB_SIMPLE,tmp ); + break; + case MSGL_ERR: + fprintf( stderr,"%s",tmp ); + fflush(stderr); + gtkMessageBox( GTK_MB_ERROR|GTK_MB_SIMPLE,tmp ); + break; + case MSGL_WARN: + fprintf( stderr, "%s",tmp ); + fflush(stdout); + gtkMessageBox( GTK_MB_WARNING|GTK_MB_SIMPLE,tmp ); + break; + default: + fprintf(stderr, "%s",tmp ); + fflush(stdout); + } + } else +#endif + if((x&255)<=MSGL_ERR){ +// fprintf(stderr,"%%%%%% "); + vfprintf(stderr,format, va); + fflush(stderr); + } else { +// printf("%%%%%% "); + vfprintf(stderr,format, va); + fflush(stdout); + } + va_end(va); +#endif +} + +#else + +FILE *mp_msg_file[MSGT_MAX]; // print message to this file (can be stdout/err) +static FILE* mp_msg_last_file=NULL; + +// how to handle errors->stderr messages->stdout ? +void mp_msg( int x, const char *format, ... ){ + if((x&255)>mp_msg_levels[x>>8] || !mp_msg_file[x>>8]) return; // do not display + va_list va; + va_start(va, format); + vfprintf(mp_msg_file[x>>8],format, va); + if(mp_msg_last_file!=mp_msg_file[x>>8]){ + fflush(mp_msg_file[x>>8]); + mp_msg_last_file=mp_msg_file[x>>8]; + } + va_end(va); +} + +#endif diff --git a/linphone/win32acm/mp_msg.h b/linphone/win32acm/mp_msg.h new file mode 100644 index 000000000..c8ab0da6c --- /dev/null +++ b/linphone/win32acm/mp_msg.h @@ -0,0 +1,131 @@ + +#ifndef _MP_MSG_H +#define _MP_MSG_H + +extern int verbose; // defined in mplayer.c + +// verbosity elevel: + +// stuff from level MSGL_FATAL-MSGL_HINT should be translated. + +#define MSGL_FATAL 0 // will exit/abort +#define MSGL_ERR 1 // continues +#define MSGL_WARN 2 // only warning +#define MSGL_HINT 3 // short help message +#define MSGL_INFO 4 // -quiet +#define MSGL_STATUS 5 // v=0 +#define MSGL_V 6 // v=1 +#define MSGL_DBG2 7 // v=2 +#define MSGL_DBG3 8 // v=3 +#define MSGL_DBG4 9 // v=4 + +// code/module: + +#define MSGT_GLOBAL 0 // common player stuff errors +#define MSGT_CPLAYER 1 // console player (mplayer.c) +#define MSGT_GPLAYER 2 // gui player + +#define MSGT_VO 3 // libvo +#define MSGT_AO 4 // libao + +#define MSGT_DEMUXER 5 // demuxer.c (general stuff) +#define MSGT_DS 6 // demux stream (add/read packet etc) +#define MSGT_DEMUX 7 // fileformat-specific stuff (demux_*.c) +#define MSGT_HEADER 8 // fileformat-specific header (*header.c) + +#define MSGT_AVSYNC 9 // mplayer.c timer stuff +#define MSGT_AUTOQ 10 // mplayer.c auto-quality stuff + +#define MSGT_CFGPARSER 11 // cfgparser.c + +#define MSGT_DECAUDIO 12 // av decoder +#define MSGT_DECVIDEO 13 + +#define MSGT_SEEK 14 // seeking code +#define MSGT_WIN32 15 // win32 dll stuff +#define MSGT_OPEN 16 // open.c (stream opening) +#define MSGT_DVD 17 // open.c (DVD init/read/seek) + +#define MSGT_PARSEES 18 // parse_es.c (mpeg stream parser) +#define MSGT_LIRC 19 // lirc_mp.c and input lirc driver + +#define MSGT_STREAM 20 // stream.c +#define MSGT_CACHE 21 // cache2.c + +#define MSGT_MENCODER 22 + +#define MSGT_XACODEC 23 // XAnim codecs + +#define MSGT_TV 24 // TV input subsystem + +#define MSGT_OSDEP 25 // OS Dependant parts (linux/ for now) + +#define MSGT_SPUDEC 26 // spudec.c + +#define MSGT_PLAYTREE 27 // Playtree handeling (playtree.c, playtreeparser.c) + +#define MSGT_INPUT 28 + +#define MSGT_VFILTER 29 + +#define MSGT_OSD 30 + +#define MSGT_NETWORK 31 + +#define MSGT_CPUDETECT 32 + +#define MSGT_CODECCFG 33 + +#define MSGT_SWS 34 + +#define MSGT_VOBSUB 35 +#define MSGT_SUBREADER 36 + +#define MSGT_AFILTER 37 // Audio filter messages + +#define MSGT_MAX 64 + +void mp_msg_init(); +void mp_msg_set_level(int verbose); +int mp_msg_test(int mod, int lev); + +#include "config.h" + +#ifdef TARGET_OS2 +// va_start/vsnprintf seems to be broken under OS2 :( +#define mp_msg(mod,lev, fmt, args... ) do{if((lev)<=mp_msg_levels[mod]) printf( fmt, ## args );}while(0) +#define mp_dbg(mod,lev, args... ) +#else + +#ifdef USE_I18N +#include +#include +#define mp_gettext(String) gettext(String) +#else +#define mp_gettext(String) String +#endif + +void mp_msg_c( int x, const char *format, ... ); + +#ifdef __GNUC__ +#define mp_msg(mod,lev, args... ) mp_msg_c(((mod)<<8)|(lev), ## args ) + +#ifdef MP_DEBUG +#define mp_dbg(mod,lev, args... ) mp_msg_c(((mod)<<8)|(lev), ## args ) +#else +// these messages are only usefull for developers, disable them +#define mp_dbg(mod,lev, args... ) +#endif +#else // not GNU C +#define mp_msg(mod,lev, ... ) mp_msg_c(((mod)<<8)|(lev), __VA_ARGS__) + +#ifdef MP_DEBUG +#define mp_dbg(mod,lev, ... ) mp_msg_c(((mod)<<8)|(lev), __VA_ARGS__) +#else +// these messages are only usefull for developers, disable them +#define mp_dbg(mod,lev, ... ) +#endif +#endif + +#endif +#endif diff --git a/linphone/win32acm/pcmin.raw b/linphone/win32acm/pcmin.raw new file mode 100644 index 0000000000000000000000000000000000000000..731338ac25ba9d880fb24b8c965eeb70158bfea4 GIT binary patch literal 128000 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 literal 0 HcmV?d00001 diff --git a/linphone/win32acm/pe_image.c b/linphone/win32acm/pe_image.c new file mode 100644 index 000000000..9ac40ebeb --- /dev/null +++ b/linphone/win32acm/pe_image.c @@ -0,0 +1,964 @@ +/* + * Copyright 1994 Eric Youndale & Erik Bos + * Copyright 1995 Martin von Löwis + * Copyright 1996-98 Marcus Meissner + * + * based on Eric Youndale's pe-test and: + * + * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP + * make that: + * ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP + */ +/* Notes: + * Before you start changing something in this file be aware of the following: + * + * - There are several functions called recursively. In a very subtle and + * obscure way. DLLs can reference each other recursively etc. + * - If you want to enhance, speed up or clean up something in here, think + * twice WHY it is implemented in that strange way. There is usually a reason. + * Though sometimes it might just be lazyness ;) + * - In PE_MapImage, right before fixup_imports() all external and internal + * state MUST be correct since this function can be called with the SAME image + * AGAIN. (Thats recursion for you.) That means MODREF.module and + * NE_MODULE.module32. + * - Sometimes, we can't use Linux mmap() to mmap() the images directly. + * + * The problem is, that there is not direct 1:1 mapping from a diskimage and + * a memoryimage. The headers at the start are mapped linear, but the sections + * are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte + * aligned in memory. Linux likes them 4096 byte aligned in memory (due to + * x86 pagesize, this cannot be fixed without a rather large kernel rewrite) + * and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM) + * and other byte blocksizes, we can't always do this. We *can* do this for + * newer pe binaries produced by MSVC 5 and later, since they are also aligned + * to 4096 byte boundaries on disk. + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include "wine/windef.h" +#include "wine/winbase.h" +#include "wine/winerror.h" +#include "wine/heap.h" +#include "wine/pe_image.h" +#include "wine/module.h" +#include "wine/debugtools.h" +#include "ext.h" +#include "win32.h" + +#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x))) + +#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta)) + +extern void* LookupExternal(const char* library, int ordinal); +extern void* LookupExternalByName(const char* library, const char* name); + +static void dump_exports( HMODULE hModule ) +{ + char *Module; + unsigned int i, j; + u_short *ordinal; + u_long *function,*functions; + u_char **name; + unsigned int load_addr = hModule; + + DWORD rva_start = PE_HEADER(hModule)->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start); + + Module = (char*)RVA(pe_exports->Name); + TRACE("*******EXPORT DATA*******\n"); + TRACE("Module name is %s, %ld functions, %ld names\n", + Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames); + + ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals); + functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions); + name=(u_char**) RVA(pe_exports->AddressOfNames); + + TRACE(" Ord RVA Addr Name\n" ); + for (i=0;iNumberOfFunctions;i++, function++) + { + if (!*function) continue; + if (TRACE_ON(win32)) + { + DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) ); + + for (j = 0; j < pe_exports->NumberOfNames; j++) + if (ordinal[j] == i) + { + DPRINTF( " %s", (char*)RVA(name[j]) ); + break; + } + if ((*function >= rva_start) && (*function <= rva_end)) + DPRINTF(" (forwarded -> %s)", (char *)RVA(*function)); + DPRINTF("\n"); + } + } +} + +/* Look up the specified function or ordinal in the exportlist: + * If it is a string: + * - look up the name in the Name list. + * - look up the ordinal with that index. + * - use the ordinal as offset into the functionlist + * If it is a ordinal: + * - use ordinal-pe_export->Base as offset into the functionlist + */ +FARPROC PE_FindExportedFunction( + WINE_MODREF *wm, + LPCSTR funcName, + WIN_BOOL snoop ) +{ + u_short * ordinals; + u_long * function; + u_char ** name; + const char *ename = NULL; + int i, ordinal; + PE_MODREF *pem = &(wm->binfmt.pe); + IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export; + unsigned int load_addr = wm->module; + u_long rva_start, rva_end, addr; + char * forward; + + if (HIWORD(funcName)) + TRACE("(%s)\n",funcName); + else + TRACE("(%d)\n",(int)funcName); + if (!exports) { + /* Not a fatal problem, some apps do + * GetProcAddress(0,"RegisterPenApp") which triggers this + * case. + */ + WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem); + return NULL; + } + ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals); + function= (u_long*) RVA(exports->AddressOfFunctions); + name = (u_char **) RVA(exports->AddressOfNames); + forward = NULL; + rva_start = PE_HEADER(wm->module)->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + + if (HIWORD(funcName)) + { + + int min = 0, max = exports->NumberOfNames - 1; + while (min <= max) + { + int res, pos = (min + max) / 2; + ename = (const char*) RVA(name[pos]); + if (!(res = strcmp( ename, funcName ))) + { + ordinal = ordinals[pos]; + goto found; + } + if (res > 0) max = pos - 1; + else min = pos + 1; + } + + for (i = 0; i < exports->NumberOfNames; i++) + { + ename = (const char*) RVA(name[i]); + if (!strcmp( ename, funcName )) + { + ERR( "%s.%s required a linear search\n", wm->modname, funcName ); + ordinal = ordinals[i]; + goto found; + } + } + return NULL; + } + else + { + ordinal = LOWORD(funcName) - exports->Base; + if (snoop && name) + { + for (i = 0; i < exports->NumberOfNames; i++) + if (ordinals[i] == ordinal) + { + ename = RVA(name[i]); + break; + } + } + } + + found: + if (ordinal >= exports->NumberOfFunctions) + { + TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base ); + return NULL; + } + addr = function[ordinal]; + if (!addr) return NULL; + if ((addr < rva_start) || (addr >= rva_end)) + { + FARPROC proc = RVA(addr); + if (snoop) + { + if (!ename) ename = "@"; +// proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc); + TRACE("SNOOP_GetProcAddress n/a\n"); + + } + return proc; + } + else + { + WINE_MODREF *wm; + char *forward = RVA(addr); + char module[256]; + char *end = strchr(forward, '.'); + + if (!end) return NULL; + if (end - forward >= sizeof(module)) return NULL; + memcpy( module, forward, end - forward ); + module[end-forward] = 0; + if (!(wm = MODULE_FindModule( module ))) + { + ERR("module not found for forward '%s'\n", forward ); + return NULL; + } + return MODULE_GetProcAddress( wm->module, end + 1, snoop ); + } +} + +static DWORD fixup_imports( WINE_MODREF *wm ) +{ + IMAGE_IMPORT_DESCRIPTOR *pe_imp; + PE_MODREF *pem; + unsigned int load_addr = wm->module; + int i,characteristics_detection=1; + char *modname; + + assert(wm->type==MODULE32_PE); + pem = &(wm->binfmt.pe); + if (pem->pe_export) + modname = (char*) RVA(pem->pe_export->Name); + else + modname = ""; + + + TRACE("Dumping imports list\n"); + + + pe_imp = pem->pe_import; + if (!pe_imp) return 0; + + /* We assume that we have at least one import with !0 characteristics and + * detect broken imports with all characteristsics 0 (notably Borland) and + * switch the detection off for them. + */ + for (i = 0; pe_imp->Name ; pe_imp++) { + if (!i && !pe_imp->u.Characteristics) + characteristics_detection = 0; + if (characteristics_detection && !pe_imp->u.Characteristics) + break; + i++; + } + if (!i) return 0; + + + wm->nDeps = i; + wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) ); + + /* load the imported modules. They are automatically + * added to the modref list of the process. + */ + + for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) { + WINE_MODREF *wmImp; + IMAGE_IMPORT_BY_NAME *pe_name; + PIMAGE_THUNK_DATA import_list,thunk_list; + char *name = (char *) RVA(pe_imp->Name); + + if (characteristics_detection && !pe_imp->u.Characteristics) + break; + +//#warning FIXME: here we should fill imports + TRACE("Loading imports for %s.dll\n", name); + + if (pe_imp->u.OriginalFirstThunk != 0) { + TRACE("Microsoft style imports used\n"); + import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk); + thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk); + + while (import_list->u1.Ordinal) { + if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) { + int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal); + +// TRACE("--- Ordinal %s,%d\n", name, ordinal); + + thunk_list->u1.Function=LookupExternal(name, ordinal); + } else { + pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData); +// TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint); + thunk_list->u1.Function=LookupExternalByName(name, pe_name->Name); + } + import_list++; + thunk_list++; + } + } else { + TRACE("Borland style imports used\n"); + thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk); + while (thunk_list->u1.Ordinal) { + if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) { + + int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal); + + TRACE("--- Ordinal %s.%d\n",name,ordinal); + thunk_list->u1.Function=LookupExternal( + name, ordinal); + } else { + pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData); + TRACE("--- %s %s.%d\n", + pe_name->Name,name,pe_name->Hint); + thunk_list->u1.Function=LookupExternalByName( + name, pe_name->Name); + } + thunk_list++; + } + } + } + return 0; +} + +static int calc_vma_size( HMODULE hModule ) +{ + int i,vma_size = 0; + IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule); + + TRACE("Dump of segment table\n"); + TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n"); + for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++) + { + TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n", + pe_seg->Name, + pe_seg->Misc.VirtualSize, + pe_seg->VirtualAddress, + pe_seg->SizeOfRawData, + pe_seg->PointerToRawData, + pe_seg->PointerToRelocations, + pe_seg->PointerToLinenumbers, + pe_seg->NumberOfRelocations, + pe_seg->NumberOfLinenumbers, + pe_seg->Characteristics); + vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData); + vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize); + pe_seg++; + } + return vma_size; +} + +static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r ) +{ + int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase; + int hdelta = (delta >> 16) & 0xFFFF; + int ldelta = delta & 0xFFFF; + + if(delta == 0) + + return; + while(r->VirtualAddress) + { + char *page = (char*) RVA(r->VirtualAddress); + int count = (r->SizeOfBlock - 8)/2; + int i; + TRACE_(fixup)("%x relocations for page %lx\n", + count, r->VirtualAddress); + + for(i=0;iTypeOffset[i] & 0xFFF; + int type = r->TypeOffset[i] >> 12; +// TRACE_(fixup)("patching %x type %x\n", offset, type); + switch(type) + { + case IMAGE_REL_BASED_ABSOLUTE: break; + case IMAGE_REL_BASED_HIGH: + *(short*)(page+offset) += hdelta; + break; + case IMAGE_REL_BASED_LOW: + *(short*)(page+offset) += ldelta; + break; + case IMAGE_REL_BASED_HIGHLOW: + *(int*)(page+offset) += delta; + + break; + case IMAGE_REL_BASED_HIGHADJ: + FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n"); + break; + case IMAGE_REL_BASED_MIPS_JMPADDR: + FIXME("Is this a MIPS machine ???\n"); + break; + default: + FIXME("Unknown fixup type\n"); + break; + } + } + r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock); + } +} + + + + + +/********************************************************************** + * PE_LoadImage + * Load one PE format DLL/EXE into memory + * + * Unluckily we can't just mmap the sections where we want them, for + * (at least) Linux does only support offsets which are page-aligned. + * + * BUT we have to map the whole image anyway, for Win32 programs sometimes + * want to access them. (HMODULE32 point to the start of it) + */ +HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version ) +{ + HMODULE hModule; + HANDLE mapping; + + IMAGE_NT_HEADERS *nt; + IMAGE_SECTION_HEADER *pe_sec; + IMAGE_DATA_DIRECTORY *dir; + BY_HANDLE_FILE_INFORMATION bhfi; + int i, rawsize, lowest_va, vma_size, file_size = 0; + DWORD load_addr = 0, aoep, reloc = 0; +// struct get_read_fd_request *req = get_req_buffer(); + int unix_handle = handle; + int page_size = getpagesize(); + + +// if ( GetFileInformationByHandle( hFile, &bhfi ) ) +// file_size = bhfi.nFileSizeLow; + file_size=lseek(handle, 0, SEEK_END); + lseek(handle, 0, SEEK_SET); + +//#warning fix CreateFileMappingA + mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT, + 0, 0, NULL ); + if (!mapping) + { + WARN("CreateFileMapping error %ld\n", GetLastError() ); + return 0; + } +// hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 ); + hModule=(HMODULE)mapping; +// CloseHandle( mapping ); + if (!hModule) + { + WARN("MapViewOfFile error %ld\n", GetLastError() ); + return 0; + } + if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE) + { + WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule); + goto error; + } + + nt = PE_HEADER( hModule ); + + + if ( nt->Signature != IMAGE_NT_SIGNATURE ) + { + WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature ); + goto error; + } + + + if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 ) + { + MESSAGE("Trying to load PE image for unsupported architecture ("); + switch (nt->FileHeader.Machine) + { + case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break; + case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break; + case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break; + case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break; + case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break; + case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break; + case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break; + default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break; + } + MESSAGE(")\n"); + goto error; + } + + + pe_sec = PE_SECTIONS( hModule ); + rawsize = 0; lowest_va = 0x10000; + for (i = 0; i < nt->FileHeader.NumberOfSections; i++) + { + if (lowest_va > pe_sec[i].VirtualAddress) + lowest_va = pe_sec[i].VirtualAddress; + if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + continue; + if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize) + rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData; + } + + + if ( file_size && file_size < rawsize ) + { + ERR("PE module is too small (header: %d, filesize: %d), " + "probably truncated download?\n", + rawsize, file_size ); + goto error; + } + + + aoep = nt->OptionalHeader.AddressOfEntryPoint; + if (aoep && (aoep < lowest_va)) + FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) " + "below the first virtual address (0x%08x) " + "(possibly infected by Tchernobyl/SpaceFiller virus)!\n", + filename, aoep, lowest_va ); + + + /* FIXME: Hack! While we don't really support shared sections yet, + * this checks for those special cases where the whole DLL + * consists only of shared sections and is mapped into the + * shared address space > 2GB. In this case, we assume that + * the module got mapped at its base address. Thus we simply + * check whether the module has actually been mapped there + * and use it, if so. This is needed to get Win95 USER32.DLL + * to work (until we support shared sections properly). + */ + + if ( nt->OptionalHeader.ImageBase & 0x80000000 ) + { + HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase; + IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS) + ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) ); + + /* Well, this check is not really comprehensive, + but should be good enough for now ... */ + if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) ) + && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0 + && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) ) + && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 ) + { + UnmapViewOfFile( (LPVOID)hModule ); + return sharedMod; + } + } + + + + load_addr = nt->OptionalHeader.ImageBase; + vma_size = calc_vma_size( hModule ); + + load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size, + MEM_RESERVE | MEM_COMMIT, + PAGE_EXECUTE_READWRITE ); + if (load_addr == 0) + { + + FIXME("We need to perform base relocations for %s\n", filename); + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC; + if (dir->Size) + reloc = dir->VirtualAddress; + else + { + FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n", + filename, + (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)? + "stripped during link" : "unknown reason" ); + goto error; + } + + /* FIXME: If we need to relocate a system DLL (base > 2GB) we should + * really make sure that the *new* base address is also > 2GB. + * Some DLLs really check the MSB of the module handle :-/ + */ + if ( nt->OptionalHeader.ImageBase & 0x80000000 ) + ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" ); + + load_addr = (DWORD)VirtualAlloc( NULL, vma_size, + MEM_RESERVE | MEM_COMMIT, + PAGE_EXECUTE_READWRITE ); + if (!load_addr) { + FIXME_(win32)( + "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size); + goto error; + } + } + + TRACE("Load addr is %lx (base %lx), range %x\n", + load_addr, nt->OptionalHeader.ImageBase, vma_size ); + TRACE_(segment)("Loading %s at %lx, range %x\n", + filename, load_addr, vma_size ); + +#if 0 + + *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule; + *PE_HEADER( load_addr ) = *nt; + memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule), + sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections ); + + + memcpy( load_addr, hModule, lowest_fa ); +#endif + + if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders, + 0, 0, PROT_EXEC | PROT_WRITE | PROT_READ, + MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr) + { + ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n"); + goto error; + } + + + pe_sec = PE_SECTIONS( hModule ); + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++) + { + if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue; + TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n", + filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress), + pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize ); + if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress), + 0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData, + PROT_EXEC | PROT_WRITE | PROT_READ, + MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress)) + { + + ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n"); + goto error; + } + if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) && + (pe_sec->SizeOfRawData & (page_size-1))) + { + DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size; + if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize; + TRACE("clearing %p - %p\n", + RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, + RVA(pe_sec->VirtualAddress) + end ); + memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0, + end - pe_sec->SizeOfRawData ); + } + } + + + if ( reloc ) + do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) ); + + + *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) + | (nt->OptionalHeader.MinorSubsystemVersion & 0xff); + + + UnmapViewOfFile( (LPVOID)hModule ); + return (HMODULE)load_addr; + +error: + if (unix_handle != -1) close( unix_handle ); + if (load_addr) + VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE ); + UnmapViewOfFile( (LPVOID)hModule ); + return 0; +} + +/********************************************************************** + * PE_CreateModule + * + * Create WINE_MODREF structure for loaded HMODULE32, link it into + * process modref_list, and fixup all imports. + * + * Note: hModule must point to a correctly allocated PE image, + * with base relocations applied; the 16-bit dummy module + * associated to hModule must already exist. + * + * Note: This routine must always be called in the context of the + * process that is to own the module to be created. + */ +WINE_MODREF *PE_CreateModule( HMODULE hModule, + LPCSTR filename, DWORD flags, WIN_BOOL builtin ) +{ + DWORD load_addr = (DWORD)hModule; + IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); + IMAGE_DATA_DIRECTORY *dir; + IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; + IMAGE_EXPORT_DIRECTORY *pe_export = NULL; + IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL; + WINE_MODREF *wm; + int result; + + + + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; + if (dir->Size) + pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; + if (dir->Size) + pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; + if (dir->Size) + pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION; + if (dir->Size) FIXME("Exception directory ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY; + if (dir->Size) FIXME("Security directory ignored\n" ); + + + + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG; + if (dir->Size) TRACE("Debug directory ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT; + if (dir->Size) FIXME("Copyright string ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR; + if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" ); + + + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG; + if (dir->Size) FIXME("Load Configuration directory ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT; + if (dir->Size) TRACE("Bound Import directory ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT; + if (dir->Size) TRACE("Import Address Table directory ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT; + if (dir->Size) + { + TRACE("Delayed import, stub calls LoadLibrary\n" ); + /* + * Nothing to do here. + */ + +#ifdef ImgDelayDescr + /* + * This code is useful to observe what the heck is going on. + */ + { + ImgDelayDescr *pe_delay = NULL; + pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress); + TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs); + TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName); + TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod); + TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT); + TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT); + TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT); + TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT); + TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp); + } +#endif + } + + dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; + if (dir->Size) FIXME("Unknown directory 14 ignored\n" ); + + dir = nt->OptionalHeader.DataDirectory+15; + if (dir->Size) FIXME("Unknown directory 15 ignored\n" ); + + + + + wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(*wm) ); + wm->module = hModule; + + if ( builtin ) + wm->flags |= WINE_MODREF_INTERNAL; + if ( flags & DONT_RESOLVE_DLL_REFERENCES ) + wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS; + if ( flags & LOAD_LIBRARY_AS_DATAFILE ) + wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE; + + wm->type = MODULE32_PE; + wm->binfmt.pe.pe_export = pe_export; + wm->binfmt.pe.pe_import = pe_import; + wm->binfmt.pe.pe_resource = pe_resource; + wm->binfmt.pe.tlsindex = -1; + + wm->filename = malloc(strlen(filename)+1); + strcpy(wm->filename, filename ); + wm->modname = strrchr( wm->filename, '\\' ); + if (!wm->modname) wm->modname = wm->filename; + else wm->modname++; + + if ( pe_export ) + dump_exports( hModule ); + + /* Fixup Imports */ + + if ( pe_import + && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) + && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) + && fixup_imports( wm ) ) + { + /* remove entry from modref chain */ + return NULL; + } + + return wm; + + return wm; +} + +/****************************************************************************** + * The PE Library Loader frontend. + * FIXME: handle the flags. + */ +WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags) +{ + HMODULE hModule32; + WINE_MODREF *wm; + char filename[256]; + int hFile; + WORD version = 0; + + + strncpy(filename, name, sizeof(filename)); + hFile=open(filename, O_RDONLY); + if(hFile==-1) + return NULL; + + + hModule32 = PE_LoadImage( hFile, filename, &version ); + if (!hModule32) + { + SetLastError( ERROR_OUTOFMEMORY ); + return NULL; + } + + if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) ) + { + ERR( "can't load %s\n", filename ); + SetLastError( ERROR_OUTOFMEMORY ); + return NULL; + } + close(hFile); + //printf("^^^^^^^^^^^^^^^^Alloc VM1 %p\n", wm); + return wm; +} + + +/***************************************************************************** + * PE_UnloadLibrary + * + * Unload the library unmapping the image and freeing the modref structure. + */ +void PE_UnloadLibrary(WINE_MODREF *wm) +{ + TRACE(" unloading %s\n", wm->filename); + + if (wm->filename) + free(wm->filename); + if (wm->short_filename) + free(wm->short_filename); + HeapFree( GetProcessHeap(), 0, wm->deps ); + VirtualFree( (LPVOID)wm->module, 0, MEM_RELEASE ); + HeapFree( GetProcessHeap(), 0, wm ); + //printf("^^^^^^^^^^^^^^^^Free VM1 %p\n", wm); +} + +/***************************************************************************** + * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA + * FIXME: this function should use PE_LoadLibraryExA, but currently can't + * due to the PROCESS_Create stuff. + */ + + +/* + * This is a dirty hack. + * The win32 DLLs contain an alloca routine, that first probes the soon + * to be allocated new memory *below* the current stack pointer in 4KByte + * increments. After the mem probing below the current %esp, the stack + * pointer is finally decremented to make room for the "alloca"ed memory. + * Maybe the probing code is intended to extend the stack on a windows box. + * Anyway, the linux kernel does *not* extend the stack by simply accessing + * memory below %esp; it segfaults. + * The extend_stack_for_dll_alloca() routine just preallocates a big chunk + * of memory on the stack, for use by the DLLs alloca routine. + */ +static void extend_stack_for_dll_alloca(void) +{ +#ifndef __FreeBSD__ + void* mem=alloca(0x20000); + *(int*)mem=0x1234; +#endif +} + +/* Called if the library is loaded or freed. + * NOTE: if a thread attaches a DLL, the current thread will only do + * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH + * (SDK) + */ +WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) +{ + WIN_BOOL retv = TRUE; + assert( wm->type == MODULE32_PE ); + + + if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) && + (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint) + ) { + DLLENTRYPROC entry ; + entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0); + if(entry==NULL) + entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint ); + + TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n", + entry, wm->module, type, lpReserved ); + + + TRACE("Entering DllMain("); + switch(type) + { + case DLL_PROCESS_DETACH: + TRACE("DLL_PROCESS_DETACH) "); + break; + case DLL_PROCESS_ATTACH: + TRACE("DLL_PROCESS_ATTACH) "); + break; + case DLL_THREAD_DETACH: + TRACE("DLL_THREAD_DETACH) "); + break; + case DLL_THREAD_ATTACH: + TRACE("DLL_THREAD_ATTACH) "); + break; + } + TRACE("for %s\n", wm->filename); + extend_stack_for_dll_alloca(); + retv = entry( wm->module, type, lpReserved ); + } + + return retv; +} + +static LPVOID +_fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) { + if ( ((DWORD)addr>opt->ImageBase) && + ((DWORD)addrImageBase+opt->SizeOfImage) + ) + + return (LPVOID)(((DWORD)addr)+delta); + else + + return addr; +} diff --git a/linphone/win32acm/pe_resource.c b/linphone/win32acm/pe_resource.c new file mode 100644 index 000000000..f7afcbfce --- /dev/null +++ b/linphone/win32acm/pe_resource.c @@ -0,0 +1,392 @@ +/* + * PE (Portable Execute) File Resources + * + * Copyright 1995 Thomas Sandford + * Copyright 1996 Martin von Loewis + * + * Based on the Win16 resource handling code in loader/resource.c + * Copyright 1993 Robert J. Amstadt + * Copyright 1995 Alexandre Julliard + * Copyright 1997 Marcus Meissner + */ +#include "config.h" + +#include +#include +#include "wine/winestring.h" +#include "wine/windef.h" +#include "wine/pe_image.h" +#include "wine/module.h" +#include "wine/heap.h" +//#include "task.h" +//#include "process.h" +//#include "stackframe.h" +#include "wine/debugtools.h" +#include "ext.h" + +/********************************************************************** + * HMODULE32toPE_MODREF + * + * small helper function to get a PE_MODREF from a passed HMODULE32 + */ +static PE_MODREF* +HMODULE32toPE_MODREF(HMODULE hmod) { + WINE_MODREF *wm; + + wm = MODULE32_LookupHMODULE( hmod ); + if (!wm || wm->type!=MODULE32_PE) + return NULL; + return &(wm->binfmt.pe); +} + +/********************************************************************** + * GetResDirEntryW + * + * Helper function - goes down one level of PE resource tree + * + */ +PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, + LPCWSTR name,DWORD root, + WIN_BOOL allowdefault) +{ + int entrynum; + PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; + int namelen; + + if (HIWORD(name)) { + if (name[0]=='#') { + char buf[10]; + + lstrcpynWtoA(buf,name+1,10); + return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault); + } + entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( + (BYTE *) resdirptr + + sizeof(IMAGE_RESOURCE_DIRECTORY)); + namelen = lstrlenW(name); + for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) + { + PIMAGE_RESOURCE_DIR_STRING_U str = + (PIMAGE_RESOURCE_DIR_STRING_U) (root + + entryTable[entrynum].u1.s.NameOffset); + if(namelen != str->Length) + continue; + if(wcsnicmp(name,str->NameString,str->Length)==0) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + entryTable[entrynum].u2.s.OffsetToDirectory); + } + return NULL; + } else { + entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( + (BYTE *) resdirptr + + sizeof(IMAGE_RESOURCE_DIRECTORY) + + resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); + for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++) + if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + entryTable[entrynum].u2.s.OffsetToDirectory); + /* just use first entry if no default can be found */ + if (allowdefault && !name && resdirptr->NumberOfIdEntries) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + entryTable[0].u2.s.OffsetToDirectory); + return NULL; + } +} + +/********************************************************************** + * GetResDirEntryA + */ +PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, + LPCSTR name, DWORD root, + WIN_BOOL allowdefault ) +{ + PIMAGE_RESOURCE_DIRECTORY retv; + LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) + : (LPWSTR)name; + + retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault ); + + if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW ); + + return retv; +} + +/********************************************************************** + * PE_FindResourceEx32W + */ +HANDLE PE_FindResourceExW( + WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang +) { + PIMAGE_RESOURCE_DIRECTORY resdirptr; + DWORD root; + HANDLE result; + PE_MODREF *pem = &(wm->binfmt.pe); + + if (!pem || !pem->pe_resource) + return 0; + + resdirptr = pem->pe_resource; + root = (DWORD) resdirptr; + if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL) + return 0; + if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) + return 0; + result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); + /* Try LANG_NEUTRAL, too */ + if(!result) + return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); + return result; +} + + +/********************************************************************** + * PE_LoadResource32 + */ +HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc ) +{ + if (!hRsrc || !wm || wm->type!=MODULE32_PE) + return 0; + return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); +} + + +/********************************************************************** + * PE_SizeofResource32 + */ +DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc ) +{ + /* we don't need hModule */ + if (!hRsrc) + return 0; + return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; +} + +/********************************************************************** + * PE_EnumResourceTypes32A + */ +WIN_BOOL +PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + HANDLE heap = GetProcessHeap(); + + if (!pem || !pem->pe_resource) + return FALSE; + + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + LPSTR name; + + if (et[i].u1.s.NameIsString) + name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); + else + name = (LPSTR)(int)et[i].u1.Id; + ret = lpfun(hmod,name,lparam); + if (HIWORD(name)) + HeapFree(heap,0,name); + if (!ret) + break; + } + return ret; +} + +/********************************************************************** + * PE_EnumResourceTypes32W + */ +WIN_BOOL +PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + + if (!pem || !pem->pe_resource) + return FALSE; + + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + LPWSTR type; + if (et[i].u1.s.NameIsString) + type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); + else + type = (LPWSTR)(int)et[i].u1.Id; + + ret = lpfun(hmod,type,lparam); + if (!ret) + break; + } + return ret; +} + +/********************************************************************** + * PE_EnumResourceNames32A + */ +WIN_BOOL +PE_EnumResourceNamesA( + HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam +) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + HANDLE heap = GetProcessHeap(); + LPWSTR typeW; + + if (!pem || !pem->pe_resource) + return FALSE; + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + if (HIWORD(type)) + typeW = HEAP_strdupAtoW(heap,0,type); + else + typeW = (LPWSTR)type; + resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); + if (HIWORD(typeW)) + HeapFree(heap,0,typeW); + if (!resdir) + return FALSE; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + LPSTR name; + + if (et[i].u1.s.NameIsString) + name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); + else + name = (LPSTR)(int)et[i].u1.Id; + ret = lpfun(hmod,type,name,lparam); + if (HIWORD(name)) HeapFree(heap,0,name); + if (!ret) + break; + } + return ret; +} + +/********************************************************************** + * PE_EnumResourceNames32W + */ +WIN_BOOL +PE_EnumResourceNamesW( + HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam +) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + + if (!pem || !pem->pe_resource) + return FALSE; + + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); + if (!resdir) + return FALSE; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + LPWSTR name; + if (et[i].u1.s.NameIsString) + name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); + else + name = (LPWSTR)(int)et[i].u1.Id; + ret = lpfun(hmod,type,name,lparam); + if (!ret) + break; + } + return ret; +} + +/********************************************************************** + * PE_EnumResourceNames32A + */ +WIN_BOOL +PE_EnumResourceLanguagesA( + HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun, + LONG lparam +) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + HANDLE heap = GetProcessHeap(); + LPWSTR nameW,typeW; + + if (!pem || !pem->pe_resource) + return FALSE; + + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + if (HIWORD(name)) + nameW = HEAP_strdupAtoW(heap,0,name); + else + nameW = (LPWSTR)name; + resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE); + if (HIWORD(nameW)) + HeapFree(heap,0,nameW); + if (!resdir) + return FALSE; + if (HIWORD(type)) + typeW = HEAP_strdupAtoW(heap,0,type); + else + typeW = (LPWSTR)type; + resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); + if (HIWORD(typeW)) + HeapFree(heap,0,typeW); + if (!resdir) + return FALSE; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + /* languages are just ids... I hopem */ + ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); + if (!ret) + break; + } + return ret; +} + +/********************************************************************** + * PE_EnumResourceLanguages32W + */ +WIN_BOOL +PE_EnumResourceLanguagesW( + HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun, + LONG lparam +) { + PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); + int i; + PIMAGE_RESOURCE_DIRECTORY resdir; + PIMAGE_RESOURCE_DIRECTORY_ENTRY et; + WIN_BOOL ret; + + if (!pem || !pem->pe_resource) + return FALSE; + + resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; + resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE); + if (!resdir) + return FALSE; + resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); + if (!resdir) + return FALSE; + et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); + ret = FALSE; + for (i=0;iNumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { + ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); + if (!ret) + break; + } + return ret; +} diff --git a/linphone/win32acm/registry.c b/linphone/win32acm/registry.c new file mode 100644 index 000000000..1fe90e099 --- /dev/null +++ b/linphone/win32acm/registry.c @@ -0,0 +1,526 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "wine/winbase.h" +#include "wine/winreg.h" +#include "wine/winnt.h" +#include "wine/winerror.h" + +#include "ext.h" +#include "registry.h" + +//#undef TRACE +//#define TRACE printf + +extern char *get_path ( char * ); + +// ...can be set before init_registry() call +char* regpathname = NULL; + +static char* localregpathname = NULL; + +typedef struct reg_handle_s +{ + int handle; + char* name; + struct reg_handle_s* next; + struct reg_handle_s* prev; +} reg_handle_t; + +struct reg_value +{ + int type; + char* name; + int len; + char* value; +}; + +static struct reg_value* regs = NULL; +static int reg_size; +static reg_handle_t* head = NULL; + +#define DIR -25 + +static void create_registry(void); +static void open_registry(void); +static void save_registry(void); +static void init_registry(void); + + +static void create_registry(void){ + if(regs) + { + printf("Logic error: create_registry() called with existing registry\n"); + save_registry(); + return; + } + regs=(struct reg_value*)malloc(3*sizeof(struct reg_value)); + regs[0].type=regs[1].type=DIR; + regs[0].name=(char*)malloc(5); + strcpy(regs[0].name, "HKLM"); + regs[1].name=(char*)malloc(5); + strcpy(regs[1].name, "HKCU"); + regs[0].value=regs[1].value=NULL; + regs[0].len=regs[1].len=0; + reg_size=2; + head = 0; + save_registry(); +} + +static void open_registry(void) +{ + int fd; + int i; + unsigned int len; + if(regs) + { + printf("Multiple open_registry(>\n"); + return; + } + fd = open(localregpathname, O_RDONLY); + if (fd == -1) + { + printf("Creating new registry\n"); + create_registry(); + return; + } + read(fd, ®_size, 4); + regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); + head = 0; + for(i=0; iname) + free(t->name); + t=t->prev; + free(f); + } + head = 0; + if (regs) + { + int i; + for(i=0; iprev) + { + if(!strcmp(t->name, name)) + { + return t; + } + } + return 0; +} +static struct reg_value* find_value_by_name(const char* name) +{ + int i; + for(i=0; iprev) + { + if(t->handle==handle) + { + return t; + } + } + return 0; +} +static int generate_handle() +{ + static unsigned int zz=249; + zz++; + while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) + zz++; + return zz; +} + +static reg_handle_t* insert_handle(long handle, const char* name) +{ + reg_handle_t* t; + t=(reg_handle_t*)malloc(sizeof(reg_handle_t)); + if(head==0) + { + t->prev=0; + } + else + { + head->next=t; + t->prev=head; + } + t->next=0; + t->name=(char*)malloc(strlen(name)+1); + strcpy(t->name, name); + t->handle=handle; + head=t; + return t; +} +static char* build_keyname(long key, const char* subkey) +{ + char* full_name; + reg_handle_t* t; + if((t=find_handle(key))==0) + { + TRACE("Invalid key\n"); + return NULL; + } + if(subkey==NULL) + subkey=""; + full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); + strcpy(full_name, t->name); + strcat(full_name, "\\"); + strcat(full_name, subkey); + return full_name; +} +static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) +{ + reg_handle_t* t; + struct reg_value* v; + char* fullname; + if((fullname=build_keyname(handle, name))==NULL) + { + TRACE("Invalid handle\n"); + return NULL; + } + + if((v=find_value_by_name(fullname))==0) + //creating new value in registry + { + if(regs==0) + create_registry(); + regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); + //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1)); + v=regs+reg_size; + reg_size++; + } + else + //replacing old one + { + free(v->value); + free(v->name); + } + TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len); + v->type=type; + v->len=len; + v->value=(char*)malloc(len); + memcpy(v->value, value, len); + v->name=(char*)malloc(strlen(fullname)+1); + strcpy(v->name, fullname); + free(fullname); + save_registry(); + return v; +} + +static void init_registry(void) +{ + TRACE("Initializing registry\n"); + // can't be free-ed - it's static and probably thread + // unsafe structure which is stored in glibc + +#ifdef MPLAYER + regpathname = get_path("registry"); + localregpathname = regpathname; +#else + // regpathname is an external pointer + // + // registry.c is holding it's own internal pointer + // localregpathname - which is being allocate/deallocated + + if (localregpathname == 0) + { + const char* pthn = regpathname; + if (!regpathname) + { + // avifile - for now reading data from user's home + struct passwd* pwent; + pwent = getpwuid(geteuid()); + pthn = pwent->pw_dir; + } + + localregpathname = (char*)malloc(strlen(pthn)+20); + strcpy(localregpathname, pthn); + strcat(localregpathname, "/.registry"); + } +#endif + + open_registry(); + insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); + insert_handle(HKEY_CURRENT_USER, "HKCU"); +} + +static reg_handle_t* find_handle_2(long key, const char* subkey) +{ + char* full_name; + reg_handle_t* t; + if((t=find_handle(key))==0) + { + TRACE("Invalid key\n"); + return (reg_handle_t*)-1; + } + if(subkey==NULL) + return t; + full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); + strcpy(full_name, t->name); + strcat(full_name, "\\"); + strcat(full_name, subkey); + t=find_handle_by_name(full_name); + free(full_name); + return t; +} + +long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) +{ + char* full_name; + reg_handle_t* t; + struct reg_value* v; + TRACE("Opening key %s\n", subkey); + + if(!regs) + init_registry() +; +/* t=find_handle_2(key, subkey); + + if(t==0) + return -1; + + if(t==(reg_handle_t*)-1) + return -1; +*/ + full_name=build_keyname(key, subkey); + if(!full_name) + return -1; + TRACE("Opening key Fullname %s\n", full_name); + v=find_value_by_name(full_name); + + t=insert_handle(generate_handle(), full_name); + *newkey=t->handle; + free(full_name); + + return 0; +} +long RegCloseKey(long key) +{ + reg_handle_t *handle; + if(key==(long)HKEY_LOCAL_MACHINE) + return 0; + if(key==(long)HKEY_CURRENT_USER) + return 0; + handle=find_handle(key); + if(handle==0) + return 0; + if(handle->prev) + handle->prev->next=handle->next; + if(handle->next) + handle->next->prev=handle->prev; + if(handle->name) + free(handle->name); + if(handle==head) + head=head->prev; + free(handle); + return 1; +} + +long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) +{ + struct reg_value* t; + char* c; + TRACE("Querying value %s\n", value); + if(!regs) + init_registry(); + + c=build_keyname(key, value); + if (!c) + return 1; + t=find_value_by_name(c); + free(c); + if (t==0) + return 2; + if (type) + *type=t->type; + if (data) + { + memcpy(data, t->value, (t->len<*count)?t->len:*count); + TRACE("returning %d bytes: %d\n", t->len, *(int*)data); + } + if(*countlen) + { + *count=t->len; + return ERROR_MORE_DATA; + } + else + { + *count=t->len; + } + return 0; +} +long RegCreateKeyExA(long key, const char* name, long reserved, + void* classs, long options, long security, + void* sec_attr, int* newkey, int* status) +{ + reg_handle_t* t; + char* fullname; + struct reg_value* v; + // TRACE("Creating/Opening key %s\n", name); + if(!regs) + init_registry(); + + fullname=build_keyname(key, name); + if (!fullname) + return 1; + TRACE("Creating/Opening key %s\n", fullname); + v=find_value_by_name(fullname); + if(v==0) + { + int qw=45708; + v=insert_reg_value(key, name, DIR, &qw, 4); + if (status) *status=REG_CREATED_NEW_KEY; + // return 0; + } + + t=insert_handle(generate_handle(), fullname); + *newkey=t->handle; + free(fullname); + return 0; +} + +/* +LONG RegEnumValue( + HKEY hKey, // handle to key to query + DWORD dwIndex, // index of value to query + LPTSTR lpValueName, // address of buffer for value string + LPDWORD lpcbValueName, // address for size of value buffer + LPDWORD lpReserved, // reserved + LPDWORD lpType, // address of buffer for type code + LPBYTE lpData, // address of buffer for value data + LPDWORD lpcbData // address for size of data buffer +); +*/ + +long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, + LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) +{ + // currenly just made to support MSZH & ZLIB + //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index, + // value, *val_count, data, *count, reg_size, data); + reg_handle_t* t = find_handle(hkey); + if (t && index < 10) + { + struct reg_value* v=find_value_by_name(t->name); + if (v) + { + memcpy(data, v->value, (v->len < *count) ? v->len : *count); + if(*count < v->len) + *count = v->len; + if (type) + *type = v->type; + //printf("Found handle %s\n", v->name); + return 0; + } + } + return ERROR_NO_MORE_ITEMS; +} + +long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) +{ + struct reg_value* t; + char* c; + TRACE("Request to set value %s %d\n", name, *(const int*)data); + if(!regs) + init_registry(); + + c=build_keyname(key, name); + if(c==NULL) + return 1; + insert_reg_value(key, name, v2, data, size); + free(c); + return 0; +} + +long RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, + LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, + LPFILETIME lpftLastWriteTime) +{ + return ERROR_NO_MORE_ITEMS; +} diff --git a/linphone/win32acm/registry.h b/linphone/win32acm/registry.h new file mode 100644 index 000000000..45a6be692 --- /dev/null +++ b/linphone/win32acm/registry.h @@ -0,0 +1,40 @@ +#ifndef AVIFILE_REGISTRY_H +#define AVIFILE_REGISTRY_H + +/******************************************************** + * + * Declaration of registry access functions + * Copyright 2000 Eugene Kuznetsov (divx@euro.ru) + * + ********************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +void free_registry(void); + +long RegOpenKeyExA(long key, const char* subkey, long reserved, + long access, int* newkey); +long RegCloseKey(long key); +long RegQueryValueExA(long key, const char* value, int* reserved, + int* type, int* data, int* count); +long RegCreateKeyExA(long key, const char* name, long reserved, + void* classs, long options, long security, + void* sec_attr, int* newkey, int* status); +long RegSetValueExA(long key, const char* name, long v1, long v2, + const void* data, long size); + +#ifdef __WINE_WINERROR_H + +long RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, + LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, + LPFILETIME lpftLastWriteTime); +long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, + LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count); +#endif +#ifdef __cplusplus +}; +#endif + +#endif // AVIFILE_REGISTRY_H diff --git a/linphone/win32acm/resource.c b/linphone/win32acm/resource.c new file mode 100644 index 000000000..3cb69bd00 --- /dev/null +++ b/linphone/win32acm/resource.c @@ -0,0 +1,482 @@ +/* + * Resources + * + * Copyright 1993 Robert J. Amstadt + * Copyright 1995 Alexandre Julliard + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/winbase.h" +#include "wine/windef.h" +#include "wine/winuser.h" +#include "wine/heap.h" +#include "wine/module.h" +#include "wine/debugtools.h" +#include "wine/winerror.h" +#include "loader.h" + +#define CP_ACP 0 + +WORD WINE_LanguageId=0x409;//english + +#define HRSRC_MAP_BLOCKSIZE 16 + +typedef struct _HRSRC_ELEM +{ + HANDLE hRsrc; + WORD type; +} HRSRC_ELEM; + +typedef struct _HRSRC_MAP +{ + int nAlloc; + int nUsed; + HRSRC_ELEM *elem; +} HRSRC_MAP; + +static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, + LPCSTR name, WORD lang, int unicode) +{ + HRSRC hRsrc = 0; + LPWSTR typeStr, nameStr; + WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); + + if(!wm) + return 0; + /* 32-bit PE module */ + + + if ( HIWORD( type ) && (!unicode)) + typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); + else + typeStr = (LPWSTR)type; + if ( HIWORD( name ) && (!unicode)) + nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); + else + nameStr = (LPWSTR)name; + + hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang ); + + if ( HIWORD( type ) && (!unicode)) + HeapFree( GetProcessHeap(), 0, typeStr ); + if ( HIWORD( name ) && (!unicode)) + HeapFree( GetProcessHeap(), 0, nameStr ); + + return hRsrc; +} + +/********************************************************************** + * RES_FindResource + */ + +static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, + LPCSTR name, WORD lang, int unicode ) +{ + HRSRC hRsrc; +// __TRY +// { + hRsrc = RES_FindResource2(hModule, type, name, lang, unicode); +// } +// __EXCEPT(page_fault) +// { +// WARN("page fault\n"); +// SetLastError(ERROR_INVALID_PARAMETER); +// return 0; +// } +// __ENDTRY + return hRsrc; +} + +/********************************************************************** + * RES_SizeofResource + */ +static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc) +{ + DWORD size = 0; + HRSRC hRsrc32; + +// HMODULE16 hMod16 = MapHModuleLS( hModule ); +// NE_MODULE *pModule = NE_GetPtr( hMod16 ); +// WINE_MODREF *wm = pModule && pModule->module32? +// MODULE32_LookupHMODULE( pModule->module32 ) : NULL; + WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); + + if ( !hModule || !hRsrc ) return 0; + + /* 32-bit PE module */ + /* If we got a 16-bit hRsrc, convert it */ +// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); + if(!HIWORD(hRsrc)) + { + printf("16-bit hRsrcs not supported\n"); + return 0; + } + size = PE_SizeofResource( hModule, hRsrc ); + return size; +} + +/********************************************************************** + * RES_AccessResource + */ +static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc ) +{ + HFILE hFile = HFILE_ERROR; + + WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); + + if ( !hModule || !hRsrc ) return HFILE_ERROR; + + /* 32-bit PE module */ + FIXME("32-bit modules not yet supported.\n" ); + hFile = HFILE_ERROR; + + return hFile; +} + +/********************************************************************** + * RES_LoadResource + */ +static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc) +{ + HGLOBAL hMem = 0; + HRSRC hRsrc32; + WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); + + + if ( !hModule || !hRsrc ) return 0; + + /* 32-bit PE module */ + + /* If we got a 16-bit hRsrc, convert it */ +// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); + if(!HIWORD(hRsrc)) + { + printf("16-bit hRsrcs not supported\n"); + return 0; + } + hMem = PE_LoadResource( wm, hRsrc ); + + return hMem; +} + +/********************************************************************** + * RES_LockResource + */ +static LPVOID RES_LockResource( HGLOBAL handle ) +{ + LPVOID bits = NULL; + + TRACE("(%08x, %s)\n", handle, "PE" ); + + bits = (LPVOID)handle; + + return bits; +} + +/********************************************************************** + * RES_FreeResource + */ +static WIN_BOOL RES_FreeResource( HGLOBAL handle ) +{ + HGLOBAL retv = handle; + return (WIN_BOOL)retv; +} + +/********************************************************************** + * FindResourceA (KERNEL32.128) + */ +HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) +{ + return RES_FindResource( hModule, type, name, + WINE_LanguageId, 0); +} +HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type ) +{ + return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, + WINE_LanguageId, 1); +} + +/********************************************************************** + * FindResourceExA (KERNEL32.129) + */ +HANDLE WINAPI FindResourceExA( HMODULE hModule, + LPCSTR type, LPCSTR name, WORD lang ) +{ + return RES_FindResource( hModule, type, name, + lang, 0 ); +} + +HANDLE WINAPI FindResourceExW( HMODULE hModule, + LPCWSTR type, LPCWSTR name, WORD lang ) +{ + return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, + lang, 1 ); +} + + + +/********************************************************************** + * LockResource (KERNEL32.384) + */ +LPVOID WINAPI LockResource( HGLOBAL handle ) +{ + return RES_LockResource( handle ); +} + + +/********************************************************************** + * FreeResource (KERNEL32.145) + */ +WIN_BOOL WINAPI FreeResource( HGLOBAL handle ) +{ + return RES_FreeResource( handle ); +} + + +/********************************************************************** + * AccessResource (KERNEL32.64) + */ +INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc ) +{ + return RES_AccessResource( hModule, hRsrc ); +} +/********************************************************************** + * SizeofResource (KERNEL32.522) + */ +DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) +{ + return RES_SizeofResource( hModule, hRsrc ); +} + + +INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, + LPWSTR buffer, INT buflen ); + +/********************************************************************** + * LoadStringA (USER32.375) + */ +INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, + LPSTR buffer, INT buflen ) +{ + INT retval; + INT wbuflen; + INT abuflen; + LPWSTR wbuf = NULL; + LPSTR abuf = NULL; + + if ( buffer != NULL && buflen > 0 ) + *buffer = 0; + + wbuflen = LoadStringW(instance,resource_id,NULL,0); + if ( !wbuflen ) + return 0; + wbuflen ++; + + retval = 0; + wbuf = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) ); + wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen); + if ( wbuflen > 0 ) + { + abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL); + if ( abuflen > 0 ) + { + if ( buffer == NULL || buflen == 0 ) + retval = abuflen; + else + { + abuf = (LPSTR) HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) ); + abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL); + if ( abuflen > 0 ) + { + abuflen = min(abuflen,buflen - 1); + memcpy( buffer, abuf, abuflen ); + buffer[abuflen] = 0; + retval = abuflen; + } + HeapFree( GetProcessHeap(), 0, abuf ); + } + } + } + HeapFree( GetProcessHeap(), 0, wbuf ); + + return retval; +} + +/********************************************************************** + * LoadStringW (USER32.376) + */ +INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, + LPWSTR buffer, INT buflen ) +{ + HGLOBAL hmem; + HRSRC hrsrc; + WCHAR *p; + int string_num; + int i; + + if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */ + resource_id = (UINT)(-((INT)resource_id)); + TRACE("instance = %04x, id = %04x, buffer = %08x, " + "length = %d\n", instance, (int)resource_id, (int) buffer, buflen); + + /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out + * 20 - 31. */ + hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1), + RT_STRINGW ); + if (!hrsrc) return 0; + hmem = LoadResource( instance, hrsrc ); + if (!hmem) return 0; + + p = (WCHAR*) LockResource(hmem); + string_num = resource_id & 0x000f; + for (i = 0; i < string_num; i++) + p += *p + 1; + + TRACE("strlen = %d\n", (int)*p ); + + if (buffer == NULL) return *p; + i = min(buflen - 1, *p); + if (i > 0) { + memcpy(buffer, p + 1, i * sizeof (WCHAR)); + buffer[i] = (WCHAR) 0; + } else { + if (buflen > 1) { + buffer[0] = (WCHAR) 0; + return 0; + } +#if 0 + WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1); +#endif + } + + TRACE("String loaded !\n"); + return i; +} + +/* Messages...used by FormatMessage32* (KERNEL32.something) + * + * They can be specified either directly or using a message ID and + * loading them from the resource. + * + * The resourcedata has following format: + * start: + * 0: DWORD nrofentries + * nrofentries * subentry: + * 0: DWORD firstentry + * 4: DWORD lastentry + * 8: DWORD offset from start to the stringentries + * + * (lastentry-firstentry) * stringentry: + * 0: WORD len (0 marks end) + * 2: WORD flags + * 4: CHAR[len-4] + * (stringentry i of a subentry refers to the ID 'firstentry+i') + * + * Yes, ANSI strings in win32 resources. Go figure. + */ + +/********************************************************************** + * LoadMessageA (internal) + */ +INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang, + LPSTR buffer, INT buflen ) +{ + HGLOBAL hmem; + HRSRC hrsrc; + PMESSAGE_RESOURCE_DATA mrd; + PMESSAGE_RESOURCE_BLOCK mrb; + PMESSAGE_RESOURCE_ENTRY mre; + int i,slen; + + TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); + + /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ + hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang); + if (!hrsrc) return 0; + hmem = LoadResource( instance, hrsrc ); + if (!hmem) return 0; + + mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); + mre = NULL; + mrb = &(mrd->Blocks[0]); + for (i=mrd->NumberOfBlocks;i--;) { + if ((id>=mrb->LowId) && (id<=mrb->HighId)) { + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); + id -= mrb->LowId; + break; + } + mrb++; + } + if (!mre) + return 0; + for (i=id;i--;) { + if (!mre->Length) + return 0; + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length)); + } + slen=mre->Length; + TRACE(" - strlen=%d\n",slen); + i = min(buflen - 1, slen); + if (buffer == NULL) + return slen; + if (i>0) { + lstrcpynA(buffer,(char*)mre->Text,i); + buffer[i]=0; + } else { + if (buflen>1) { + buffer[0]=0; + return 0; + } + } + if (buffer) + TRACE("'%s' copied !\n", buffer); + return i; +} + + + +/********************************************************************** + * EnumResourceTypesA (KERNEL32.90) + */ +WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun, + LONG lParam) +{ + /* FIXME: move WINE_MODREF stuff here */ + return PE_EnumResourceTypesA(hmodule,lpfun,lParam); +} + +/********************************************************************** + * EnumResourceNamesA (KERNEL32.88) + */ +WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type, + ENUMRESNAMEPROCA lpfun, LONG lParam ) +{ + /* FIXME: move WINE_MODREF stuff here */ + return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam); +} +/********************************************************************** + * EnumResourceLanguagesA (KERNEL32.86) + */ +WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type, + LPCSTR name, ENUMRESLANGPROCA lpfun, + LONG lParam) +{ + /* FIXME: move WINE_MODREF stuff here */ + return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam); +} +/********************************************************************** + * LoadResource (KERNEL32.370) + */ +HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) +{ + return RES_LoadResource( hModule, hRsrc); +} diff --git a/linphone/win32acm/stubs.s b/linphone/win32acm/stubs.s new file mode 100644 index 000000000..24d99aa9b --- /dev/null +++ b/linphone/win32acm/stubs.s @@ -0,0 +1,35 @@ + .data +.LC0: .string "Called unk_%s\n" + .balign 4 +.globl unk_exp1 +unk_exp1: + pushl %ebp + movl %esp,%ebp + subl $4,%esp + movl $1,-4(%ebp) + movl -4(%ebp),%eax + movl %eax,%ecx + movl %ecx,%edx + sall $4,%edx + subl %eax,%edx + leal 0(,%edx,2),%eax + movl %eax,%edx + addl $export_names,%edx + pushl %edx + pushl $.LC0 + call printf + addl $8,%esp + xorl %eax,%eax + leave + ret +.globl exp_EH_prolog +exp_EH_prolog: + pushl $0xff + pushl %eax + pushl %fs:0 + movl %esp, %fs:0 + movl 12(%esp), %eax + movl %ebp, 12(%esp) + leal 12(%esp), %ebp + pushl %eax + ret diff --git a/linphone/win32acm/test_truespeech.c b/linphone/win32acm/test_truespeech.c new file mode 100644 index 000000000..1cf102490 --- /dev/null +++ b/linphone/win32acm/test_truespeech.c @@ -0,0 +1,438 @@ +/* test_truespeech.c + * + * Copyright 2003 Robert W. Brewer + * and based on some initial code to load the + * TrueSpeech DLL with these libraries by + * Piotr P. Karwasz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "loader.h" +#include "driver.h" +#include "wine/windef.h" +#include "wineacm.h" +#include "string.h" + +#define PCM_INFILE "pcmin.raw" +#define TS_OUTFILE "truespeechout.raw" +#define PCM_OUTFILE "pcmout.raw" + +int verbose=5; +char* get_path(char* x){ return strdup(x);} + +#define TRUESPEECH_FORMAT 0x22 +#define TRUESPEECH_CBSIZE 32 + +// Looks like entire .wav header for a TrueSpeech +// file is 90 bytes long. This means if we assume +// we have a TrueSpeech input file we can just skip +// the first 90 bytes instead of deleting them first +// with a hex editor to create a .raw file. + + + +void* xmalloc(size_t s) +{ + void* p = malloc(s); + if (!p) + { + printf("out of memory\n"); + exit(1); + } + + return p; +} + + +// infilepcm: 1 if infile is pcm, outfile is truespeech +// 0 if infile is truespeech, outfile is pcm +// Returns: +// 0: success +// 1: error +int convertfile(char* infile, char* outfile, int infilepcm) +{ + WAVEFORMATEX *ts_wf = 0; + WAVEFORMATEX pcm_wf; + WAVEFORMATEX *i_wf = 0; + WAVEFORMATEX *o_wf = 0; + HACMSTREAM handle; + MMRESULT ret; + DWORD srcsize = 0; + DWORD destsize = 0; + long* iptr = 0; + PWINE_ACMDRIVERID acmDriver1 = 0; + PWINE_ACMDRIVERID acmDriver2 = 0; + ACMSTREAMHEADER header; + FILE* i_file; + FILE* o_file; + + + // TrueSpeech format + ts_wf = xmalloc(sizeof(WAVEFORMATEX) + TRUESPEECH_CBSIZE); + memset(ts_wf, 0, sizeof(*ts_wf) + TRUESPEECH_CBSIZE); + + ts_wf->wFormatTag = TRUESPEECH_FORMAT; + ts_wf->nChannels = 1; + ts_wf->nSamplesPerSec = 8000; + ts_wf->wBitsPerSample = 1; + ts_wf->nBlockAlign = 32; + ts_wf->nAvgBytesPerSec = 1067; + ts_wf->cbSize = TRUESPEECH_CBSIZE; + + // write extra data needed by TrueSpeech codec found + // from examining a TrueSpeech .wav file header + iptr = (long*)(ts_wf + 1); + *iptr = 0x00f00001; + +// print_wave_header(in_fmt); + + // Typical PCM format, 16-bit signed samples at 8 KHz. + memset(&pcm_wf, 0, sizeof(pcm_wf)); + + pcm_wf.wFormatTag = WAVE_FORMAT_PCM; + pcm_wf.nChannels = 1; + pcm_wf.nSamplesPerSec = 8000; + pcm_wf.wBitsPerSample = 16; + pcm_wf.nBlockAlign = pcm_wf.nChannels * pcm_wf.wBitsPerSample / 8; + pcm_wf.nAvgBytesPerSec = pcm_wf.nSamplesPerSec * pcm_wf.nBlockAlign; + +// print_wave_header(priv->o_wf); + + // decide which way to perform the conversion + if (infilepcm) + { + i_wf = &pcm_wf; + o_wf = ts_wf; + } + else + { + i_wf = ts_wf; + o_wf = &pcm_wf; + } + + // from here on out, everything is pretty generic as long as we + // use i_wf and o_wf + + acmDriver1 = MSACM_RegisterDriver("tssoft32.acm", TRUESPEECH_FORMAT, 0); + if (!acmDriver1) + { + printf("error registering TrueSpeech ACM driver for TrueSpeech\n"); + return 1; + } + + printf("register driver complete for truespeech\n"); + + + acmDriver2 = MSACM_RegisterDriver("tssoft32.acm", WAVE_FORMAT_PCM, 0); + if (!acmDriver2) + { + printf("error registering TrueSpeech ACM driver for PCM\n"); + return 1; + } + + printf("register driver complete for pcm\n"); + + // TrueSpeech isn't confident it can do realtime + // compression. Tell it we don't care and it's happy. + ret = acmStreamOpen(&handle, 0, i_wf, o_wf, 0, 0, 0, + ACM_STREAMOPENF_NONREALTIME); + if (ret) + { + if (ret == ACMERR_NOTPOSSIBLE) + { + printf("invalid codec\n"); + } + else + { + printf("acmStreamOpen error %d\n", ret); + } + + return 1; + } + + printf("audio codec opened\n"); + + // we assume that the format with the largest block alignment is + // the most picky. And it basically turns out that TrueSpeech has + // the largest block alignment. Anyway, we use that block alignment + // to ask for the preferred size of the "other" format's buffer. + // Then we turn around and ask for the first one's preferred buffer + // size based on the other's buffer size, which seems to turn out + // to be its block alignment. Or something like that. + if (i_wf->nBlockAlign > o_wf->nBlockAlign) + { + ret = acmStreamSize(handle, i_wf->nBlockAlign, &destsize, ACM_STREAMSIZEF_SOURCE); + if (ret) + { + printf("acmStreamSize error %d\n", ret); + return 1; + } + + printf("Audio ACM output buffer min. size: %ld\n", destsize); + if (!destsize) + { + printf("ACM codec reports destsize=0\n"); + return 1; + } + + ret = acmStreamSize(handle, destsize, &srcsize, ACM_STREAMSIZEF_DESTINATION); + if (ret) + { + printf("acmStreamSize error\n"); + return 1; + } + + printf("Audio ACM input buffer min. size: %ld\n", srcsize); + } + else + { + ret = acmStreamSize(handle, o_wf->nBlockAlign, &srcsize, ACM_STREAMSIZEF_DESTINATION); + if (ret) + { + printf("acmStreamSize error %d\n", ret); + return 1; + } + + printf("Audio ACM input buffer min. size: %ld\n", srcsize); + if (!srcsize) + { + printf("ACM codec reports srcsize=0\n"); + return 1; + } + + ret = acmStreamSize(handle, srcsize, &destsize, ACM_STREAMSIZEF_SOURCE); + if (ret) + { + printf("acmStreamSize error\n"); + return 1; + } + + printf("Audio ACM input buffer min. size: %ld\n", destsize); + } + + + // set up conversion buffers + + memset(&header, 0, sizeof(header)); + header.cbStruct = sizeof(header); + header.cbSrcLength = srcsize; + header.pbSrc = xmalloc(header.cbSrcLength); + header.cbDstLength = destsize; + header.pbDst = xmalloc(header.cbDstLength); + + ret = acmStreamPrepareHeader(handle, &header, 0); + if (ret) + { + printf("error preparing header\n"); + return 1; + } + + printf("header prepared %lx\n", header.fdwStatus); + + + // open files + i_file = fopen(infile, "rb"); + if (!i_file) + { + printf("error opening input file %s\n", infile); + return 1; + } + + printf("input file opened\n"); + + + o_file = fopen(outfile, "wb"); + if (!o_file) + { + printf("error opening output file %s\n", outfile); + return 1; + } + + + printf("output file opened\n"); + + int inbytes = 0; + + while (1) + { + inbytes = fread(header.pbSrc, 1, srcsize, i_file); + + if (inbytes != srcsize) + { + if (feof(i_file)) + { + printf("end of input file, last byte count %d\n", inbytes); + break; + } + + printf("read error\n"); + return 1; + } + + ret = acmStreamConvert(handle, &header, ACM_STREAMCONVERTF_BLOCKALIGN); + if (ret) + { + printf("conversion error\n"); + return 1; + } + + if (!(header.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)) + { + printf("header not marked done %lx\n", header.fdwStatus); + return 1; + } + + if (header.cbSrcLengthUsed != header.cbSrcLength) + { + printf("didn't use all of source data\n"); + return 1; + } + + printf("converted %d bytes to %d bytes\n", + header.cbSrcLengthUsed, + header.cbDstLengthUsed); + + if (fwrite(header.pbDst, 1, header.cbDstLengthUsed, o_file) != + header.cbDstLengthUsed) + { + printf("error writing file\n"); + return 1; + } + } + + // now convert the remaining bit of the file + // and ask for any leftover stuff + + header.cbSrcLength = inbytes; + while (1) + { + if (header.cbSrcLength) + { + // not a full block, but not quite the "end" either + ret = acmStreamConvert(handle, &header, 0); + } + else + { + // now we're at the end, let's see if anything is left + ret = acmStreamConvert(handle, &header, ACM_STREAMCONVERTF_END); + } + + if (ret) + { + printf("conversion error\n"); + return 1; + } + + if (!(header.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)) + { + printf("header not marked done %lx\n", header.fdwStatus); + return 1; + } + + if (header.cbSrcLengthUsed != header.cbSrcLength) + { + printf("didn't use all of source data\n"); + return 1; + } + + printf("converted %d bytes to %d bytes\n", + header.cbSrcLengthUsed, + header.cbDstLengthUsed); + + if (!header.cbDstLengthUsed) + { + printf("nothing given to output, must be done\n"); + break; + } + + if (fwrite(header.pbDst, 1, header.cbDstLengthUsed, o_file) != + header.cbDstLengthUsed) + { + printf("error writing file\n"); + return 1; + } + + // ensure we are getting the remaining stuff on the next time around + header.cbSrcLength = 0; + } + + + printf("finished converting file\n"); + + + // now close up shop + + fclose(i_file); + fclose(o_file); + + ret = acmStreamUnprepareHeader(handle, &header, 0); + if (ret) + { + printf("error unpreparing header\n"); + return 1; + } + + free(header.pbSrc); + free(header.pbDst); + + + ret = acmStreamClose(handle, 0); + if (ret) + { + printf("error closing acm stream\n"); + return 1; + } + + printf("acm stream closed\n"); + + MSACM_UnregisterDriver(acmDriver1); + + printf("acm driver unregistered for truespeech\n"); + + MSACM_UnregisterDriver(acmDriver2); + + printf("acm driver unregistered for pcm\n"); + + free(ts_wf); + + return 0; +} + + +int main (int argc, char **argv) +{ + printf("converting pcm to truespeech\n"); + + if (convertfile(PCM_INFILE, TS_OUTFILE, 1)) + { + printf("error converting pcm -> truespeech\n"); + return 1; + } + + printf("converting truespeech to pcm\n"); + + if (convertfile(TS_OUTFILE, PCM_OUTFILE, 0)) + { + printf("error converting truespeech -> pcm\n"); + return 1; + } + + printf("all done\n"); + + return 0; +} diff --git a/linphone/win32acm/win32.c b/linphone/win32acm/win32.c new file mode 100644 index 000000000..726aecd91 --- /dev/null +++ b/linphone/win32acm/win32.c @@ -0,0 +1,5184 @@ +/*********************************************************** + +Win32 emulation code. Functions that emulate +responses from corresponding Win32 API calls. +Since we are not going to be able to load +virtually any DLL, we can only implement this +much, adding needed functions with each new codec. + +Basic principle of implementation: it's not good +for DLL to know too much about its environment. + +************************************************************/ + +#include "config.h" + +#ifdef MPLAYER +#ifdef USE_QTX_CODECS +#define QTX +#endif +#define REALPLAYER +//#define LOADLIB_TRY_NATIVE +#endif + +#ifdef QTX +#define PSEUDO_SCREEN_WIDTH /*640*/800 +#define PSEUDO_SCREEN_HEIGHT /*480*/600 +#endif + +#include "wine/winbase.h" +#include "wine/winreg.h" +#include "wine/winnt.h" +#include "wine/winerror.h" +#include "wine/debugtools.h" +#include "wine/module.h" +#include "wine/winuser.h" + +#include +#include "win32.h" + +#include "registry.h" +#include "loader.h" +#include "com.h" +#include "ext.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_KSTAT +#include +#endif + +#if HAVE_VSSCANF +int vsscanf( const char *str, const char *format, va_list ap); +#else +/* system has no vsscanf. try to provide one */ +static int vsscanf( const char *str, const char *format, va_list ap) +{ + long p1 = va_arg(ap, long); + long p2 = va_arg(ap, long); + long p3 = va_arg(ap, long); + long p4 = va_arg(ap, long); + long p5 = va_arg(ap, long); + return sscanf(str, format, p1, p2, p3, p4, p5); +} +#endif + +char* def_path = WIN32_PATH; + +static void do_cpuid(unsigned int ax, unsigned int *regs) +{ + __asm__ __volatile__ + ( + "pushl %%ebx; pushl %%ecx; pushl %%edx;" + ".byte 0x0f, 0xa2;" + "movl %%eax, (%2);" + "movl %%ebx, 4(%2);" + "movl %%ecx, 8(%2);" + "movl %%edx, 12(%2);" + "popl %%edx; popl %%ecx; popl %%ebx;" + : "=a" (ax) + : "0" (ax), "S" (regs) + ); +} +static unsigned int c_localcount_tsc() +{ + int a; + __asm__ __volatile__ + ( + "rdtsc\n\t" + :"=a"(a) + : + :"edx" + ); + return a; +} +static void c_longcount_tsc(long long* z) +{ + __asm__ __volatile__ + ( + "pushl %%ebx\n\t" + "movl %%eax, %%ebx\n\t" + "rdtsc\n\t" + "movl %%eax, 0(%%ebx)\n\t" + "movl %%edx, 4(%%ebx)\n\t" + "popl %%ebx\n\t" + ::"a"(z) + ); +} +static unsigned int c_localcount_notsc() +{ + struct timeval tv; + unsigned limit=~0; + limit/=1000000; + gettimeofday(&tv, 0); + return limit*tv.tv_usec; +} +static void c_longcount_notsc(long long* z) +{ + struct timeval tv; + unsigned long long result; + unsigned limit=~0; + if(!z)return; + limit/=1000000; + gettimeofday(&tv, 0); + result=tv.tv_sec; + result<<=32; + result+=limit*tv.tv_usec; + *z=result; +} +static unsigned int localcount_stub(void); +static void longcount_stub(long long*); +static unsigned int (*localcount)()=localcount_stub; +static void (*longcount)(long long*)=longcount_stub; + +static pthread_mutex_t memmut; + +static unsigned int localcount_stub(void) +{ + unsigned int regs[4]; + do_cpuid(1, regs); + if ((regs[3] & 0x00000010) != 0) + { + localcount=c_localcount_tsc; + longcount=c_longcount_tsc; + } + else + { + localcount=c_localcount_notsc; + longcount=c_longcount_notsc; + } + return localcount(); +} +static void longcount_stub(long long* z) +{ + unsigned int regs[4]; + do_cpuid(1, regs); + if ((regs[3] & 0x00000010) != 0) + { + localcount=c_localcount_tsc; + longcount=c_longcount_tsc; + } + else + { + localcount=c_localcount_notsc; + longcount=c_longcount_notsc; + } + longcount(z); +} + +#ifdef MPLAYER +#include "mp_msg.h" +#endif +int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT +//#define DETAILED_OUT +static inline void dbgprintf(char* fmt, ...) +{ +#ifdef DETAILED_OUT + if(LOADER_DEBUG) + { + FILE* f; + va_list va; + va_start(va, fmt); + f=fopen("./log", "a"); + vprintf(fmt, va); + fflush(stdout); + if(f) + { + vfprintf(f, fmt, va); + fsync(fileno(f)); + fclose(f); + } + va_end(va); + } +#endif +#ifdef MPLAYER + if (verbose > 2) + { + va_list va; + + va_start(va, fmt); + vprintf(fmt, va); +// mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va); + va_end(va); + } + fflush(stdout); +#endif +} + + +char export_names[300][32]={ + "name1", + //"name2", + //"name3" +}; +//#define min(x,y) ((x)<(y)?(x):(y)) + +void destroy_event(void* event); + +struct th_list_t; +typedef struct th_list_t{ + int id; + void* thread; + struct th_list_t* next; + struct th_list_t* prev; +} th_list; + + +// have to be cleared by GARBAGE COLLECTOR +static unsigned char* heap=NULL; +static int heap_counter=0; +static tls_t* g_tls=NULL; +static th_list* list=NULL; + +static void test_heap(void) +{ + int offset=0; + if(heap==0) + return; + while(offset20000000) + { + printf("No enough memory\n"); + return 0; + } + *(int*)(heap+heap_counter)=0x433476; + heap_counter+=4; + *(int*)(heap+heap_counter)=size; + heap_counter+=4; + printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size); + if(to_zero) + memset(heap+heap_counter, 0, size); + else + memset(heap+heap_counter, 0xcc, size); // make crash reproducable + heap_counter+=size; + return heap+heap_counter-size; +} +static int my_release(char* memory) +{ + // test_heap(); + if(memory==NULL) + { + printf("ERROR: free(0)\n"); + return 0; + } + if(*(int*)(memory-8)!=0x433476) + { + printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n"); + return 0; + } + printf("Freed %d bytes of memory\n", *(int*)(memory-4)); + // memset(memory-8, *(int*)(memory-4), 0xCC); + return 0; +} + +#else +#define GARBAGE +typedef struct alloc_header_t alloc_header; +struct alloc_header_t +{ + // let's keep allocated data 16 byte aligned + alloc_header* prev; + alloc_header* next; + long deadbeef; + long size; + long type; + long reserved1; + long reserved2; + long reserved3; +}; + +#ifdef GARBAGE +static alloc_header* last_alloc = NULL; +static int alccnt = 0; +#endif + +#define AREATYPE_CLIENT 0 +#define AREATYPE_EVENT 1 +#define AREATYPE_MUTEX 2 +#define AREATYPE_COND 3 +#define AREATYPE_CRITSECT 4 + +/* -- critical sections -- */ +struct CRITSECT +{ + pthread_t id; + pthread_mutex_t mutex; + int locked; + long deadbeef; +}; + +void* mreq_private(int size, int to_zero, int type); +void* mreq_private(int size, int to_zero, int type) +{ + int nsize = size + sizeof(alloc_header); + alloc_header* header = (alloc_header* ) malloc(nsize); + if (!header) + return 0; + if (to_zero) + memset(header, 0, nsize); +#ifdef GARBAGE + if (!last_alloc) + { + pthread_mutex_init(&memmut, NULL); + pthread_mutex_lock(&memmut); + } + else + { + pthread_mutex_lock(&memmut); + last_alloc->next = header; /* set next */ + } + + header->prev = last_alloc; + header->next = 0; + last_alloc = header; + alccnt++; + pthread_mutex_unlock(&memmut); +#endif + header->deadbeef = 0xdeadbeef; + header->size = size; + header->type = type; + + //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt); + return header + 1; +} + +static int my_release(void* memory) +{ + alloc_header* header = (alloc_header*) memory - 1; +#ifdef GARBAGE + alloc_header* prevmem; + alloc_header* nextmem; + + if (memory == 0) + return 0; + + if (header->deadbeef != (long) 0xdeadbeef) + { + printf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); + return 0; + } + + pthread_mutex_lock(&memmut); + + switch(header->type) + { + case AREATYPE_EVENT: + destroy_event(memory); + break; + case AREATYPE_COND: + pthread_cond_destroy((pthread_cond_t*)memory); + break; + case AREATYPE_MUTEX: + pthread_mutex_destroy((pthread_mutex_t*)memory); + break; + case AREATYPE_CRITSECT: + pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex); + break; + default: + //memset(memory, 0xcc, header->size); + ; + } + + header->deadbeef = 0; + prevmem = header->prev; + nextmem = header->next; + + if (prevmem) + prevmem->next = nextmem; + if (nextmem) + nextmem->prev = prevmem; + + if (header == last_alloc) + last_alloc = prevmem; + + alccnt--; + + if (last_alloc) + pthread_mutex_unlock(&memmut); + else + pthread_mutex_destroy(&memmut); + + //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt); +#else + if (memory == 0) + return 0; +#endif + //memset(header + 1, 0xcc, header->size); + free(header); + return 0; +} +#endif + +static inline void* my_mreq(int size, int to_zero) +{ + return mreq_private(size, to_zero, AREATYPE_CLIENT); +} + +static int my_size(void* memory) +{ + if(!memory) return 0; + return ((alloc_header*)memory)[-1].size; +} + +static void* my_realloc(void* memory, int size) +{ + void *ans = memory; + int osize; + if (memory == NULL) + return my_mreq(size, 0); + osize = my_size(memory); + if (osize < size) + { + ans = my_mreq(size, 0); + memcpy(ans, memory, osize); + my_release(memory); + } + return ans; +} + +/* + * + * WINE API - native implementation for several win32 libraries + * + */ + +static int WINAPI ext_unknown() +{ + printf("Unknown func called\n"); + return 0; +} + +static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) +{ + int result = (count == 0 || ptr != 0) ? 0 : 1; + dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result); + return result; +} +static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count) +{ + int result = (count == 0 || ptr != 0) ? 0 : 1; + dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result); + return result; +} +static int WINAPI expDisableThreadLibraryCalls(int module) +{ + dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module); + return 0; +} + +static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv) +{ + HMODULE result; + if (pdrv==NULL) + result=0; + else + result=pdrv->hDriverModule; + dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result); + return result; +} + +#define MODULE_HANDLE_kernel32 ((HMODULE)0x120) +#define MODULE_HANDLE_user32 ((HMODULE)0x121) +#ifdef QTX +#define MODULE_HANDLE_wininet ((HMODULE)0x122) +#define MODULE_HANDLE_ddraw ((HMODULE)0x123) +#define MODULE_HANDLE_advapi32 ((HMODULE)0x124) +#endif + +static HMODULE WINAPI expGetModuleHandleA(const char* name) +{ + WINE_MODREF* wm; + HMODULE result; + if(!name) +#ifdef QTX + result=1; +#else + result=0; +#endif + else + { + wm=MODULE_FindModule(name); + if(wm==0)result=0; + else + result=(HMODULE)(wm->module); + } + if(!result) + { + if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll"))) + result=MODULE_HANDLE_kernel32; +#ifdef QTX + if(name && strcasecmp(name, "user32")==0) + result=MODULE_HANDLE_user32; +#endif + } + dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); + return result; +} + +static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, + void* lpStartAddress, void* lpParameter, + long dwFlags, long* dwThreadId) +{ + pthread_t *pth; + // printf("CreateThread:"); + pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0); + pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); + if(dwFlags) + printf( "WARNING: CreateThread flags not supported\n"); + if(dwThreadId) + *dwThreadId=(long)pth; + if(list==NULL) + { + list=my_mreq(sizeof(th_list), 1); + list->next=list->prev=NULL; + } + else + { + list->next=my_mreq(sizeof(th_list), 0); + list->next->prev=list; + list->next->next=NULL; + list=list->next; + } + list->thread=pth; + dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n", + pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); + return pth; +} + +struct mutex_list_t; + +struct mutex_list_t +{ + char type; + pthread_mutex_t *pm; + pthread_cond_t *pc; + char state; + char reset; + char name[128]; + int semaphore; + struct mutex_list_t* next; + struct mutex_list_t* prev; +}; +typedef struct mutex_list_t mutex_list; +static mutex_list* mlist=NULL; + +void destroy_event(void* event) +{ + mutex_list* pp=mlist; + // printf("garbage collector: destroy_event(%x)\n", event); + while(pp) + { + if(pp==(mutex_list*)event) + { + if(pp->next) + pp->next->prev=pp->prev; + if(pp->prev) + pp->prev->next=pp->next; + if(mlist==(mutex_list*)event) + mlist=mlist->prev; + /* + pp=mlist; + while(pp) + { + printf("%x => ", pp); + pp=pp->prev; + } + printf("0\n"); + */ + return; + } + pp=pp->prev; + } +} + +static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, + char bInitialState, const char* name) +{ + pthread_mutex_t *pm; + pthread_cond_t *pc; + /* + mutex_list* pp; + pp=mlist; + while(pp) + { + printf("%x => ", pp); + pp=pp->prev; + } + printf("0\n"); + */ + if(mlist!=NULL) + { + mutex_list* pp=mlist; + if(name!=NULL) + do + { + if((strcmp(pp->name, name)==0) && (pp->type==0)) + { + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", + pSecAttr, bManualReset, bInitialState, name, name, pp->pm); + return pp->pm; + } + }while((pp=pp->prev) != NULL); + } + pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); + pthread_mutex_init(pm, NULL); + pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); + pthread_cond_init(pc, NULL); + if(mlist==NULL) + { + mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next=mlist->prev=NULL; + } + else + { + mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next->prev=mlist; + mlist->next->next=NULL; + mlist=mlist->next; + } + mlist->type=0; /* Type Event */ + mlist->pm=pm; + mlist->pc=pc; + mlist->state=bInitialState; + mlist->reset=bManualReset; + if(name) + strncpy(mlist->name, name, 127); + else + mlist->name[0]=0; + if(pm==NULL) + dbgprintf("ERROR::: CreateEventA failure\n"); + /* + if(bInitialState) + pthread_mutex_lock(pm); + */ + if(name) + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", + pSecAttr, bManualReset, bInitialState, name, name, mlist); + else + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n", + pSecAttr, bManualReset, bInitialState, mlist); + return mlist; +} + +static void* WINAPI expSetEvent(void* event) +{ + mutex_list *ml = (mutex_list *)event; + dbgprintf("SetEvent(%x) => 0x1\n", event); + pthread_mutex_lock(ml->pm); + if (ml->state == 0) { + ml->state = 1; + pthread_cond_signal(ml->pc); + } + pthread_mutex_unlock(ml->pm); + + return (void *)1; +} +static void* WINAPI expResetEvent(void* event) +{ + mutex_list *ml = (mutex_list *)event; + dbgprintf("ResetEvent(0x%x) => 0x1\n", event); + pthread_mutex_lock(ml->pm); + ml->state = 0; + pthread_mutex_unlock(ml->pm); + + return (void *)1; +} + +static void* WINAPI expWaitForSingleObject(void* object, int duration) +{ + mutex_list *ml = (mutex_list *)object; + // FIXME FIXME FIXME - this value is sometime unititialize !!! + int ret = WAIT_FAILED; + mutex_list* pp=mlist; + if(object == (void*)0xcfcf9898) + { + /** + From GetCurrentThread() documentation: + A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes. + + This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS. + + The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function. + **/ + dbgprintf("WaitForSingleObject(thread_handle) called\n"); + return (void*)WAIT_FAILED; + } + dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration); + + // loop below was slightly fixed - its used just for checking if + // this object really exists in our list + if (!ml) + return (void*) ret; + while (pp && (pp->pm != ml->pm)) + pp = pp->prev; + if (!pp) { + dbgprintf("WaitForSingleObject: NotFound\n"); + return (void*)ret; + } + + pthread_mutex_lock(ml->pm); + + switch(ml->type) { + case 0: /* Event */ + if (duration == 0) { /* Check Only */ + if (ml->state == 1) ret = WAIT_FAILED; + else ret = WAIT_OBJECT_0; + } + if (duration == -1) { /* INFINITE */ + if (ml->state == 0) + pthread_cond_wait(ml->pc,ml->pm); + if (ml->reset) + ml->state = 0; + ret = WAIT_OBJECT_0; + } + if (duration > 0) { /* Timed Wait */ + struct timespec abstime; + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000; + abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000; + if (ml->state == 0) + ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime); + if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT; + else ret = WAIT_OBJECT_0; + if (ml->reset) + ml->state = 0; + } + break; + case 1: /* Semaphore */ + if (duration == 0) { + if(ml->semaphore==0) ret = WAIT_FAILED; + else { + ml->semaphore++; + ret = WAIT_OBJECT_0; + } + } + if (duration == -1) { + if (ml->semaphore==0) + pthread_cond_wait(ml->pc,ml->pm); + ml->semaphore--; + } + break; + } + pthread_mutex_unlock(ml->pm); + + dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret); + return (void *)ret; +} + +#ifdef QTX +static void* WINAPI expWaitForMultipleObjects(int count, const void** objects, + int WaitAll, int duration) +{ + int i; + void *object; + void *ret; + + dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n", + count, objects, WaitAll, duration); + + for (i = 0; i < count; i++) + { + object = objects[i]; + ret = expWaitForSingleObject(object, duration); + if (WaitAll) + dbgprintf("WaitAll flag not yet supported...\n"); + else + return ret; + } + return NULL; +} + +static void WINAPI expExitThread(int retcode) +{ + dbgprintf("ExitThread(%d)\n", retcode); + pthread_exit(&retcode); +} + +static HANDLE WINAPI expCreateMutexA(void *pSecAttr, + char bInitialOwner, const char *name) +{ + HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name); + + if (name) + dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", + pSecAttr, bInitialOwner, name, mlist); + else + dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n", + pSecAttr, bInitialOwner, mlist); +#ifndef QTX + /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject + waits for ever, else it works ;) */ + return mlist; +#endif +} + +static int WINAPI expReleaseMutex(HANDLE hMutex) +{ + dbgprintf("ReleaseMutex(%x) => 1\n", hMutex); + /* FIXME:XXX !! not yet implemented */ + return 1; +} +#endif + +static int pf_set = 0; +static BYTE PF[64] = {0,}; + +static void DumpSystemInfo(const SYSTEM_INFO* si) +{ + dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); + dbgprintf(" Page size: %d\n", si->dwPageSize); + dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress); + dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress); + dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask); + dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors); + dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType); + dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity); + dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel); + dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision); +} + +static void WINAPI expGetSystemInfo(SYSTEM_INFO* si) +{ + /* FIXME: better values for the two entries below... */ + static int cache = 0; + static SYSTEM_INFO cachedsi; + unsigned int regs[4]; + dbgprintf("GetSystemInfo(%p) =>\n", si); + + if (cache) { + memcpy(si,&cachedsi,sizeof(*si)); + DumpSystemInfo(si); + return; + } + memset(PF,0,sizeof(PF)); + pf_set = 1; + + cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; + cachedsi.dwPageSize = getpagesize(); + + /* FIXME: better values for the two entries below... */ + cachedsi.lpMinimumApplicationAddress = (void *)0x00000000; + cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; + cachedsi.dwActiveProcessorMask = 1; + cachedsi.dwNumberOfProcessors = 1; + cachedsi.dwProcessorType = PROCESSOR_INTEL_386; + cachedsi.dwAllocationGranularity = 0x10000; + cachedsi.wProcessorLevel = 5; /* pentium */ + cachedsi.wProcessorRevision = 0x0101; + +#ifdef MPLAYER + /* mplayer's way to detect PF's */ + { +#include "cpudetect.h" + extern CpuCaps gCpuCaps; + + if (gCpuCaps.hasMMX) + PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; + if (gCpuCaps.hasSSE) + PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; + if (gCpuCaps.has3DNow) + PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; + + switch(gCpuCaps.cpuType) + { + case CPUTYPE_I686: + case CPUTYPE_I586: + cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel = 5; + break; + case CPUTYPE_I486: + cachedsi.dwProcessorType = PROCESSOR_INTEL_486; + cachedsi.wProcessorLevel = 4; + break; + case CPUTYPE_I386: + default: + cachedsi.dwProcessorType = PROCESSOR_INTEL_386; + cachedsi.wProcessorLevel = 3; + break; + } + cachedsi.wProcessorRevision = gCpuCaps.cpuStepping; + cachedsi.dwNumberOfProcessors = 1; /* hardcoded */ + + } +#endif + +/* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */ +#ifndef MPLAYER +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) + do_cpuid(1, regs); + switch ((regs[0] >> 8) & 0xf) { // cpu family + case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; + cachedsi.wProcessorLevel= 3; + break; + case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; + cachedsi.wProcessorLevel= 4; + break; + case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + } + cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping + if (regs[3] & (1 << 8)) + PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; + if (regs[3] & (1 << 23)) + PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; + if (regs[3] & (1 << 25)) + PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; + if (regs[3] & (1 << 31)) + PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; + cachedsi.dwNumberOfProcessors=1; +#endif +#endif /* MPLAYER */ + +/* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking + fdiv_bug and fpu emulation flags -- alex/MPlayer */ +#ifdef __linux__ + { + char buf[20]; + char line[200]; + FILE *f = fopen ("/proc/cpuinfo", "r"); + + if (!f) + return; + while (fgets(line,200,f)!=NULL) { + char *s,*value; + + /* NOTE: the ':' is the only character we can rely on */ + if (!(value = strchr(line,':'))) + continue; + /* terminate the valuename */ + *value++ = '\0'; + /* skip any leading spaces */ + while (*value==' ') value++; + if ((s=strchr(value,'\n'))) + *s='\0'; + + /* 2.1 method */ + if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) { + if (isdigit (value[0])) { + switch (value[0] - '0') { + case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; + cachedsi.wProcessorLevel= 3; + break; + case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; + cachedsi.wProcessorLevel= 4; + break; + case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + } + } + /* set the CPU type of the current processor */ + sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); + continue; + } + /* old 2.0 method */ + if (!lstrncmpiA(line, "cpu",strlen("cpu"))) { + if ( isdigit (value[0]) && value[1] == '8' && + value[2] == '6' && value[3] == 0 + ) { + switch (value[0] - '0') { + case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; + cachedsi.wProcessorLevel= 3; + break; + case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; + cachedsi.wProcessorLevel= 4; + break; + case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; + cachedsi.wProcessorLevel= 5; + break; + } + } + /* set the CPU type of the current processor */ + sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); + continue; + } + if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) { + if (!lstrncmpiA(value,"yes",3)) + PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; + + continue; + } + if (!lstrncmpiA(line,"fpu",strlen("fpu"))) { + if (!lstrncmpiA(value,"no",2)) + PF[PF_FLOATING_POINT_EMULATED] = TRUE; + + continue; + } + if (!lstrncmpiA(line,"processor",strlen("processor"))) { + /* processor number counts up...*/ + unsigned int x; + + if (sscanf(value,"%d",&x)) + if (x+1>cachedsi.dwNumberOfProcessors) + cachedsi.dwNumberOfProcessors=x+1; + + /* Create a new processor subkey on a multiprocessor + * system + */ + sprintf(buf,"%d",x); + } + if (!lstrncmpiA(line,"stepping",strlen("stepping"))) { + int x; + + if (sscanf(value,"%d",&x)) + cachedsi.wProcessorRevision = x; + } + if + ( (!lstrncmpiA(line,"flags",strlen("flags"))) + || (!lstrncmpiA(line,"features",strlen("features"))) ) + { + if (strstr(value,"cx8")) + PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; + if (strstr(value,"mmx")) + PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; + if (strstr(value,"tsc")) + PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; + if (strstr(value,"xmm")) + PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; + if (strstr(value,"3dnow")) + PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; + } + } + fclose (f); + /* + * ad hoc fix for smp machines. + * some problems on WaitForSingleObject,CreateEvent,SetEvent + * CreateThread ...etc.. + * + */ + cachedsi.dwNumberOfProcessors=1; + } +#endif /* __linux__ */ + cache = 1; + memcpy(si,&cachedsi,sizeof(*si)); + DumpSystemInfo(si); +} + +// avoid undefined expGetSystemInfo +static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) +{ + WIN_BOOL result = 0; + if (!pf_set) + { + SYSTEM_INFO si; + expGetSystemInfo(&si); + } + if(v<64) result=PF[v]; + dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); + return result; +} + + +static long WINAPI expGetVersion() +{ + dbgprintf("GetVersion() => 0xC0000004\n"); + return 0xC0000004;//Windows 95 +} + +static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size) +{ + // printf("HeapCreate:"); + HANDLE result; + if(init_size==0) + result=(HANDLE)my_mreq(0x110000, 0); + else + result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0); + dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result); + return result; +} + +// this is another dirty hack +// VP31 is releasing one allocated Heap chunk twice +// we will silently ignore this second call... +static void* heapfreehack = 0; +static int heapfreehackshown = 0; +//extern void trapbug(void); +static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size) +{ + void* z; + /** + Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for + HeapAlloc returns area larger than size argument :-/ + + actually according to M$ Doc HeapCreate size should be rounded + to page boundaries thus we should simulate this + **/ + //if (size == 22276) trapbug(); + z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY)); + if(z==0) + printf("HeapAlloc failure\n"); + dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z); + heapfreehack = 0; // reset + return z; +} +static long WINAPI expHeapDestroy(void* heap) +{ + dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap); + my_release(heap); + return 1; +} + +static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem) +{ + dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem); + if (heapfreehack != lpMem && lpMem != (void*)0xffffffff + && lpMem != (void*)0xbdbdbdbd) + // 0xbdbdbdbd is for i263_drv.drv && libefence + // it seems to be reading from relased memory + // EF_PROTECT_FREE doens't show any probleme + my_release(lpMem); + else + { + if (!heapfreehackshown++) + printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem); + } + heapfreehack = lpMem; + return 1; +} +static long WINAPI expHeapSize(int heap, int flags, void* pointer) +{ + long result=my_size(pointer); + dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result); + return result; +} +static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size) +{ + long orgsize = my_size(lpMem); + dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size); + return my_realloc(lpMem, size); +} +static long WINAPI expGetProcessHeap(void) +{ + dbgprintf("GetProcessHeap() => 1\n"); + return 1; +} +static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4) +{ + void* z = VirtualAlloc(v1, v2, v3, v4); + if(z==0) + printf("VirtualAlloc failure\n"); + dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z); + return z; +} +static int WINAPI expVirtualFree(void* v1, int v2, int v3) +{ + int result = VirtualFree(v1,v2,v3); + dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result); + return result; +} + +/* we're building a table of critical sections. cs_win pointer uses the DLL + cs_unix is the real structure, we're using cs_win only to identifying cs_unix */ +struct critsecs_list_t +{ + CRITICAL_SECTION *cs_win; + struct CRITSECT *cs_unix; +}; + +/* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */ +#undef CRITSECS_NEWTYPE +//#define CRITSECS_NEWTYPE 1 + +#ifdef CRITSECS_NEWTYPE +/* increased due to ucod needs more than 32 entries */ +/* and 64 should be enough for everything */ +#define CRITSECS_LIST_MAX 64 +static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX]; + +static int critsecs_get_pos(CRITICAL_SECTION *cs_win) +{ + int i; + + for (i=0; i < CRITSECS_LIST_MAX; i++) + if (critsecs_list[i].cs_win == cs_win) + return(i); + return(-1); +} + +static int critsecs_get_unused(void) +{ + int i; + + for (i=0; i < CRITSECS_LIST_MAX; i++) + if (critsecs_list[i].cs_win == NULL) + return(i); + return(-1); +} + +struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win) +{ + int i; + + for (i=0; i < CRITSECS_LIST_MAX; i++) + if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix) + return(critsecs_list[i].cs_unix); + return(NULL); +} +#endif + +static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) +{ + dbgprintf("InitializeCriticalSection(0x%x)\n", c); + /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) + { + printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", + sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION)); + return; + }*/ + /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */ +#ifdef CRITSECS_NEWTYPE + { + struct CRITSECT *cs; + int i = critsecs_get_unused(); + + if (i < 0) + { + printf("InitializeCriticalSection(%p) - no more space in list\n", c); + return; + } + dbgprintf("got unused space at %d\n", i); + cs = malloc(sizeof(struct CRITSECT)); + if (!cs) + { + printf("InitializeCriticalSection(%p) - out of memory\n", c); + return; + } + pthread_mutex_init(&cs->mutex, NULL); + cs->locked = 0; + critsecs_list[i].cs_win = c; + critsecs_list[i].cs_unix = cs; + dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n", + i, c, cs); + } +#else + { + struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION), + 0, AREATYPE_CRITSECT); + pthread_mutex_init(&cs->mutex, NULL); + cs->locked=0; + cs->deadbeef = 0xdeadbeef; + *(void**)c = cs; + } +#endif + return; +} + +static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) +{ +#ifdef CRITSECS_NEWTYPE + struct CRITSECT* cs = critsecs_get_unix(c); +#else + struct CRITSECT* cs = (*(struct CRITSECT**)c); +#endif + dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs); + if (!cs) + { + dbgprintf("entered uninitialized critisec!\n"); + expInitializeCriticalSection(c); +#ifdef CRITSECS_NEWTYPE + cs=critsecs_get_unix(c); +#else + cs = (*(struct CRITSECT**)c); +#endif + printf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c); + } + if(cs->locked) + if(cs->id==pthread_self()) + return; + pthread_mutex_lock(&(cs->mutex)); + cs->locked=1; + cs->id=pthread_self(); + return; +} +static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) +{ +#ifdef CRITSECS_NEWTYPE + struct CRITSECT* cs = critsecs_get_unix(c); +#else + struct CRITSECT* cs = (*(struct CRITSECT**)c); +#endif + // struct CRITSECT* cs=(struct CRITSECT*)c; + dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs); + if (!cs) + { + printf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c); + return; + } + cs->locked=0; + pthread_mutex_unlock(&(cs->mutex)); + return; +} + +static void expfree(void* mem); /* forward declaration */ + +static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) +{ +#ifdef CRITSECS_NEWTYPE + struct CRITSECT* cs = critsecs_get_unix(c); +#else + struct CRITSECT* cs= (*(struct CRITSECT**)c); +#endif + // struct CRITSECT* cs=(struct CRITSECT*)c; + dbgprintf("DeleteCriticalSection(0x%x)\n",c); + +#ifndef GARBAGE + pthread_mutex_destroy(&(cs->mutex)); + // released by GarbageCollector in my_relase otherwise +#endif + my_release(cs); +#ifdef CRITSECS_NEWTYPE + { + int i = critsecs_get_pos(c); + + if (i < 0) + { + printf("DeleteCriticalSection(%p) error (critsec not found)\n", c); + return; + } + + critsecs_list[i].cs_win = NULL; + expfree(critsecs_list[i].cs_unix); + critsecs_list[i].cs_unix = NULL; + dbgprintf("DeleteCriticalSection -> itemno=%d\n", i); + } +#endif + return; +} +static int WINAPI expGetCurrentThreadId() +{ + dbgprintf("GetCurrentThreadId() => %d\n", pthread_self()); + return pthread_self(); +} +static int WINAPI expGetCurrentProcess() +{ + dbgprintf("GetCurrentProcess() => %d\n", getpid()); + return getpid(); +} + +#ifdef QTX +// this version is required for Quicktime codecs (.qtx/.qts) to work. +// (they assume some pointers at FS: segment) + +extern void* fs_seg; + +//static int tls_count; +static int tls_use_map[64]; +static int WINAPI expTlsAlloc() +{ + int i; + for(i=0; i<64; i++) + if(tls_use_map[i]==0) + { + tls_use_map[i]=1; + dbgprintf("TlsAlloc() => %d\n",i); + return i; + } + dbgprintf("TlsAlloc() => -1 (ERROR)\n"); + return -1; +} + +//static int WINAPI expTlsSetValue(DWORD index, void* value) +static int WINAPI expTlsSetValue(int index, void* value) +{ + dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value); +// if((index<0) || (index>64)) + if((index>=64)) + return 0; + *(void**)((char*)fs_seg+0x88+4*index) = value; + return 1; +} + +static void* WINAPI expTlsGetValue(DWORD index) +{ + dbgprintf("TlsGetValue(%d)\n",index); +// if((index<0) || (index>64)) + if((index>=64)) return NULL; + return *(void**)((char*)fs_seg+0x88+4*index); +} + +static int WINAPI expTlsFree(int idx) +{ + int index = (int) idx; + dbgprintf("TlsFree(%d)\n",index); + if((index<0) || (index>64)) + return 0; + tls_use_map[index]=0; + return 1; +} + +#else +struct tls_s { + void* value; + int used; + struct tls_s* prev; + struct tls_s* next; +}; + +static void* WINAPI expTlsAlloc() +{ + if (g_tls == NULL) + { + g_tls=my_mreq(sizeof(tls_t), 0); + g_tls->next=g_tls->prev=NULL; + } + else + { + g_tls->next=my_mreq(sizeof(tls_t), 0); + g_tls->next->prev=g_tls; + g_tls->next->next=NULL; + g_tls=g_tls->next; + } + dbgprintf("TlsAlloc() => 0x%x\n", g_tls); + if (g_tls) + g_tls->value=0; /* XXX For Divx.dll */ + return g_tls; +} + +static int WINAPI expTlsSetValue(void* idx, void* value) +{ + tls_t* index = (tls_t*) idx; + int result; + if(index==0) + result=0; + else + { + index->value=value; + result=1; + } + dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result ); + return result; +} +static void* WINAPI expTlsGetValue(void* idx) +{ + tls_t* index = (tls_t*) idx; + void* result; + if(index==0) + result=0; + else + result=index->value; + dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result); + return result; +} +static int WINAPI expTlsFree(void* idx) +{ + tls_t* index = (tls_t*) idx; + int result; + if(index==0) + result=0; + else + { + if(index->next) + index->next->prev=index->prev; + if(index->prev) + index->prev->next=index->next; + if (g_tls == index) + g_tls = index->prev; + my_release((void*)index); + result=1; + } + dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); + return result; +} +#endif + +static void* WINAPI expLocalAlloc(int flags, int size) +{ + void* z = my_mreq(size, (flags & GMEM_ZEROINIT)); + if (z == 0) + printf("LocalAlloc() failed\n"); + dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); + return z; +} + +static void* WINAPI expLocalReAlloc(int handle,int size, int flags) +{ + void *newpointer; + int oldsize; + + newpointer=NULL; + if (flags & LMEM_MODIFY) { + dbgprintf("LocalReAlloc MODIFY\n"); + return (void *)handle; + } + oldsize = my_size((void *)handle); + newpointer = my_realloc((void *)handle,size); + dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer); + + return newpointer; +} + +static void* WINAPI expLocalLock(void* z) +{ + dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z); + return z; +} + +static void* WINAPI expGlobalAlloc(int flags, int size) +{ + void* z; + dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags); + + z=my_mreq(size, (flags & GMEM_ZEROINIT)); + //z=calloc(size, 1); + //z=malloc(size); + if(z==0) + printf("GlobalAlloc() failed\n"); + dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); + return z; +} +static void* WINAPI expGlobalLock(void* z) +{ + dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z); + return z; +} +// pvmjpg20 - but doesn't work anyway +static int WINAPI expGlobalSize(void* amem) +{ + int size = 100000; +#ifdef GARBAGE + alloc_header* header = last_alloc; + alloc_header* mem = (alloc_header*) amem - 1; + if (amem == 0) + return 0; + pthread_mutex_lock(&memmut); + while (header) + { + if (header->deadbeef != 0xdeadbeef) + { + printf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); + break; + } + + if (header == mem) + { + size = header->size; + break; + } + + header = header->prev; + } + pthread_mutex_unlock(&memmut); +#endif + + dbgprintf("GlobalSize(0x%x)\n", amem); + return size; +} +static int WINAPI expLoadStringA(long instance, long id, void* buf, long size) +{ + int result=LoadStringA(instance, id, buf, size); + // if(buf) + dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n", + instance, id, buf, size, result, buf); + // else + // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n", + // instance, id, buf, size, result); + return result; +} + +static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2) +{ +#warning FIXME + int i; + int result; + if(s2==0) + result=1; + else + { + if(siz1>siz2/2)siz1=siz2/2; + for(i=1; i<=siz1; i++) + { + *s2=*s1; + if(!*s1)break; + s2++; + s1++; + } + result=i; + } + if(s1) + dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s'," + "size %d, dest buffer 0x%x, dest size %d) => %d\n", + v1, v2, s1, s1, siz1, s2, siz2, result); + else + dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL," + "size %d, dest buffer 0x%x, dest size %d) =>\n", + v1, v2, siz1, s2, siz2, result); + return result; +} +static void wch_print(const short* str) +{ + dbgprintf(" src: "); + while(*str)dbgprintf("%c", *str++); + dbgprintf("\n"); +} +static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, + char* s2, int siz2, char* c3, int* siz3) +{ + int result; + dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, " + "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3); + result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3); + dbgprintf("=> %d\n", result); + //if(s1)wch_print(s1); + if(s2)dbgprintf(" dest: %s\n", s2); + return result; +} +static long WINAPI expGetVersionExA(OSVERSIONINFOA* c) +{ + dbgprintf("GetVersionExA(0x%x) => 1\n"); + c->dwOSVersionInfoSize=sizeof(*c); + c->dwMajorVersion=4; + c->dwMinorVersion=0; + c->dwBuildNumber=0x4000457; +#if 1 + // leave it here for testing win9x-only codecs + c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; + strcpy(c->szCSDVersion, " B"); +#else + c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers + strcpy(c->szCSDVersion, "Service Pack 3"); +#endif + dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n" + " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n"); + return 1; +} +static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, + long max_count, char* name) +{ + pthread_mutex_t *pm; + pthread_cond_t *pc; + mutex_list* pp; + /* + printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "")); + pp=mlist; + while(pp) + { + printf("%p => ", pp); + pp=pp->prev; + } + printf("0\n"); + */ + if(mlist!=NULL) + { + mutex_list* pp=mlist; + if(name!=NULL) + do + { + if((strcmp(pp->name, name)==0) && (pp->type==1)) + { + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n", + v1, init_count, max_count, name, name, mlist); + return (HANDLE)mlist; + } + }while((pp=pp->prev) != NULL); + } + pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); + pthread_mutex_init(pm, NULL); + pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); + pthread_cond_init(pc, NULL); + if(mlist==NULL) + { + mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next=mlist->prev=NULL; + } + else + { + mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); + mlist->next->prev=mlist; + mlist->next->next=NULL; + mlist=mlist->next; + // printf("new semaphore %p\n", mlist); + } + mlist->type=1; /* Type Semaphore */ + mlist->pm=pm; + mlist->pc=pc; + mlist->state=0; + mlist->reset=0; + mlist->semaphore=init_count; + if(name!=NULL) + strncpy(mlist->name, name, 64); + else + mlist->name[0]=0; + if(pm==NULL) + dbgprintf("ERROR::: CreateSemaphoreA failure\n"); + if(name) + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n", + v1, init_count, max_count, name, name, mlist); + else + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n", + v1, init_count, max_count, mlist); + return (HANDLE)mlist; +} + +static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) +{ + // The state of a semaphore object is signaled when its count + // is greater than zero and nonsignaled when its count is equal to zero + // Each time a waiting thread is released because of the semaphore's signaled + // state, the count of the semaphore is decreased by one. + mutex_list *ml = (mutex_list *)hsem; + + pthread_mutex_lock(ml->pm); + if (prev_count != 0) *prev_count = ml->semaphore; + if (ml->semaphore == 0) pthread_cond_signal(ml->pc); + ml->semaphore += increment; + pthread_mutex_unlock(ml->pm); + dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n", + hsem, increment, prev_count); + return 1; +} + + +static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) +{ + long result=RegOpenKeyExA(key, subkey, reserved, access, newkey); + dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n", + key, subkey, reserved, access, newkey, result); + if(newkey)dbgprintf(" New key: 0x%x\n", *newkey); + return result; +} +static long WINAPI expRegCloseKey(long key) +{ + long result=RegCloseKey(key); + dbgprintf("RegCloseKey(0x%x) => %d\n", key, result); + return result; +} +static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) +{ + long result=RegQueryValueExA(key, value, reserved, type, data, count); + dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)" + " => 0x%x\n", key, value, reserved, data, count, result); + if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data); + return result; +} +static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved, + void* classs, long options, long security, + void* sec_attr, int* newkey, int* status) +{ + long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status); + dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x," + " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n", + key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result); + if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey); + if(!result && status) dbgprintf(" New key status: 0x%x\n", *status); + return result; +} +static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size) +{ + long result=RegSetValueExA(key, name, v1, v2, data, size); + dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d", + key, name, v1, v2, data, *(int*)data, data, size, result); + return result; +} + +static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult) +{ + long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult); + dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n", + hKey, lpSubKey, phkResult, result); + if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult); + return result; +} + +static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, + LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) +{ + return RegEnumValueA(hkey, index, value, val_count, + reserved, type, data, count); +} + +static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, + LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, + LPFILETIME lpftLastWriteTime) +{ + return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass, + lpcbClass, lpftLastWriteTime); +} + +static long WINAPI expQueryPerformanceCounter(long long* z) +{ + longcount(z); + dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z); + return 1; +} + +/* + * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo) + */ +static double linux_cpuinfo_freq() +{ + double freq=-1; + FILE *f; + char line[200]; + char *s,*value; + + f = fopen ("/proc/cpuinfo", "r"); + if (f != NULL) { + while (fgets(line,sizeof(line),f)!=NULL) { + /* NOTE: the ':' is the only character we can rely on */ + if (!(value = strchr(line,':'))) + continue; + /* terminate the valuename */ + *value++ = '\0'; + /* skip any leading spaces */ + while (*value==' ') value++; + if ((s=strchr(value,'\n'))) + *s='\0'; + + if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz")) + && sscanf(value, "%lf", &freq) == 1) { + freq*=1000; + break; + } + } + fclose(f); + } + return freq; +} + + +static double solaris_kstat_freq() +{ +#if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32) + /* + * try to extract the CPU speed from the solaris kernel's kstat data + */ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *kdata; + int mhz = 0; + + kc = kstat_open(); + if (kc != NULL) + { + ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0"); + + /* kstat found and name/value pairs? */ + if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED) + { + /* read the kstat data from the kernel */ + if (kstat_read(kc, ksp, NULL) != -1) + { + /* + * lookup desired "clock_MHz" entry, check the expected + * data type + */ + kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz"); + if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32) + mhz = kdata->value.i32; + } + } + kstat_close(kc); + } + + if (mhz > 0) + return mhz * 1000.; +#endif /* HAVE_LIBKSTAT */ + return -1; // kstat stuff is not available, CPU freq is unknown +} + +/* + * Measure CPU freq using the pentium's time stamp counter register (TSC) + */ +static double tsc_freq() +{ + static double ofreq=0.0; + int i; + int x,y; + i=time(NULL); + if (ofreq != 0.0) return ofreq; + while(i==time(NULL)); + x=localcount(); + i++; + while(i==time(NULL)); + y=localcount(); + ofreq = (double)(y-x)/1000.; + return ofreq; +} + +static double CPU_Freq() +{ + double freq; + + if ((freq = linux_cpuinfo_freq()) > 0) + return freq; + + if ((freq = solaris_kstat_freq()) > 0) + return freq; + + return tsc_freq(); +} + +static long WINAPI expQueryPerformanceFrequency(long long* z) +{ + *z=(long long)CPU_Freq(); + dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z); + return 1; +} +static long WINAPI exptimeGetTime() +{ + struct timeval t; + long result; + gettimeofday(&t, 0); + result=1000*t.tv_sec+t.tv_usec/1000; + dbgprintf("timeGetTime() => %d\n", result); + return result; +} +static void* WINAPI expLocalHandle(void* v) +{ + dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v); + return v; +} + +static void* WINAPI expGlobalHandle(void* v) +{ + dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v); + return v; +} +static int WINAPI expGlobalUnlock(void* v) +{ + dbgprintf("GlobalUnlock(0x%x) => 1\n", v); + return 1; +} +static void* WINAPI expGlobalFree(void* v) +{ + dbgprintf("GlobalFree(0x%x) => 0\n", v); + my_release(v); + //free(v); + return 0; +} + +static void* WINAPI expGlobalReAlloc(void* v, int size, int flags) +{ + void* result=my_realloc(v, size); + //void* result=realloc(v, size); + dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result); + return result; +} + +static int WINAPI expLocalUnlock(void* v) +{ + dbgprintf("LocalUnlock(0x%x) => 1\n", v); + return 1; +} +// +static void* WINAPI expLocalFree(void* v) +{ + dbgprintf("LocalFree(0x%x) => 0\n", v); + my_release(v); + return 0; +} +static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type) +{ + HRSRC result; + + result=FindResourceA(module, name, type); + dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n", + module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result); + return result; +} + +extern HRSRC WINAPI LoadResource(HMODULE, HRSRC); +static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res) +{ + HGLOBAL result=LoadResource(module, res); + dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result); + return result; +} +static void* WINAPI expLockResource(long res) +{ + void* result=LockResource(res); + dbgprintf("LockResource(0x%x) => 0x%x\n", res, result); + return result; +} +static int WINAPI expFreeResource(long res) +{ + int result=FreeResource(res); + dbgprintf("FreeResource(0x%x) => %d\n", res, result); + return result; +} +//bool fun(HANDLE) +//!0 on success +static int WINAPI expCloseHandle(long v1) +{ + dbgprintf("CloseHandle(0x%x) => 1\n", v1); + /* do not close stdin,stdout and stderr */ + if (v1 > 2) + if (!close(v1)) + return 0; + return 1; +} + +static const char* WINAPI expGetCommandLineA() +{ + dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n"); + return "c:\\aviplay.exe"; +} +static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0}; +static LPWSTR WINAPI expGetEnvironmentStringsW() +{ + dbgprintf("GetEnvironmentStringsW() => 0\n", envs); + return 0; +} +static void * WINAPI expRtlZeroMemory(void *p, size_t len) +{ + void* result=memset(p,0,len); + dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result); + return result; +} +static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len) +{ + void* result=memmove(dst,src,len); + dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result); + return result; +} + +static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len) +{ + void* result=memset(p,ch,len); + dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result); + return result; +} +static int WINAPI expFreeEnvironmentStringsW(short* strings) +{ + dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings); + return 1; +} +static int WINAPI expFreeEnvironmentStringsA(char* strings) +{ + dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings); + return 1; +} + +static const char ch_envs[]= +"__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n" +"PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n"; +static LPCSTR WINAPI expGetEnvironmentStrings() +{ + dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs); + return (LPCSTR)ch_envs; + // dbgprintf("GetEnvironmentStrings() => 0\n"); + // return 0; +} + +static int WINAPI expGetStartupInfoA(STARTUPINFOA *s) +{ + int i; + dbgprintf("GetStartupInfoA(0x%x) => 1\n"); + memset(s, 0, sizeof(*s)); + s->cb=sizeof(*s); + // s->lpReserved="Reserved"; + // s->lpDesktop="Desktop"; + // s->lpTitle="Title"; + // s->dwX=s->dwY=0; + // s->dwXSize=s->dwYSize=200; + s->dwFlags=s->wShowWindow=1; + // s->hStdInput=s->hStdOutput=s->hStdError=0x1234; + dbgprintf(" cb=%d\n", s->cb); + dbgprintf(" lpReserved='%s'\n", s->lpReserved); + dbgprintf(" lpDesktop='%s'\n", s->lpDesktop); + dbgprintf(" lpTitle='%s'\n", s->lpTitle); + dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n", + s->dwX, s->dwY, s->dwXSize, s->dwYSize); + dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n", + s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute); + dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n", + s->dwFlags, s->wShowWindow, s->cbReserved2); + dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n", + s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError); + return 1; +} + +static int WINAPI expGetStdHandle(int z) +{ + dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234); + return z+0x1234; +} + +#ifdef QTX +#define FILE_HANDLE_quicktimeqts ((HANDLE)0x444) +#define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445) +#endif + +static int WINAPI expGetFileType(int handle) +{ + dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle); + return 0x3; +} +#ifdef QTX +static int WINAPI expGetFileAttributesA(char *filename) +{ + dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename); + if (strstr(filename, "QuickTime.qts")) + return FILE_ATTRIBUTE_SYSTEM; + return FILE_ATTRIBUTE_NORMAL; +} +#endif +static int WINAPI expSetHandleCount(int count) +{ + dbgprintf("SetHandleCount(0x%x) => 1\n", count); + return 1; +} +static int WINAPI expGetACP(void) +{ + dbgprintf("GetACP() => 0\n"); + return 0; +} +extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m); +static int WINAPI expGetModuleFileNameA(int module, char* s, int len) +{ + WINE_MODREF *mr; + int result; + //printf("File name of module %X (%s) requested\n", module, s); + + if (module == 0 && len >= 12) + { + /* return caller program name */ + strcpy(s, "aviplay.dll"); + result=1; + } + else if(s==0) + result=0; + else + if(len<35) + result=0; + else + { + result=1; + strcpy(s, "c:\\windows\\system\\"); + mr=MODULE32_LookupHMODULE(module); + if(mr==0)//oops + strcat(s, "aviplay.dll"); + else + if(strrchr(mr->filename, '/')==NULL) + strcat(s, mr->filename); + else + strcat(s, strrchr(mr->filename, '/')+1); + } + if(!s) + dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n", + module, s, len, result); + else + dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n", + module, s, len, result, s); + return result; +} + +static int WINAPI expSetUnhandledExceptionFilter(void* filter) +{ + dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter); + return 1;//unsupported and probably won't ever be supported +} + +static int WINAPI expLoadLibraryA(char* name) +{ + int result = 0; + char* lastbc; + int i; + if (!name) + return -1; + // we skip to the last backslash + // this is effectively eliminating weird characters in + // the text output windows + + lastbc = strrchr(name, '\\'); + if (lastbc) + { + int i; + lastbc++; + for (i = 0; 1 ;i++) + { + name[i] = *lastbc++; + if (!name[i]) + break; + } + } + if(strncmp(name, "c:\\windows\\", 11)==0) name += 11; + if(strncmp(name, ".\\", 2)==0) name += 2; + + dbgprintf("Entering LoadLibraryA(%s)\n", name); + + // PIMJ and VIVO audio are loading kernel32.dll + if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0) + return MODULE_HANDLE_kernel32; +// return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */ + /* exported -> do not return failed! */ + + if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0) +// return MODULE_HANDLE_kernel32; + return MODULE_HANDLE_user32; + +#ifdef QTX + if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0) + return MODULE_HANDLE_wininet; + if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0) + return MODULE_HANDLE_ddraw; + if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0) + return MODULE_HANDLE_advapi32; +#endif + + result=LoadLibraryA(name); + dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result); + + return result; +} + +static int WINAPI expFreeLibrary(int module) +{ +#ifdef QTX + int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */ +#else + int result=FreeLibrary(module); +#endif + dbgprintf("FreeLibrary(0x%x) => %d\n", module, result); + return result; +} + +static void* WINAPI expGetProcAddress(HMODULE mod, char* name) +{ + void* result; + switch(mod){ + case MODULE_HANDLE_kernel32: + result=LookupExternalByName("kernel32.dll", name); break; + case MODULE_HANDLE_user32: + result=LookupExternalByName("user32.dll", name); break; +#ifdef QTX + case MODULE_HANDLE_wininet: + result=LookupExternalByName("wininet.dll", name); break; + case MODULE_HANDLE_ddraw: + result=LookupExternalByName("ddraw.dll", name); break; + case MODULE_HANDLE_advapi32: + result=LookupExternalByName("advapi32.dll", name); break; +#endif + default: + result=GetProcAddress(mod, name); + } + dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result); + return result; +} + +static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, + long flProtect, long dwMaxHigh, + long dwMaxLow, const char* name) +{ + long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); + if(!name) + dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x," + "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n", + hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result); + else + dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x," + "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n", + hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result); + return result; +} + +static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) +{ + long result=OpenFileMappingA(hFile, hz, name); + if(!name) + dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n", + hFile, hz, result); + else + dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n", + hFile, hz, name, name, result); + return result; +} + +static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, + DWORD offLow, DWORD size) +{ + dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n", + file,mode,offHigh,offLow,size,(char*)file+offLow); + return (char*)file+offLow; +} + +static void* WINAPI expUnmapViewOfFile(void* view) +{ + dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view); + return 0; +} + +static void* WINAPI expSleep(int time) +{ +#if HAVE_NANOSLEEP + /* solaris doesn't have thread safe usleep */ + struct timespec tsp; + tsp.tv_sec = time / 1000000; + tsp.tv_nsec = (time % 1000000) * 1000; + nanosleep(&tsp, NULL); +#else + usleep(time); +#endif + dbgprintf("Sleep(%d) => 0\n", time); + return 0; +} + +// why does IV32 codec want to call this? I don't know ... +static int WINAPI expCreateCompatibleDC(int hdc) +{ + int dc = 0;//0x81; + //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc); + dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc); + return dc; +} + +static int WINAPI expGetDeviceCaps(int hdc, int unk) +{ + dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk); +#ifdef QTX + #define BITSPIXEL 12 + #define PLANES 14 + if (unk == BITSPIXEL) + return 24; + if (unk == PLANES) + return 1; +#endif + return 1; +} + +static WIN_BOOL WINAPI expDeleteDC(int hdc) +{ + dbgprintf("DeleteDC(0x%x) => 0\n", hdc); + if (hdc == 0x81) + return 1; + return 0; +} + +static WIN_BOOL WINAPI expDeleteObject(int hdc) +{ + dbgprintf("DeleteObject(0x%x) => 1\n", hdc); + /* FIXME - implement code here */ + return 1; +} + +/* btvvc32.drv wants this one */ +static void* WINAPI expGetWindowDC(int hdc) +{ + dbgprintf("GetWindowDC(%d) => 0x0\n", hdc); + return 0; +} + +#ifdef QTX +static int WINAPI expGetWindowRect(HWND win, RECT *r) +{ + dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r); + /* (win == 0) => desktop */ + r->right = PSEUDO_SCREEN_WIDTH; + r->left = 0; + r->bottom = PSEUDO_SCREEN_HEIGHT; + r->top = 0; + return 1; +} + +static int WINAPI expMonitorFromWindow(HWND win, int flags) +{ + dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags); + return 0; +} + +static int WINAPI expMonitorFromRect(RECT *r, int flags) +{ + dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags); + return 0; +} + +static int WINAPI expMonitorFromPoint(void *p, int flags) +{ + dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags); + return 0; +} + +static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r, + int WINAPI (*callback_proc)(), void *callback_param) +{ + dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n", + dc, r, callback_proc, callback_param); + return callback_proc(0, dc, r, callback_param); +} + +#if 0 +typedef struct tagMONITORINFO { + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; +#endif + +#define CCHDEVICENAME 8 +typedef struct tagMONITORINFOEX { + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; + TCHAR szDevice[CCHDEVICENAME]; +} MONITORINFOEX, *LPMONITORINFOEX; + +static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi) +{ + dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi); + + lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH; + lpmi->rcMonitor.left = lpmi->rcWork.left = 0; + lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT; + lpmi->rcMonitor.top = lpmi->rcWork.top = 0; + + lpmi->dwFlags = 1; /* primary monitor */ + + if (lpmi->cbSize == sizeof(MONITORINFOEX)) + { + LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi; + dbgprintf("MONITORINFOEX!\n"); + strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME); + } + + return 1; +} + +static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum, + void *dispdev, int flags) +{ + dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n", + device, device, devnum, dispdev, flags); + return 1; +} + +static int WINAPI expIsWindowVisible(HWND win) +{ + dbgprintf("IsWindowVisible(0x%x) => 1\n", win); + return 1; +} + +static HWND WINAPI expGetActiveWindow(void) +{ + dbgprintf("GetActiveWindow() => 0\n"); + return (HWND)0; +} + +static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount) +{ + strncat(classname, "QuickTime", maxcount); + dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n", + win, classname, maxcount, strlen(classname)); + return strlen(classname); +} + +#define LPWNDCLASS void * +static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass) +{ + dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst, + classname, classname, wndclass); + return 1; +} + +static int WINAPI expGetWindowLongA(HWND win, int index) +{ + dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index); + return 1; +} + +static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj) +{ + dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize); + return objsize; +} + +static int WINAPI expCreateRectRgn(int x, int y, int width, int height) +{ + dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height); + return 0; +} + +static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param) +{ + int i, i2; + dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param); + i = callback_func(0, callback_param); + i2 = callback_func(1, callback_param); + return i && i2; +} + +static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data) +{ + int tid = pthread_self(); + dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n", + win, pid_data, tid); + if (pid_data) + (int)*pid_data = tid; + return tid; +} + +//HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT, +// INT,INT,HWND,HMENU,HINSTANCE,LPVOID); + +static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname, + const char *winname, int style, int x, int y, int w, int h, + HWND parent, HMENU menu, HINSTANCE inst, LPVOID param) +{ + printf("CreateWindowEx() called\n"); + dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n", + exstyle, classname, classname, winname, winname, style, x, y, w, h, + parent, menu, inst, param); + printf("CreateWindowEx() called okey\n"); + return 1; +} + +static int WINAPI expwaveOutGetNumDevs(void) +{ + dbgprintf("waveOutGetNumDevs() => 0\n"); + return 0; +} +#endif + +/* + * Returns the number of milliseconds, modulo 2^32, since the start + * of the wineserver. + */ +static int WINAPI expGetTickCount(void) +{ + static int tcstart = 0; + struct timeval t; + int tc; + gettimeofday( &t, NULL ); + tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart; + if (tcstart == 0) + { + tcstart = 0; + tc = 0; + } + dbgprintf("GetTickCount() => %d\n", tc); + return tc; +} + +static int WINAPI expCreateFontA(void) +{ + dbgprintf("CreateFontA() => 0x0\n"); + return 1; +} + +/* tried to get pvmjpg work in a different way - no success */ +static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount, + LPRECT lpRect, unsigned int uFormat) +{ + dbgprintf("expDrawTextA(%p,...) => 8\n", hDC); + return 8; +} + +static int WINAPI expGetPrivateProfileIntA(const char* appname, + const char* keyname, + int default_value, + const char* filename) +{ + int size=255; + char buffer[256]; + char* fullname; + int result; + + buffer[255]=0; + if(!(appname && keyname && filename) ) + { + dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value ); + return default_value; + } + fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); + strcpy(fullname, "Software\\IniFileMapping\\"); + strcat(fullname, appname); + strcat(fullname, "\\"); + strcat(fullname, keyname); + strcat(fullname, "\\"); + strcat(fullname, filename); + result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size); + if((size>=0)&&(size<256)) + buffer[size]=0; + // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer); + free(fullname); + if(result) + result=default_value; + else + result=atoi(buffer); + dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result); + return result; +} +static int WINAPI expGetProfileIntA(const char* appname, + const char* keyname, + int default_value) +{ + dbgprintf("GetProfileIntA -> "); + return expGetPrivateProfileIntA(appname, keyname, default_value, "default"); +} + +static int WINAPI expGetPrivateProfileStringA(const char* appname, + const char* keyname, + const char* def_val, + char* dest, unsigned int len, + const char* filename) +{ + int result; + int size; + char* fullname; + dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename ); + if(!(appname && keyname && filename) ) return 0; + fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); + strcpy(fullname, "Software\\IniFileMapping\\"); + strcat(fullname, appname); + strcat(fullname, "\\"); + strcat(fullname, keyname); + strcat(fullname, "\\"); + strcat(fullname, filename); + size=len; + result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size); + free(fullname); + if(result) + { + strncpy(dest, def_val, size); + if (strlen(def_val)< size) size = strlen(def_val); + } + dbgprintf(" => %d ( '%s' )\n", size, dest); + return size; +} +static int WINAPI expWritePrivateProfileStringA(const char* appname, + const char* keyname, + const char* string, + const char* filename) +{ + int size=256; + char* fullname; + dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename ); + if(!(appname && keyname && filename) ) + { + dbgprintf(" => -1\n"); + return -1; + } + fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); + strcpy(fullname, "Software\\IniFileMapping\\"); + strcat(fullname, appname); + strcat(fullname, "\\"); + strcat(fullname, keyname); + strcat(fullname, "\\"); + strcat(fullname, filename); + RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string)); + // printf("RegSetValueExA(%s,%d)\n", string, strlen(string)); + // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename ); + free(fullname); + dbgprintf(" => 0\n"); + return 0; +} + +unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename) +{ + return expGetPrivateProfileIntA(appname, keyname, default_value, filename); +} +int _GetPrivateProfileStringA(const char* appname, const char* keyname, + const char* def_val, char* dest, unsigned int len, const char* filename) +{ + return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename); +} +int _WritePrivateProfileStringA(const char* appname, const char* keyname, + const char* string, const char* filename) +{ + return expWritePrivateProfileStringA(appname, keyname, string, filename); +} + + + +static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2) +{ + dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2); + return 0; +} + +static int WINAPI expSizeofResource(int v1, int v2) +{ + int result=SizeofResource(v1, v2); + dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result); + return result; +} + +static int WINAPI expGetLastError() +{ + int result=GetLastError(); + dbgprintf("GetLastError() => 0x%x\n", result); + return result; +} + +static void WINAPI expSetLastError(int error) +{ + dbgprintf("SetLastError(0x%x)\n", error); + SetLastError(error); +} + +static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax) +{ + int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", + guid->f1, guid->f2, guid->f3, + (unsigned char)guid->f4[0], (unsigned char)guid->f4[1], + (unsigned char)guid->f4[2], (unsigned char)guid->f4[3], + (unsigned char)guid->f4[4], (unsigned char)guid->f4[5], + (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]); + dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result); + return result; +} + + +static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle) +{ + dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle); + return 0; +} + +static int WINAPI expIsBadStringPtrW(const short* string, int nchars) +{ + int result; + if(string==0)result=1; else result=0; + dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result); + if(string)wch_print(string); + return result; +} +static int WINAPI expIsBadStringPtrA(const char* string, int nchars) +{ + return expIsBadStringPtrW((const short*)string, nchars); +} +static long WINAPI expInterlockedExchangeAdd( long* dest, long incr ) +{ + long ret; + __asm__ __volatile__ + ( + "lock; xaddl %0,(%1)" + : "=r" (ret) + : "r" (dest), "0" (incr) + : "memory" + ); + return ret; +} + +static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand) +{ + unsigned long retval = *dest; + if(*dest == comperand) + *dest = exchange; + return retval; +} + +static long WINAPI expInterlockedIncrement( long* dest ) +{ + long result=expInterlockedExchangeAdd( dest, 1 ) + 1; + dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result); + return result; +} +static long WINAPI expInterlockedDecrement( long* dest ) +{ + long result=expInterlockedExchangeAdd( dest, -1 ) - 1; + dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result); + return result; +} + +static void WINAPI expOutputDebugStringA( const char* string ) +{ + dbgprintf("OutputDebugStringA(0x%x='%s')\n", string); + fprintf(stderr, "DEBUG: %s\n", string); +} + +static int WINAPI expGetDC(int hwnd) +{ + dbgprintf("GetDC(0x%x) => 1\n", hwnd); + return 1; +} + +static int WINAPI expReleaseDC(int hwnd, int hdc) +{ + dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc); + return 1; +} + +static int WINAPI expGetDesktopWindow() +{ + dbgprintf("GetDesktopWindow() => 0\n"); + return 0; +} + +static int cursor[100]; + +static int WINAPI expLoadCursorA(int handle,LPCSTR name) +{ + dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]); + return (int)&cursor[0]; +} +static int WINAPI expSetCursor(void *cursor) +{ + dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor); + return (int)cursor; +} +static int WINAPI expGetCursorPos(void *cursor) +{ + dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor); + return 1; +} +#ifdef QTX +static int show_cursor = 0; +static int WINAPI expShowCursor(int show) +{ + dbgprintf("ShowCursor(%d) => %d\n", show, show); + if (show) + show_cursor++; + else + show_cursor--; + return show_cursor; +} +#endif +static int WINAPI expRegisterWindowMessageA(char *message) +{ + dbgprintf("RegisterWindowMessageA(%s)\n", message); + return 1; +} +static int WINAPI expGetProcessVersion(int pid) +{ + dbgprintf("GetProcessVersion(%d)\n", pid); + return 1; +} +static int WINAPI expGetCurrentThread(void) +{ +#warning FIXME! + dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898); + return 0xcfcf9898; +} +static int WINAPI expGetOEMCP(void) +{ + dbgprintf("GetOEMCP()\n"); + return 1; +} +static int WINAPI expGetCPInfo(int cp,void *info) +{ + dbgprintf("GetCPInfo()\n"); + return 0; +} +#ifdef QTX +#define SM_CXSCREEN 0 +#define SM_CYSCREEN 1 +#define SM_XVIRTUALSCREEN 76 +#define SM_YVIRTUALSCREEN 77 +#define SM_CXVIRTUALSCREEN 78 +#define SM_CYVIRTUALSCREEN 79 +#define SM_CMONITORS 80 +#endif +static int WINAPI expGetSystemMetrics(int index) +{ + dbgprintf("GetSystemMetrics(%d)\n", index); +#ifdef QTX + switch(index) + { + case SM_XVIRTUALSCREEN: + case SM_YVIRTUALSCREEN: + return 0; + case SM_CXSCREEN: + case SM_CXVIRTUALSCREEN: + return PSEUDO_SCREEN_WIDTH; + case SM_CYSCREEN: + case SM_CYVIRTUALSCREEN: + return PSEUDO_SCREEN_HEIGHT; + case SM_CMONITORS: + return 1; + } +#endif + return 1; +} +static int WINAPI expGetSysColor(int index) +{ + dbgprintf("GetSysColor(%d) => 1\n", index); + return 1; +} +static int WINAPI expGetSysColorBrush(int index) +{ + dbgprintf("GetSysColorBrush(%d)\n", index); + return 1; +} + + + +static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe) +{ + dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n", + hdc, iStartIndex, nEntries, lppe); + return 0; +} + +/* + typedef struct _TIME_ZONE_INFORMATION { + long Bias; + char StandardName[32]; + SYSTEMTIME StandardDate; + long StandardBias; + char DaylightName[32]; + SYSTEMTIME DaylightDate; + long DaylightBias; + } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + */ + +static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation) +{ + const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a', + 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0}; + const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y', + 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0}; + dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n"); + memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION)); + lpTimeZoneInformation->Bias=360;//GMT-6 + memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name)); + lpTimeZoneInformation->StandardDate.wMonth=10; + lpTimeZoneInformation->StandardDate.wDay=5; + lpTimeZoneInformation->StandardDate.wHour=2; + lpTimeZoneInformation->StandardBias=0; + memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname)); + lpTimeZoneInformation->DaylightDate.wMonth=4; + lpTimeZoneInformation->DaylightDate.wDay=1; + lpTimeZoneInformation->DaylightDate.wHour=2; + lpTimeZoneInformation->DaylightBias=-60; + return TIME_ZONE_ID_STANDARD; +} + +static void WINAPI expGetLocalTime(SYSTEMTIME* systime) +{ + time_t local_time; + struct tm *local_tm; + struct timeval tv; + + dbgprintf("GetLocalTime(0x%x)\n"); + gettimeofday(&tv, NULL); + local_time=tv.tv_sec; + local_tm=localtime(&local_time); + + systime->wYear = local_tm->tm_year + 1900; + systime->wMonth = local_tm->tm_mon + 1; + systime->wDayOfWeek = local_tm->tm_wday; + systime->wDay = local_tm->tm_mday; + systime->wHour = local_tm->tm_hour; + systime->wMinute = local_tm->tm_min; + systime->wSecond = local_tm->tm_sec; + systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; + dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" + " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" + " Milliseconds: %d\n", + systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, + systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); +} + +static int WINAPI expGetSystemTime(SYSTEMTIME* systime) +{ + time_t local_time; + struct tm *local_tm; + struct timeval tv; + + dbgprintf("GetSystemTime(0x%x)\n", systime); + gettimeofday(&tv, NULL); + local_time=tv.tv_sec; + local_tm=gmtime(&local_time); + + systime->wYear = local_tm->tm_year + 1900; + systime->wMonth = local_tm->tm_mon + 1; + systime->wDayOfWeek = local_tm->tm_wday; + systime->wDay = local_tm->tm_mday; + systime->wHour = local_tm->tm_hour; + systime->wMinute = local_tm->tm_min; + systime->wSecond = local_tm->tm_sec; + systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; + dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" + " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" + " Milliseconds: %d\n", + systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, + systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); + return 0; +} + +#define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL) +static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime) +{ + struct tm *local_tm; + struct timeval tv; + unsigned long long secs; + + dbgprintf("GetSystemTime(0x%x)\n", systime); + gettimeofday(&tv, NULL); + secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000; + secs += tv.tv_usec * 10; + systime->dwLowDateTime = secs & 0xffffffff; + systime->dwHighDateTime = (secs >> 32); +} + +static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size) +{ + char *p; + // printf("%s %x %x\n", name, field, size); + if(field)field[0]=0; + /* + p = getenv(name); + if (p) strncpy(field,p,size); + */ + if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0) + strcpy(field,"__GLOBAL_HEAP_SELECTED,1"); + dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field)); + return strlen(field); +} + +static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value) +{ + dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value); + return 0; +} + +static void* WINAPI expCoTaskMemAlloc(ULONG cb) +{ + return my_mreq(cb, 0); +} +static void WINAPI expCoTaskMemFree(void* cb) +{ + my_release(cb); +} + + + + +void* CoTaskMemAlloc(unsigned long cb) +{ + return expCoTaskMemAlloc(cb); +} +void CoTaskMemFree(void* cb) +{ + expCoTaskMemFree(cb); +} + +struct COM_OBJECT_INFO +{ + GUID clsid; + long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv); +}; + +static struct COM_OBJECT_INFO* com_object_table=0; +static int com_object_size=0; +int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) +{ + if(!clsid || !gcs) + return -1; + com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size)); + com_object_table[com_object_size-1].clsid=*clsid; + com_object_table[com_object_size-1].GetClassObject=gcs; + return 0; +} + +int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) +{ + int found = 0; + int i = 0; + if(!clsid || !gcs) + return -1; + + if (com_object_table == 0) + printf("Warning: UnregisterComClass() called without any registered class\n"); + while (i < com_object_size) + { + if (found && i > 0) + { + memcpy(&com_object_table[i - 1].clsid, + &com_object_table[i].clsid, sizeof(GUID)); + com_object_table[i - 1].GetClassObject = + com_object_table[i].GetClassObject; + } + else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0 + && com_object_table[i].GetClassObject == gcs) + { + found++; + } + i++; + } + if (found) + { + if (--com_object_size == 0) + { + free(com_object_table); + com_object_table = 0; + } + } + return 0; +} + + +const GUID IID_IUnknown = +{ + 0x00000000, 0x0000, 0x0000, + {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} +}; +const GUID IID_IClassFactory = +{ + 0x00000001, 0x0000, 0x0000, + {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} +}; + +static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, + long dwClsContext, const GUID* riid, void** ppv) +{ + int i; + struct COM_OBJECT_INFO* ci=0; + for(i=0; iGetClassObject(rclsid, riid, ppv); + return i; +} + +long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, + long dwClsContext, const GUID* riid, void** ppv) +{ + return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); +} + +static int WINAPI expIsRectEmpty(CONST RECT *lprc) +{ + int r = 0; + int w,h; +//trapbug(); + if (lprc) + { + w = lprc->right - lprc->left; + h = lprc->bottom - lprc->top; + if (w <= 0 || h <= 0) + r = 1; + } + else + r = 1; + + dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE"); + //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom); +// return 0; // wmv9? + return r; // TM20 +} + +static int _adjust_fdiv=0; //what's this? - used to adjust division + + + + +static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path) +{ + dbgprintf("GetTempPathA(%d, 0x%x)", len, path); + if(len<5) + { + dbgprintf(" => 0\n"); + return 0; + } + strcpy(path, "/tmp"); + dbgprintf(" => 5 ( '/tmp' )\n"); + return 5; +} +/* + FYI: + typedef struct + { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + CHAR cFileName[260]; + CHAR cAlternateFileName[14]; + } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; + */ + +static DIR* qtx_dir=NULL; + +static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd) +{ +#ifdef QTX + dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd); + if(h==FILE_HANDLE_quicktimeqtx){ + struct dirent* d; + if(!qtx_dir) return 0; + while((d=readdir(qtx_dir))){ + char* x=strrchr(d->d_name,'.'); + if(!x) continue; + if(strcmp(x,".qtx")) continue; + strcpy(lpfd->cFileName,d->d_name); +// sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name); + strcpy(lpfd->cAlternateFileName,"foobar.qtx"); + printf("### FindNext: %s\n",lpfd->cFileName); + return 1; + } + closedir(qtx_dir); qtx_dir=NULL; + return 0; + } +#endif + return 0; +} + +static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd) +{ + dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd); +// printf("\n### FindFirstFileA('%s')...\n",s); +#ifdef QTX + if(strstr(s, "quicktime\\*.QTX")){ + dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd); + printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path); + qtx_dir=opendir(def_path); + if(!qtx_dir) return (HANDLE)-1; + memset(lpfd,0,sizeof(*lpfd)); + if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd)) + return FILE_HANDLE_quicktimeqtx; + printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path); + return (HANDLE)-1; + } +#if 0 + if(strstr(s, "QuickTime.qts")){ + dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd); +// if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX")) +// return (HANDLE)-1; + strcpy(lpfd->cFileName, "QuickTime.qts"); + strcpy(lpfd->cAlternateFileName, "QuickT~1.qts"); + return FILE_HANDLE_quicktimeqts; + } +#endif +#endif + if(strstr(s, "*.vwp")){ + // hack for VoxWare codec plugins: + strcpy(lpfd->cFileName, "msms001.vwp"); + strcpy(lpfd->cAlternateFileName, "msms001.vwp"); + return (HANDLE)0; + } + // return 'file not found' + return (HANDLE)-1; +} + +static WIN_BOOL WINAPI expFindClose(HANDLE h) +{ + dbgprintf("FindClose(0x%x) => 0\n", h); +#ifdef QTX +// if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){ +// closedir(qtx_dir); +// qtx_dir=NULL; +// } +#endif + return 0; +} +static UINT WINAPI expSetErrorMode(UINT i) +{ + dbgprintf("SetErrorMode(%d) => 0\n", i); + return 0; +} +static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c) +{ + char windir[]="c:\\windows"; + int result; + strncpy(s, windir, c); + result=1+((c %d\n", s, c, result); + return result; +} +#ifdef QTX +static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s) +{ + char curdir[]="c:\\"; + int result; + strncpy(s, curdir, c); + result=1+((c %d\n", s, c, result); + return result; +} + +static int WINAPI expSetCurrentDirectoryA(const char *pathname) +{ + dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname); +#if 0 + if (strrchr(pathname, '\\')) + chdir(strcat(strrchr(pathname, '\\')+1, '/')); + else + chdir(pathname); +#endif + return 1; +} + +static int WINAPI expCreateDirectoryA(const char *pathname, void *sa) +{ + dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n", + pathname, pathname, sa); +#if 0 + p = strrchr(pathname, '\\')+1; + strcpy(&buf[0], p); /* should be strncpy */ + if (!strlen(p)) + { + buf[0] = '.'; + buf[1] = 0; + } +#if 0 + if (strrchr(pathname, '\\')) + mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666); + else + mkdir(pathname, 666); +#endif + mkdir(&buf); +#endif + return 1; +} +#endif +static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s) +{ + dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s); + return 0; +} +static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf) +{ + dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf); + return 0; +} + +static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps) +{ + char mask[16]="/tmp/AP_XXXXXX"; + int result; + dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps); + if(i && i<10) + { + dbgprintf(" => -1\n"); + return -1; + } + result=mkstemp(mask); + sprintf(ps, "AP%d", result); + dbgprintf(" => %d\n", strlen(ps)); + return strlen(ps); +} +// +// This func might need proper implementation if we want AngelPotion codec. +// They try to open APmpeg4v1.apl with it. +// DLL will close opened file with CloseHandle(). +// +static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2, + LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5) +{ + dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1, + i2, p1, i3, i4, i5); + if((!cs1) || (strlen(cs1)<2))return -1; + +#ifdef QTX + if(strstr(cs1, "QuickTime.qts")) + { + int result; + char* tmp=(char*)malloc(strlen(def_path)+50); + strcpy(tmp, def_path); + strcat(tmp, "/"); + strcat(tmp, "QuickTime.qts"); + result=open(tmp, O_RDONLY); + free(tmp); + return result; + } + if(strstr(cs1, ".qtx")) + { + int result; + char* tmp=(char*)malloc(strlen(def_path)+250); + char* x=strrchr(cs1,'\\'); + sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1); +// printf("### Open: %s -> %s\n",cs1,tmp); + result=open(tmp, O_RDONLY); + free(tmp); + return result; + } +#endif + + if(strncmp(cs1, "AP", 2) == 0) + { + int result; + char* tmp=(char*)malloc(strlen(def_path)+50); + strcpy(tmp, def_path); + strcat(tmp, "/"); + strcat(tmp, "APmpg4v1.apl"); + result=open(tmp, O_RDONLY); + free(tmp); + return result; + } + if (strstr(cs1, "vp3")) + { + int r; + int flg = 0; + char* tmp=(char*)malloc(20 + strlen(cs1)); + strcpy(tmp, "/tmp/"); + strcat(tmp, cs1); + r = 4; + while (tmp[r]) + { + if (tmp[r] == ':' || tmp[r] == '\\') + tmp[r] = '_'; + r++; + } + if (GENERIC_READ & i1) + flg |= O_RDONLY; + else if (GENERIC_WRITE & i1) + { + flg |= O_WRONLY; + printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg); + } + r=open(tmp, flg); + free(tmp); + return r; + } + +#if 0 + /* we need this for some virtualdub filters */ + { + int r; + int flg = 0; + if (GENERIC_READ & i1) + flg |= O_RDONLY; + else if (GENERIC_WRITE & i1) + { + flg |= O_WRONLY; + printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg); + } + r=open(cs1, flg); + return r; + } +#endif + + return atoi(cs1+2); +} +static UINT WINAPI expGetSystemDirectoryA( + char* lpBuffer, // address of buffer for system directory + UINT uSize // size of directory buffer +){ + dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize); + if(!lpBuffer) strcpy(lpBuffer,"."); + return 1; +} +/* +static char sysdir[]="."; +static LPCSTR WINAPI expGetSystemDirectoryA() +{ + dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir); + return sysdir; +} +*/ +static DWORD WINAPI expGetFullPathNameA +( + LPCTSTR lpFileName, + DWORD nBufferLength, + LPTSTR lpBuffer, + LPTSTR lpFilePart +){ + if(!lpFileName) return 0; + dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength, + lpBuffer, lpFilePart); +#if 0 +#ifdef QTX + strcpy(lpFilePart, "Quick123.qts"); +#else + strcpy(lpFilePart, lpFileName); +#endif +#else + if (strrchr(lpFileName, '\\')) + lpFilePart = strrchr(lpFileName, '\\'); + else + lpFilePart = lpFileName; +#endif + strcpy(lpBuffer, lpFileName); +// strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName); + return strlen(lpBuffer); +} + +static DWORD WINAPI expGetShortPathNameA +( + LPCSTR longpath, + LPSTR shortpath, + DWORD shortlen +){ + if(!longpath) return 0; + dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen); + strcpy(shortpath,longpath); + return strlen(shortpath); +} + +static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused) +{ + int result; + dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd); + result=read(h, pv, size); + if(rd)*rd=result; + if(!result)return 0; + return 1; +} + +static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused) +{ + int result; + dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr); + if(h==1234)h=1; + result=write(h, pv, size); + if(wr)*wr=result; + if(!result)return 0; + return 1; +} +static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence) +{ + int wh; + dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, *ext, whence); + //why would DLL want temporary file with >2Gb size? + switch(whence) + { + case FILE_BEGIN: + wh=SEEK_SET;break; + case FILE_END: + wh=SEEK_END;break; + case FILE_CURRENT: + wh=SEEK_CUR;break; + default: + return -1; + } +#ifdef QTX + if (val == 0 && ext != 0) + val = val&(*ext); +#endif + return lseek(h, val, wh); +} + +static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, + LPARAM lParam2) +{ + dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); + return -1; +} +static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName, + LPARAM lParam2) +{ + dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); + return -1; +} + + +static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess, + LPDWORD lpProcessAffinityMask, + LPDWORD lpSystemAffinityMask) +{ + dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n", + hProcess, lpProcessAffinityMask, lpSystemAffinityMask); + if(lpProcessAffinityMask)*lpProcessAffinityMask=1; + if(lpSystemAffinityMask)*lpSystemAffinityMask=1; + return 1; +} + +static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator) +{ + static const long long max_int=0x7FFFFFFFLL; + static const long long min_int=-0x80000000LL; + long long tmp=(long long)nNumber*(long long)nNumerator; + dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator); + if(!nDenominator)return 1; + tmp/=nDenominator; + if(tmpmax_int) return 1; + return (int)tmp; +} + +static LONG WINAPI explstrcmpiA(const char* str1, const char* str2) +{ + LONG result=strcasecmp(str1, str2); + dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result); + return result; +} + +static LONG WINAPI explstrlenA(const char* str1) +{ + LONG result=strlen(str1); + dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result); + return result; +} + +static LONG WINAPI explstrcpyA(char* str1, const char* str2) +{ + int result= (int) strcpy(str1, str2); + dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result); + return result; +} +static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len) +{ + int result; + if (strlen(str2)>len) + result = (int) strncpy(str1, str2,len); + else + result = (int) strcpy(str1,str2); + dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result); + return result; +} +static LONG WINAPI explstrcatA(char* str1, const char* str2) +{ + int result= (int) strcat(str1, str2); + dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result); + return result; +} + + +static LONG WINAPI expInterlockedExchange(long *dest, long l) +{ + long retval = *dest; + *dest = l; + return retval; +} + +static void WINAPI expInitCommonControls(void) +{ + dbgprintf("InitCommonControls called!\n"); + return; +} + +#ifdef QTX +/* needed by QuickTime.qts */ +static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy, + HWND parent, INT id, HINSTANCE inst, + HWND buddy, INT maxVal, INT minVal, INT curVal) +{ + dbgprintf("CreateUpDownControl(...)\n"); + return 0; +} +#endif + +/* alex: implement this call! needed for 3ivx */ +static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner) +{ + dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n", + pUnkOuter, ppUnkInner); +// return 0; + return ERROR_CALL_NOT_IMPLEMENTED; +} + + +static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process + HANDLE hSourceHandle, // handle to duplicate + HANDLE hTargetProcessHandle, // handle to target process + HANDLE* lpTargetHandle, // duplicate handle + DWORD dwDesiredAccess, // requested access + int bInheritHandle, // handle inheritance option + DWORD dwOptions // optional actions + ) +{ + dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n", + hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, + lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions); + *lpTargetHandle = hSourceHandle; + return 1; +} + +// required by PIM1 codec (used by win98 PCTV Studio capture sw) +static HRESULT WINAPI expCoInitialize( + LPVOID lpReserved /* [in] pointer to win32 malloc interface + (obsolete, should be NULL) */ + ) +{ + /* + * Just delegate to the newer method. + */ + return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED); +} + +static DWORD WINAPI expSetThreadAffinityMask +( + HANDLE hThread, + DWORD dwThreadAffinityMask +){ + return 0; +}; + +/* + * no WINAPI functions - CDECL + */ +static void* expmalloc(int size) +{ + //printf("malloc"); + // return malloc(size); + void* result=my_mreq(size,0); + dbgprintf("malloc(0x%x) => 0x%x\n", size,result); + if(result==0) + printf("WARNING: malloc() failed\n"); + return result; +} +static void expfree(void* mem) +{ + // return free(mem); + dbgprintf("free(%p)\n", mem); + my_release(mem); +} +/* needed by atrac3.acm */ +static void *expcalloc(int num, int size) +{ + void* result=my_mreq(num*size,1); + dbgprintf("calloc(%d,%d) => %p\n", num,size,result); + if(result==0) + printf("WARNING: calloc() failed\n"); + return result; +} +static void* expnew(int size) +{ + // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size)); + // printf("%08x %08x %08x %08x\n", + // size, *(1+(int*)&size), + // *(2+(int*)&size),*(3+(int*)&size)); + void* result; + assert(size >= 0); + + result=my_mreq(size,0); + dbgprintf("new(%d) => %p\n", size, result); + if (result==0) + printf("WARNING: new() failed\n"); + return result; + +} +static int expdelete(void* memory) +{ + dbgprintf("delete(%p)\n", memory); + my_release(memory); + return 0; +} + +/* + * local definition - we need only the last two members at this point + * otherwice we would have to introduce here GUIDs and some more types.. + */ +typedef struct __attribute__((__packed__)) +{ + char hay[0x40]; + unsigned long cbFormat; //0x40 + char* pbFormat; //0x44 +} MY_MEDIA_TYPE; +static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src) +{ + if (!dest || !src) + return E_POINTER; + memcpy(dest, src, sizeof(MY_MEDIA_TYPE)); + if (dest->cbFormat) + { + dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0); + if (!dest->pbFormat) + return E_OUTOFMEMORY; + memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat); + } + return S_OK; +} +static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat) +{ + if (!dest) + return E_POINTER; + memset(dest, 0, sizeof(MY_MEDIA_TYPE)); + if (cbFormat) + { + dest->pbFormat = (char*) my_mreq(cbFormat, 0); + if (!dest->pbFormat) + return E_OUTOFMEMORY; + } + return S_OK; +} +static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat) +{ + if (!dest) + return E_POINTER; + *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0); + return expMoInitMediaType(*dest, cbFormat); +} +static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src) +{ + if (!dest) + return E_POINTER; + *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0); + return expMoCopyMediaType(*dest, src); +} +static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest) +{ + if (!dest) + return E_POINTER; + if (dest->pbFormat) + { + my_release(dest->pbFormat); + dest->pbFormat = 0; + dest->cbFormat = 0; + } + return S_OK; +} +static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest) +{ + if (!dest) + return E_POINTER; + expMoFreeMediaType(dest); + my_release(dest); + return S_OK; +} + + +#if 0 +static int exp_initterm(int v1, int v2) +{ + dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); + return 0; +} +#else +/* merged from wine - 2002.04.21 */ +typedef void (*_INITTERMFUNC)(); +static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end) +{ + dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start); + while (start < end) + { + if (*start) + { + //printf("call _initfunc: from: %p %d\n", *start); + // ok this trick with push/pop is necessary as otherwice + // edi/esi registers are being trashed + void* p = *start; + __asm__ __volatile__ + ( + "pushl %%ebx \n\t" + "pushl %%ecx \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "pushl %%esi \n\t" + "call *%%eax \n\t" + "popl %%esi \n\t" + "popl %%edi \n\t" + "popl %%edx \n\t" + "popl %%ecx \n\t" + "popl %%ebx \n\t" + : + : "a"(p) + : "memory" + ); + //printf("done %p %d:%d\n", end); + } + start++; + } + return 0; +} +#endif + +static void* exp__dllonexit() +{ + // FIXME extract from WINE + return NULL; +} + +static int expwsprintfA(char* string, char* format, ...) +{ + va_list va; + int result; + va_start(va, format); + result = vsprintf(string, format, va); + dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result); + va_end(va); + return result; +} + +static int expsprintf(char* str, const char* format, ...) +{ + va_list args; + int r; + dbgprintf("sprintf(%s, %s)\n", str, format); + va_start(args, format); + r = vsprintf(str, format, args); + va_end(args); + return r; +} +static int expsscanf(const char* str, const char* format, ...) +{ + va_list args; + int r; + dbgprintf("sscanf(%s, %s)\n", str, format); + va_start(args, format); + r = vsscanf(str, format, args); + va_end(args); + return r; +} +static void* expfopen(const char* path, const char* mode) +{ + printf("fopen: \"%s\" mode:%s\n", path, mode); + //return fopen(path, mode); + return fdopen(0, mode); // everything on screen +} +static int expfprintf(void* stream, const char* format, ...) +{ + va_list args; + int r = 0; + dbgprintf("fprintf(%p, %s, ...)\n", stream, format); +#if 1 + va_start(args, format); + r = vfprintf((FILE*) stream, format, args); + va_end(args); +#endif + return r; +} + +static int expprintf(const char* format, ...) +{ + va_list args; + int r; + dbgprintf("printf(%s, ...)\n", format); + va_start(args, format); + r = vprintf(format, args); + va_end(args); + return r; +} + +static char* expgetenv(const char* varname) +{ + char* v = getenv(varname); + dbgprintf("getenv(%s) => %s\n", varname, v); + return v; +} + +static void* expwcscpy(WCHAR* dst, const WCHAR* src) +{ + WCHAR* p = dst; + while ((*p++ = *src++)) + ; + return dst; +} + +static char* expstrrchr(char* string, int value) +{ + char* result=strrchr(string, value); + if(result) + dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result); + else + dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value); + return result; +} + +static char* expstrchr(char* string, int value) +{ + char* result=strchr(string, value); + if(result) + dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result); + else + dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value); + return result; +} +static int expstrlen(char* str) +{ + int result=strlen(str); + dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result); + return result; +} +static char* expstrcpy(char* str1, const char* str2) +{ + char* result= strcpy(str1, str2); + dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result); + return result; +} +static char* expstrncpy(char* str1, const char* str2, size_t count) +{ + char* result= strncpy(str1, str2, count); + dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result); + return result; +} +static int expstrcmp(const char* str1, const char* str2) +{ + int result=strcmp(str1, str2); + dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result); + return result; +} +static int expstrncmp(const char* str1, const char* str2,int x) +{ + int result=strncmp(str1, str2,x); + dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result); + return result; +} +static char* expstrcat(char* str1, const char* str2) +{ + char* result = strcat(str1, str2); + dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result); + return result; +} +static char* exp_strdup(const char* str1) +{ + int l = strlen(str1); + char* result = (char*) my_mreq(l + 1,0); + if (result) + strcpy(result, str1); + dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result); + return result; +} +static int expisalnum(int c) +{ + int result= (int) isalnum(c); + dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result); + return result; +} +static int expisspace(int c) +{ + int result= (int) isspace(c); + dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result); + return result; +} +static int expisalpha(int c) +{ + int result= (int) isalpha(c); + dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result); + return result; +} +static int expisdigit(int c) +{ + int result= (int) isdigit(c); + dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result); + return result; +} +static void* expmemmove(void* dest, void* src, int n) +{ + void* result = memmove(dest, src, n); + dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result); + return result; +} +static int expmemcmp(void* dest, void* src, int n) +{ + int result = memcmp(dest, src, n); + dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result); + return result; +} +static void* expmemcpy(void* dest, void* src, int n) +{ + void *result = memcpy(dest, src, n); + dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result); + return result; +} +static void* expmemset(void* dest, int c, size_t n) +{ + void *result = memset(dest, c, n); + dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result); + return result; +} +static time_t exptime(time_t* t) +{ + time_t result = time(t); + dbgprintf("time(0x%x) => %d\n", t, result); + return result; +} + +static int exprand(void) +{ + return rand(); +} + +static void expsrand(int seed) +{ + srand(seed); +} + +#if 1 + +// prefered compilation with -O2 -ffast-math ! + +static double explog10(double x) +{ + /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/ + return log10(x); +} + +static double expcos(double x) +{ + /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ + return cos(x); +} + +/* doens't work */ +static long exp_ftol_wrong(double x) +{ + return (long) x; +} + +#else + +static void explog10(void) +{ + __asm__ __volatile__ + ( + "fldl 8(%esp) \n\t" + "fldln2 \n\t" + "fxch %st(1) \n\t" + "fyl2x \n\t" + ); +} + +static void expcos(void) +{ + __asm__ __volatile__ + ( + "fldl 8(%esp) \n\t" + "fcos \n\t" + ); +} + +#endif + +// this seem to be the only how to make this function working properly +// ok - I've spent tremendous amount of time (many many many hours +// of debuging fixing & testing - it's almost unimaginable - kabi + +// _ftol - operated on the float value which is already on the FPU stack + +static void exp_ftol(void) +{ + __asm__ __volatile__ + ( + "sub $12, %esp \n\t" + "fstcw -2(%ebp) \n\t" + "wait \n\t" + "movw -2(%ebp), %ax \n\t" + "orb $0x0C, %ah \n\t" + "movw %ax, -4(%ebp) \n\t" + "fldcw -4(%ebp) \n\t" + "fistpl -12(%ebp) \n\t" + "fldcw -2(%ebp) \n\t" + "movl -12(%ebp), %eax \n\t" + //Note: gcc 3.03 does not do the following op if it + // knows that ebp=esp + "movl %ebp, %esp \n\t" + ); +} + +#warning check for _CIpow +static double exp_CIpow(double x, double y) +{ + /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/ + return pow(x, y); +} + +static double exppow(double x, double y) +{ + /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/ + return pow(x, y); +} + +static double expldexp(double x, int expo) +{ + /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ + return ldexp(x, expo); +} + +static double expfrexp(double x, int* expo) +{ + /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ + return frexp(x, expo); +} + + + +static int exp_stricmp(const char* s1, const char* s2) +{ + return strcasecmp(s1, s2); +} + +/* from declaration taken from Wine sources - this fountion seems to be + * undocumented in any M$ doc */ +static int exp_setjmp3(void* jmpbuf, int x) +{ + //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x); + //return 0; + __asm__ __volatile__ + ( + //"mov 4(%%esp), %%edx \n\t" + "mov (%%esp), %%eax \n\t" + "mov %%eax, (%%edx) \n\t" // store ebp + + //"mov %%ebp, (%%edx) \n\t" + "mov %%ebx, 4(%%edx) \n\t" + "mov %%edi, 8(%%edx) \n\t" + "mov %%esi, 12(%%edx) \n\t" + "mov %%esp, 16(%%edx) \n\t" + + "mov 4(%%esp), %%eax \n\t" + "mov %%eax, 20(%%edx) \n\t" + + "movl $0x56433230, 32(%%edx) \n\t" // VC20 ?? + "movl $0, 36(%%edx) \n\t" + : // output + : "d"(jmpbuf) // input + : "eax" + ); +#if 1 + __asm__ __volatile__ + ( + "mov %%fs:0, %%eax \n\t" // unsure + "mov %%eax, 24(%%edx) \n\t" + "cmp $0xffffffff, %%eax \n\t" + "jnz l1 \n\t" + "mov %%eax, 28(%%edx) \n\t" + "l1: \n\t" + : + : + : "eax" + ); +#endif + + return 0; +} + +static DWORD WINAPI expGetCurrentProcessId(void) +{ + dbgprintf("GetCurrentProcessId(void) => %d\n", getpid()); + return getpid(); //(DWORD)NtCurrentTeb()->pid; +} + + +typedef struct { + UINT wPeriodMin; + UINT wPeriodMax; +} TIMECAPS, *LPTIMECAPS; + +static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize) +{ + dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize); + + lpCaps->wPeriodMin = 1; + lpCaps->wPeriodMax = 65535; + return 0; +} + +static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod) +{ + dbgprintf("timeBeginPeriod(%u) !\n", wPeriod); + + if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO; + return 0; +} + +#ifdef QTX +static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod) +{ + dbgprintf("timeEndPeriod(%u) !\n", wPeriod); + + if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO; + return 0; +} +#endif + +static void WINAPI expGlobalMemoryStatus( + LPMEMORYSTATUS lpmem +) { + static MEMORYSTATUS cached_memstatus; + static int cache_lastchecked = 0; + SYSTEM_INFO si; + FILE *f; + + if (time(NULL)==cache_lastchecked) { + memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS)); + return; + } + +#if 1 + f = fopen( "/proc/meminfo", "r" ); + if (f) + { + char buffer[256]; + int total, used, free, shared, buffers, cached; + + lpmem->dwLength = sizeof(MEMORYSTATUS); + lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0; + lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0; + while (fgets( buffer, sizeof(buffer), f )) + { + /* old style /proc/meminfo ... */ + if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached )) + { + lpmem->dwTotalPhys += total; + lpmem->dwAvailPhys += free + buffers + cached; + } + if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free )) + { + lpmem->dwTotalPageFile += total; + lpmem->dwAvailPageFile += free; + } + + /* new style /proc/meminfo ... */ + if (sscanf(buffer, "MemTotal: %d", &total)) + lpmem->dwTotalPhys = total*1024; + if (sscanf(buffer, "MemFree: %d", &free)) + lpmem->dwAvailPhys = free*1024; + if (sscanf(buffer, "SwapTotal: %d", &total)) + lpmem->dwTotalPageFile = total*1024; + if (sscanf(buffer, "SwapFree: %d", &free)) + lpmem->dwAvailPageFile = free*1024; + if (sscanf(buffer, "Buffers: %d", &buffers)) + lpmem->dwAvailPhys += buffers*1024; + if (sscanf(buffer, "Cached: %d", &cached)) + lpmem->dwAvailPhys += cached*1024; + } + fclose( f ); + + if (lpmem->dwTotalPhys) + { + DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile; + DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile; + lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical) + / (TotalPhysical / 100); + } + } else +#endif + { + /* FIXME: should do something for other systems */ + lpmem->dwMemoryLoad = 0; + lpmem->dwTotalPhys = 16*1024*1024; + lpmem->dwAvailPhys = 16*1024*1024; + lpmem->dwTotalPageFile = 16*1024*1024; + lpmem->dwAvailPageFile = 16*1024*1024; + } + expGetSystemInfo(&si); + lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress; + /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */ + lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024; + memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS)); + cache_lastchecked = time(NULL); + + /* it appears some memory display programs want to divide by these values */ + if(lpmem->dwTotalPageFile==0) + lpmem->dwTotalPageFile++; + + if(lpmem->dwAvailPageFile==0) + lpmem->dwAvailPageFile++; +} + +/********************************************************************** + * SetThreadPriority [KERNEL32.@] Sets priority for thread. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +static WIN_BOOL WINAPI expSetThreadPriority( + HANDLE hthread, /* [in] Handle to thread */ + INT priority) /* [in] Thread priority level */ +{ + dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority); + return TRUE; +} + +static void WINAPI expExitProcess( DWORD status ) +{ + printf("EXIT - code %ld\n",status); + exit(status); +} + +static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){ + printf("MSGBOX '%s' '%s' (%d)\n",text,title,type); +#ifdef QTX + if (type == MB_ICONHAND && !strlen(text) && !strlen(title)) + return IDIGNORE; +#endif + return IDOK; +} + +/* these are needed for mss1 */ + +/* defined in stubs.s */ +void exp_EH_prolog(void); + +#include +static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong) +{ +// dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong)); + return htonl(hostlong); +} + +static WINAPI inline unsigned long int expntohl(unsigned long int netlong) +{ +// dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong)); + return ntohl(netlong); +} +static void WINAPI expVariantInit(void* p) +{ + printf("InitCommonControls called!\n"); + return; +} + +int expRegisterClassA(const void/*WNDCLASSA*/ *wc) +{ + dbgprintf("RegisterClassA(%p) => random id\n", wc); + return time(NULL); /* be precise ! */ +} + +int expUnregisterClassA(const char *className, HINSTANCE hInstance) +{ + dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance); + return 0; +} + +#ifdef QTX +/* should be fixed bcs it's not fully strlen equivalent */ +static int expSysStringByteLen(void *str) +{ + dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str)); + return strlen(str); +} + +static int expDirectDrawCreate(void) +{ + dbgprintf("DirectDrawCreate(...) => NULL\n"); + return 0; +} + +#if 1 +typedef struct tagPALETTEENTRY { + BYTE peRed; + BYTE peGreen; + BYTE peBlue; + BYTE peFlags; +} PALETTEENTRY; + +/* reversed the first 2 entries */ +typedef struct tagLOGPALETTE { + WORD palNumEntries; + WORD palVersion; + PALETTEENTRY palPalEntry[1]; +} LOGPALETTE; + +static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl) +{ + HPALETTE test; + int i; + + dbgprintf("CreatePalette(%x) => NULL\n", lpgpl); + + i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY)); + test = (HPALETTE)malloc(i); + memcpy((void *)test, lpgpl, i); + + return test; +} +#else +static int expCreatePalette(void) +{ + dbgprintf("CreatePalette(...) => NULL\n"); + return NULL; +} +#endif + +static int WINAPI expGetClientRect(HWND win, RECT *r) +{ + dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r); + r->right = PSEUDO_SCREEN_WIDTH; + r->left = 0; + r->bottom = PSEUDO_SCREEN_HEIGHT; + r->top = 0; + return 1; +} + +#if 0 +typedef struct tagPOINT { + LONG x; + LONG y; +} POINT, *PPOINT; +#endif + +static int WINAPI expClientToScreen(HWND win, POINT *p) +{ + dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y); + p->x = 0; + p->y = 0; + return 1; +} +#endif + +/* for m3jpeg */ +static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc) +{ + dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc); + return 0; +} + +static int WINAPI expMessageBeep(int type) +{ + dbgprintf("MessageBeep(%d) => 1\n", type); + return 1; +} + +static int WINAPI expDialogBoxParamA(void *inst, const char *name, + HWND parent, void *dialog_func, void *init_param) +{ + dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n", + inst, name, name, parent, dialog_func, init_param); + return 0x42424242; +} + +/* needed by imagepower mjpeg2k */ +static void *exprealloc(void *ptr, size_t size) +{ + dbgprintf("realloc(0x%x, %x)\n", ptr, size); + if (!ptr) + return my_mreq(size,0); + else + return my_realloc(ptr, size); +} + +struct exports +{ + char name[64]; + int id; + void* func; +}; +struct libs +{ + char name[64]; + int length; + struct exports* exps; +}; + +#define FF(X,Y) \ + {#X, Y, (void*)exp##X}, + +struct exports exp_kernel32[]= +{ + FF(IsBadWritePtr, 357) + FF(IsBadReadPtr, 354) + FF(IsBadStringPtrW, -1) + FF(IsBadStringPtrA, -1) + FF(DisableThreadLibraryCalls, -1) + FF(CreateThread, -1) + FF(CreateEventA, -1) + FF(SetEvent, -1) + FF(ResetEvent, -1) + FF(WaitForSingleObject, -1) +#ifdef QTX + FF(WaitForMultipleObjects, -1) + FF(ExitThread, -1) + FF(CreateMutexA,-1) + FF(ReleaseMutex,-1) +#endif + FF(GetSystemInfo, -1) + FF(GetVersion, 332) + FF(HeapCreate, 461) + FF(HeapAlloc, -1) + FF(HeapDestroy, -1) + FF(HeapFree, -1) + FF(HeapSize, -1) + FF(HeapReAlloc,-1) + FF(GetProcessHeap, -1) + FF(VirtualAlloc, -1) + FF(VirtualFree, -1) + FF(InitializeCriticalSection, -1) + FF(EnterCriticalSection, -1) + FF(LeaveCriticalSection, -1) + FF(DeleteCriticalSection, -1) + FF(TlsAlloc, -1) + FF(TlsFree, -1) + FF(TlsGetValue, -1) + FF(TlsSetValue, -1) + FF(GetCurrentThreadId, -1) + FF(GetCurrentProcess, -1) + FF(LocalAlloc, -1) + FF(LocalReAlloc,-1) + FF(LocalLock, -1) + FF(GlobalAlloc, -1) + FF(GlobalReAlloc, -1) + FF(GlobalLock, -1) + FF(GlobalSize, -1) + FF(MultiByteToWideChar, 427) + FF(WideCharToMultiByte, -1) + FF(GetVersionExA, -1) + FF(CreateSemaphoreA, -1) + FF(QueryPerformanceCounter, -1) + FF(QueryPerformanceFrequency, -1) + FF(LocalHandle, -1) + FF(LocalUnlock, -1) + FF(LocalFree, -1) + FF(GlobalHandle, -1) + FF(GlobalUnlock, -1) + FF(GlobalFree, -1) + FF(LoadResource, -1) + FF(ReleaseSemaphore, -1) + FF(FindResourceA, -1) + FF(LockResource, -1) + FF(FreeResource, -1) + FF(SizeofResource, -1) + FF(CloseHandle, -1) + FF(GetCommandLineA, -1) + FF(GetEnvironmentStringsW, -1) + FF(FreeEnvironmentStringsW, -1) + FF(FreeEnvironmentStringsA, -1) + FF(GetEnvironmentStrings, -1) + FF(GetStartupInfoA, -1) + FF(GetStdHandle, -1) + FF(GetFileType, -1) +#ifdef QTX + FF(GetFileAttributesA, -1) +#endif + FF(SetHandleCount, -1) + FF(GetACP, -1) + FF(GetModuleFileNameA, -1) + FF(SetUnhandledExceptionFilter, -1) + FF(LoadLibraryA, -1) + FF(GetProcAddress, -1) + FF(FreeLibrary, -1) + FF(CreateFileMappingA, -1) + FF(OpenFileMappingA, -1) + FF(MapViewOfFile, -1) + FF(UnmapViewOfFile, -1) + FF(Sleep, -1) + FF(GetModuleHandleA, -1) + FF(GetProfileIntA, -1) + FF(GetPrivateProfileIntA, -1) + FF(GetPrivateProfileStringA, -1) + FF(WritePrivateProfileStringA, -1) + FF(GetLastError, -1) + FF(SetLastError, -1) + FF(InterlockedIncrement, -1) + FF(InterlockedDecrement, -1) + FF(GetTimeZoneInformation, -1) + FF(OutputDebugStringA, -1) + FF(GetLocalTime, -1) + FF(GetSystemTime, -1) + FF(GetSystemTimeAsFileTime, -1) + FF(GetEnvironmentVariableA, -1) + FF(SetEnvironmentVariableA, -1) + FF(RtlZeroMemory,-1) + FF(RtlMoveMemory,-1) + FF(RtlFillMemory,-1) + FF(GetTempPathA,-1) + FF(FindFirstFileA,-1) + FF(FindNextFileA,-1) + FF(FindClose,-1) + FF(FileTimeToLocalFileTime,-1) + FF(DeleteFileA,-1) + FF(ReadFile,-1) + FF(WriteFile,-1) + FF(SetFilePointer,-1) + FF(GetTempFileNameA,-1) + FF(CreateFileA,-1) + FF(GetSystemDirectoryA,-1) + FF(GetWindowsDirectoryA,-1) +#ifdef QTX + FF(GetCurrentDirectoryA,-1) + FF(SetCurrentDirectoryA,-1) + FF(CreateDirectoryA,-1) +#endif + FF(GetShortPathNameA,-1) + FF(GetFullPathNameA,-1) + FF(SetErrorMode, -1) + FF(IsProcessorFeaturePresent, -1) + FF(GetProcessAffinityMask, -1) + FF(InterlockedExchange, -1) + FF(InterlockedCompareExchange, -1) + FF(MulDiv, -1) + FF(lstrcmpiA, -1) + FF(lstrlenA, -1) + FF(lstrcpyA, -1) + FF(lstrcatA, -1) + FF(lstrcpynA,-1) + FF(GetProcessVersion,-1) + FF(GetCurrentThread,-1) + FF(GetOEMCP,-1) + FF(GetCPInfo,-1) + FF(DuplicateHandle,-1) + FF(GetTickCount, -1) + FF(SetThreadAffinityMask,-1) + FF(GetCurrentProcessId,-1) + FF(GlobalMemoryStatus,-1) + FF(SetThreadPriority,-1) + FF(ExitProcess,-1) + {"LoadLibraryExA", -1, (void*)&LoadLibraryExA}, + FF(SetThreadIdealProcessor,-1) +}; + +struct exports exp_msvcrt[]={ + FF(malloc, -1) + FF(_initterm, -1) + FF(__dllonexit, -1) + FF(free, -1) + {"??3@YAXPAX@Z", -1, expdelete}, + {"??2@YAPAXI@Z", -1, expnew}, + {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, + FF(strrchr, -1) + FF(strchr, -1) + FF(strlen, -1) + FF(strcpy, -1) + FF(strncpy, -1) + FF(wcscpy, -1) + FF(strcmp, -1) + FF(strncmp, -1) + FF(strcat, -1) + FF(_stricmp,-1) + FF(_strdup,-1) + FF(_setjmp3,-1) + FF(isalnum, -1) + FF(isspace, -1) + FF(isalpha, -1) + FF(isdigit, -1) + FF(memmove, -1) + FF(memcmp, -1) + FF(memset, -1) + FF(memcpy, -1) + FF(time, -1) + FF(rand, -1) + FF(srand, -1) + FF(log10, -1) + FF(pow, -1) + FF(cos, -1) + FF(_ftol,-1) + FF(_CIpow,-1) + FF(ldexp,-1) + FF(frexp,-1) + FF(sprintf,-1) + FF(sscanf,-1) + FF(fopen,-1) + FF(fprintf,-1) + FF(printf,-1) + FF(getenv,-1) +#ifdef MPLAYER + FF(_EH_prolog,-1) +#endif + FF(calloc,-1) + {"ceil",-1,(void*)&ceil}, +/* needed by imagepower mjpeg2k */ + {"clock",-1,(void*)&clock}, + {"memchr",-1,(void*)&memchr}, + {"vfprintf",-1,(void*)&vfprintf}, +// {"realloc",-1,(void*)&realloc}, + FF(realloc,-1) + {"puts",-1,(void*)&puts} +}; +struct exports exp_winmm[]={ + FF(GetDriverModuleHandle, -1) + FF(timeGetTime, -1) + FF(DefDriverProc, -1) + FF(OpenDriverA, -1) + FF(OpenDriver, -1) + FF(timeGetDevCaps, -1) + FF(timeBeginPeriod, -1) +#ifdef QTX + FF(timeEndPeriod, -1) + FF(waveOutGetNumDevs, -1) +#endif +}; +struct exports exp_user32[]={ + FF(LoadStringA, -1) + FF(wsprintfA, -1) + FF(GetDC, -1) + FF(GetDesktopWindow, -1) + FF(ReleaseDC, -1) + FF(IsRectEmpty, -1) + FF(LoadCursorA,-1) + FF(SetCursor,-1) + FF(GetCursorPos,-1) +#ifdef QTX + FF(ShowCursor,-1) +#endif + FF(RegisterWindowMessageA,-1) + FF(GetSystemMetrics,-1) + FF(GetSysColor,-1) + FF(GetSysColorBrush,-1) + FF(GetWindowDC, -1) + FF(DrawTextA, -1) + FF(MessageBoxA, -1) + FF(RegisterClassA, -1) + FF(UnregisterClassA, -1) +#ifdef QTX + FF(GetWindowRect, -1) + FF(MonitorFromWindow, -1) + FF(MonitorFromRect, -1) + FF(MonitorFromPoint, -1) + FF(EnumDisplayMonitors, -1) + FF(GetMonitorInfoA, -1) + FF(EnumDisplayDevicesA, -1) + FF(GetClientRect, -1) + FF(ClientToScreen, -1) + FF(IsWindowVisible, -1) + FF(GetActiveWindow, -1) + FF(GetClassNameA, -1) + FF(GetClassInfoA, -1) + FF(GetWindowLongA, -1) + FF(EnumWindows, -1) + FF(GetWindowThreadProcessId, -1) + FF(CreateWindowExA, -1) +#endif + FF(MessageBeep, -1) + FF(DialogBoxParamA, -1) +}; +struct exports exp_advapi32[]={ + FF(RegCloseKey, -1) + FF(RegCreateKeyExA, -1) + FF(RegEnumKeyExA, -1) + FF(RegEnumValueA, -1) + FF(RegOpenKeyA, -1) + FF(RegOpenKeyExA, -1) + FF(RegQueryValueExA, -1) + FF(RegSetValueExA, -1) +}; +struct exports exp_gdi32[]={ + FF(CreateCompatibleDC, -1) + FF(CreateFontA, -1) + FF(DeleteDC, -1) + FF(DeleteObject, -1) + FF(GetDeviceCaps, -1) + FF(GetSystemPaletteEntries, -1) +#ifdef QTX + FF(CreatePalette, -1) + FF(GetObjectA, -1) + FF(CreateRectRgn, -1) +#endif +}; +struct exports exp_version[]={ + FF(GetFileVersionInfoSizeA, -1) +}; +struct exports exp_ole32[]={ + FF(CoCreateFreeThreadedMarshaler,-1) + FF(CoCreateInstance, -1) + FF(CoInitialize, -1) + FF(CoTaskMemAlloc, -1) + FF(CoTaskMemFree, -1) + FF(StringFromGUID2, -1) +}; +// do we really need crtdll ??? +// msvcrt is the correct place probably... +struct exports exp_crtdll[]={ + FF(memcpy, -1) + FF(wcscpy, -1) +}; +struct exports exp_comctl32[]={ + FF(StringFromGUID2, -1) + FF(InitCommonControls, 17) +#ifdef QTX + FF(CreateUpDownControl, 16) +#endif +}; +struct exports exp_wsock32[]={ + FF(htonl,8) + FF(ntohl,14) +}; +struct exports exp_msdmo[]={ + FF(memcpy, -1) // just test + FF(MoCopyMediaType, -1) + FF(MoCreateMediaType, -1) + FF(MoDeleteMediaType, -1) + FF(MoDuplicateMediaType, -1) + FF(MoFreeMediaType, -1) + FF(MoInitMediaType, -1) +}; +struct exports exp_oleaut32[]={ + FF(VariantInit, 8) +#ifdef QTX + FF(SysStringByteLen, 149) +#endif +}; + +/* realplayer8: + DLL Name: PNCRT.dll + vma: Hint/Ord Member-Name + 22ff4 615 free + 2302e 250 _ftol + 22fea 666 malloc + 2303e 609 fprintf + 2305e 167 _adjust_fdiv + 23052 280 _initterm + + 22ffc 176 _beginthreadex + 23036 284 _iob + 2300e 85 __CxxFrameHandler + 23022 411 _purecall +*/ +#ifdef REALPLAYER +struct exports exp_pncrt[]={ + FF(malloc, -1) // just test + FF(free, -1) // just test + FF(fprintf, -1) // just test + {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, + FF(_ftol,-1) + FF(_initterm, -1) + {"??3@YAXPAX@Z", -1, expdelete}, + {"??2@YAPAXI@Z", -1, expnew}, + FF(__dllonexit, -1) + FF(strncpy, -1) + FF(_CIpow,-1) + FF(calloc,-1) + FF(memmove, -1) +}; +#endif + +#ifdef QTX +struct exports exp_ddraw[]={ + FF(DirectDrawCreate, -1) +}; +#endif + +#define LL(X) \ + {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, + +struct libs libraries[]={ + LL(kernel32) + LL(msvcrt) + LL(winmm) + LL(user32) + LL(advapi32) + LL(gdi32) + LL(version) + LL(ole32) + LL(oleaut32) + LL(crtdll) + LL(comctl32) + LL(wsock32) + LL(msdmo) +#ifdef REALPLAYER + LL(pncrt) +#endif +#ifdef QTX + LL(ddraw) +#endif +}; + +static void ext_stubs(void) +{ + // expects: + // ax position index + // cx address of printf function +#if 1 + __asm__ __volatile__ + ( + "push %%edx \n\t" + "movl $0xdeadbeef, %%eax \n\t" + "movl $0xdeadbeef, %%edx \n\t" + "shl $5, %%eax \n\t" // ax * 32 + "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names + "pushl %%eax \n\t" + "pushl $0xdeadbeef \n\t" // overwrite called_unk + "call *%%edx \n\t" // printf (via dx) + "addl $8, %%esp \n\t" + "xorl %%eax, %%eax \n\t" + "pop %%edx \n\t" + : + : + : "eax" + ); +#else + __asm__ __volatile__ + ( + "push %%edx \n\t" + "movl $0, %%eax \n\t" + "movl $0, %%edx \n\t" + "shl $5, %%eax \n\t" // ax * 32 + "addl %0, %%eax \n\t" + "pushl %%eax \n\t" + "pushl %1 \n\t" + "call *%%edx \n\t" // printf (via dx) + "addl $8, %%esp \n\t" + "xorl %%eax, %%eax \n\t" + "pop %%edx \n\t" + ::"m"(*export_names), "m"(*called_unk) + : "memory", "edx", "eax" + ); +#endif + +} + +//static void add_stub(int pos) + +extern int unk_exp1; +static int pos=0; +static char extcode[20000];// place for 200 unresolved exports +static const char* called_unk = "Called unk_%s\n"; + +static void* add_stub(void) +{ + // generated code in runtime! + char* answ = (char*)extcode+pos*0x30; +#if 0 + memcpy(answ, &unk_exp1, 0x64); + *(int*)(answ+9)=pos; + *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); +#endif + memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size + //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000) + *((int*) (answ + 5)) = pos; + //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000) + *((long*) (answ + 10)) = (long)printf; + //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000) + *((long*) (answ + 18)) = (long)export_names; + //answ[23] = 0x68; // pushl $0 (0x68 0x00000000) + *((long*) (answ + 24)) = (long)called_unk; + pos++; + return (void*)answ; +} + +void* LookupExternal(const char* library, int ordinal) +{ + int i,j; + if(library==0) + { + printf("ERROR: library=0\n"); + return (void*)ext_unknown; + } + // printf("%x %x\n", &unk_exp1, &unk_exp2); + + printf("External func %s:%d\n", library, ordinal); + + for(i=0; i150)return 0; + sprintf(export_names[pos], "%s:%d", library, ordinal); + return add_stub(); +} + +void* LookupExternalByName(const char* library, const char* name) +{ + char* answ; + int i,j; + // return (void*)ext_unknown; + if(library==0) + { + printf("ERROR: library=0\n"); + return (void*)ext_unknown; + } + if(name==0) + { + printf("ERROR: name=0\n"); + return (void*)ext_unknown; + } + dbgprintf("External func %s:%s\n", library, name); + for(i=0; i150)return 0;// to many symbols + strcpy(export_names[pos], name); + return add_stub(); +} + +void my_garbagecollection(void) +{ +#ifdef GARBAGE + int unfree = 0, unfreecnt = 0; + + int max_fatal = 8; + free_registry(); + while (last_alloc) + { + alloc_header* mem = last_alloc + 1; + unfree += my_size(mem); + unfreecnt++; + if (my_release(mem) != 0) + // avoid endless loop when memory is trashed + if (--max_fatal < 0) + break; + } + printf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt); +#endif + g_tls = NULL; + list = NULL; +} diff --git a/linphone/win32acm/win32.h b/linphone/win32acm/win32.h new file mode 100644 index 000000000..46512ada9 --- /dev/null +++ b/linphone/win32acm/win32.h @@ -0,0 +1,40 @@ +#ifndef loader_win32_h +#define loader_win32_h + +#include + +#include "wine/windef.h" +#include "wine/winbase.h" +#include "com.h" + +#ifdef AVIFILE +#ifdef __GNUC__ +#include "avm_output.h" +#ifndef __cplusplus +#define printf(a, ...) avm_printf("Win32 plugin", a, ## __VA_ARGS__) +#endif +#endif +#endif + +extern void my_garbagecollection(void); + +typedef struct { + UINT uDriverSignature; + HINSTANCE hDriverModule; + DRIVERPROC DriverProc; + DWORD dwDriverID; +} DRVR; + +typedef DRVR *PDRVR; +typedef DRVR *NPDRVR; +typedef DRVR *LPDRVR; + +typedef struct tls_s tls_t; + + +extern void* LookupExternal(const char* library, int ordinal); +extern void* LookupExternalByName(const char* library, const char* name); +extern int expRegisterClassA(const void/*WNDCLASSA*/ *wc); +extern int expUnregisterClassA(const char *className, HINSTANCE hInstance); + +#endif diff --git a/linphone/win32acm/win32codec.c b/linphone/win32acm/win32codec.c new file mode 100644 index 000000000..f3f353fe8 --- /dev/null +++ b/linphone/win32acm/win32codec.c @@ -0,0 +1,256 @@ +/* + Copyright 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include + +#include "win32codec.h" +#include "loader.h" +#include "driver.h" +#include "wine/windef.h" +#include "wineacm.h" + +/* FIXME figure out a better way to deal with these two things. */ +int verbose=5; +char* get_path(char* x){ return strdup(x);} + + +Win32CodecDriver* win32codec_create_driver(const char* dllName, + short formatTag, + int encodeFlag) +{ + Win32CodecDriver* d = 0; + short format = formatTag; + + d = malloc(sizeof(Win32CodecDriver)); + if (!d) + { + return 0; + } + + if (encodeFlag) + { + format = WAVE_FORMAT_PCM; + } + + d->id = MSACM_RegisterDriver(dllName, format, 0); + if (!d->id) + { + free(d); + return 0; + } + + return d; +} + + +void win32codec_destroy_driver(Win32CodecDriver* d) +{ + MSACM_UnregisterDriver(d->id); + free(d); +} + + + +Win32Codec* win32codec_create(const WAVEFORMATEX* wf, + int encode) +{ + Win32Codec* c = 0; + WAVEFORMATEX pcm_wf; + WAVEFORMATEX* i_wf = 0; + WAVEFORMATEX* o_wf = 0; + MMRESULT ret; + + c = malloc(sizeof(Win32Codec)); + if (!c) + { + return 0; + } + + /* Typical PCM format, 16-bit signed linear samples at + the same rate and number of channels as the desired + codec. + */ + memset(&pcm_wf, 0, sizeof(pcm_wf)); + + pcm_wf.wFormatTag = WAVE_FORMAT_PCM; + pcm_wf.nChannels = wf->nChannels; + pcm_wf.nSamplesPerSec = wf->nSamplesPerSec; + pcm_wf.wBitsPerSample = 16; + pcm_wf.nBlockAlign = pcm_wf.nChannels * pcm_wf.wBitsPerSample / 8; + pcm_wf.nAvgBytesPerSec = pcm_wf.nSamplesPerSec * pcm_wf.nBlockAlign; + + /* decide which way to perform the conversion */ + if (encode) + { + i_wf = &pcm_wf; + o_wf = wf; + } + else + { + i_wf = wf; + o_wf = &pcm_wf; + } + + /* Some codecs (like TrueSpeech) aren't confident they + can do realtime compression. + Tell it we don't care and it's happy. + */ + ret = acmStreamOpen(&c->handle, 0, i_wf, o_wf, 0, 0, 0, + ACM_STREAMOPENF_NONREALTIME); + if (ret) + { + free(c); + return 0; + } + + /* calculate minimum sizes to use for conversions */ + /* we assume that the format with the largest block alignment is + the most picky. And it basically turns out that TrueSpeech has + the largest block alignment. Anyway, we use that block alignment + to ask for the preferred size of the "other" format's buffer. + Then we turn around and ask for the first one's preferred buffer + size based on the other's buffer size, which seems to turn out + to be its block alignment. Or something like that. + */ + if (i_wf->nBlockAlign > o_wf->nBlockAlign) + { + ret = acmStreamSize(c->handle, i_wf->nBlockAlign, &c->min_outsize, + ACM_STREAMSIZEF_SOURCE); + if (ret) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + + if (!c->min_outsize) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + + ret = acmStreamSize(c->handle, c->min_outsize, &c->min_insize, + ACM_STREAMSIZEF_DESTINATION); + if (ret) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + } + else + { + ret = acmStreamSize(c->handle, o_wf->nBlockAlign, &c->min_insize, + ACM_STREAMSIZEF_DESTINATION); + if (ret) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + + if (!c->min_insize) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + + ret = acmStreamSize(c->handle, c->min_insize, &c->min_outsize, + ACM_STREAMSIZEF_SOURCE); + if (ret) + { + acmStreamClose(c->handle, 0); + free(c); + return 0; + } + } + + return c; +} + + + +void win32codec_destroy(Win32Codec* c) +{ + /* FIXME need to put this back. See TODO file + for ideas. + */ + printf("Warning: win32codec_destroy() stubbed out\n"); +/* acmStreamClose(c->handle, 0); */ + free(c); +} + + + +signed long win32codec_convert(Win32Codec* c, + const void* inbuf, long inlen, + void* outbuf, long outlen) +{ + ACMSTREAMHEADER header; + MMRESULT ret; + signed long rval; + + /* set up conversion buffers */ + memset(&header, 0, sizeof(header)); + header.cbStruct = sizeof(header); + header.cbSrcLength = inlen; + header.pbSrc = inbuf; + header.cbDstLength = outlen; + header.pbDst = outbuf; + + ret = acmStreamPrepareHeader(c->handle, &header, 0); + if (ret) + { + return -1; + } + + /* convert */ + ret = acmStreamConvert(c->handle, &header, 0); + if (ret) + { + return -1; + } + + if (!(header.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)) + { + return -1; + } + + if (header.cbSrcLengthUsed != header.cbSrcLength) + { + return -1; + } + + /* not sure if the header is still valid after unpreparing, + so let's save this off + */ + rval = header.cbDstLengthUsed; + + /* seemed to succeed, now unprepare the header */ + ret = acmStreamUnprepareHeader(c->handle, &header, 0); + if (ret) + { + return -1; + } + + return rval; +} + diff --git a/linphone/win32acm/win32codec.h b/linphone/win32acm/win32codec.h new file mode 100644 index 000000000..b63bdcb71 --- /dev/null +++ b/linphone/win32acm/win32codec.h @@ -0,0 +1,92 @@ +#ifndef _WIN32CODEC_H_ +#define _WIN32CODEC_H_ + +/* + Copyright 2003 Robert W. Brewer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + Wrapper for Windows ACM functions mainly designed to make it easier + to write Linphone codecs, but may be useful in other applications + too. +*/ + + +#include "wine/msacm.h" +#include "wineacm.h" + +typedef struct _Win32Codec +{ + HACMSTREAM handle; + unsigned int min_insize; + unsigned int min_outsize; +} Win32Codec; + + +typedef struct _Win32CodecDriver +{ + PWINE_ACMDRIVERID id; +} Win32CodecDriver; + + +/* Register an ACM DLL for the corresponding formatTag. + This should be called twice for each type of codec + needed, once with the encode flag set to encoding + and once for decoding (assuming both will be used). + Under the hood a PCM registration is made when encoding + is requested. Many instances + of a Win32Codec in the corresponding encode/decode mode can + be created after the DLL is registered with this call. + Returns 0 if driver could not be created. +*/ +Win32CodecDriver* win32codec_create_driver(const char* dllName, + short formatTag, + int encodeFlag); + +void win32codec_destroy_driver(Win32CodecDriver* d); + + + + +/* Create a codec that can handle 1 stream of data + in a single direction only. If encode is 1, the + data will originate in 16-bit signed linear PCM format at the + sampling rate and number of channels given in wf and be converted to wf. + If encode is 0, it will originate in the codec specified + by wf and be converted to 16-bit signed linear PCM at the same + sampling rate and number of channels. + + Returns 0 if codec cannot be created correctly. +*/ +Win32Codec* win32codec_create(const WAVEFORMATEX* wf, + int encodeFlag); +void win32codec_destroy(Win32Codec* c); + + +/* Best to use a multiple of min_insize and min_outsize + for inlen and outlen. + Returns: + -1: conversion failure + >= 0: number of bytes used in outbuf +*/ +signed long win32codec_convert(Win32Codec* c, const void* inbuf, long inlen, + void* outbuf, long outlen); + + + + +#endif /* _WIN32CODEC_H_ */ diff --git a/linphone/win32acm/wine/basetsd.h b/linphone/win32acm/wine/basetsd.h new file mode 100644 index 000000000..7b5d3aba9 --- /dev/null +++ b/linphone/win32acm/wine/basetsd.h @@ -0,0 +1,145 @@ +/* + * Compilers that uses ILP32, LP64 or P64 type models + * for both Win32 and Win64 are supported by this file. + */ + +#ifndef __WINE_BASETSD_H +#define __WINE_BASETSD_H + +#ifdef __WINE__ +#include "config.h" +#endif /* defined(__WINE__) */ + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/* + * Win32 was easy to implement under Unix since most (all?) 32-bit + * Unices uses the same type model (ILP32) as Win32, where int, long + * and pointer are 32-bit. + * + * Win64, however, will cause some problems when implemented under Unix. + * Linux/{Alpha, Sparc64} and most (all?) other 64-bit Unices uses + * the LP64 type model where int is 32-bit and long and pointer are + * 64-bit. Win64 on the other hand uses the P64 (sometimes called LLP64) + * type model where int and long are 32 bit and pointer is 64-bit. + */ + +/* Type model indepent typedefs */ + +typedef char __int8; +typedef unsigned char __uint8; + +typedef short __int16; +typedef unsigned short __uint16; + +typedef int __int32; +typedef unsigned int __uint32; + +typedef long long __int64; +typedef unsigned long long __uint64; + +#if defined(_WIN64) + +typedef __uint32 __ptr32; +typedef void *__ptr64; + +#else /* FIXME: defined(_WIN32) */ + +typedef void *__ptr32; +typedef __uint64 __ptr64; + +#endif + +/* Always signed and 32 bit wide */ + +typedef __int32 LONG32; +//typedef __int32 INT32; + +typedef LONG32 *PLONG32; +//typedef INT32 *PINT32; + +/* Always unsigned and 32 bit wide */ + +typedef __uint32 ULONG32; +typedef __uint32 DWORD32; +typedef __uint32 UINT32; + +typedef ULONG32 *PULONG32; +typedef DWORD32 *PDWORD32; +typedef UINT32 *PUINT32; + +/* Always signed and 64 bit wide */ + +typedef __int64 LONG64; +typedef __int64 INT64; + +typedef LONG64 *PLONG64; +typedef INT64 *PINT64; + +/* Always unsigned and 64 bit wide */ + +typedef __uint64 ULONG64; +typedef __uint64 DWORD64; +typedef __uint64 UINT64; + +typedef ULONG64 *PULONG64; +typedef DWORD64 *PDWORD64; +typedef UINT64 *PUINT64; + +/* Win32 or Win64 dependent typedef/defines. */ + +#ifdef _WIN64 + +typedef __int64 INT_PTR, *PINT_PTR; +typedef __uint64 UINT_PTR, *PUINT_PTR; + +#define MAXINT_PTR 0x7fffffffffffffff +#define MININT_PTR 0x8000000000000000 +#define MAXUINT_PTR 0xffffffffffffffff + +typedef __int32 HALF_PTR, *PHALF_PTR; +typedef __int32 UHALF_PTR, *PUHALF_PTR; + +#define MAXHALF_PTR 0x7fffffff +#define MINHALF_PTR 0x80000000 +#define MAXUHALF_PTR 0xffffffff + +typedef __int64 LONG_PTR, *PLONG_PTR; +typedef __uint64 ULONG_PTR, *PULONG_PTR; +typedef __uint64 DWORD_PTR, *PDWORD_PTR; + +#else /* FIXME: defined(_WIN32) */ + +typedef __int32 INT_PTR, *PINT_PTR; +typedef __uint32 UINT_PTR, *PUINT_PTR; + +#define MAXINT_PTR 0x7fffffff +#define MININT_PTR 0x80000000 +#define MAXUINT_PTR 0xffffffff + +typedef __int16 HALF_PTR, *PHALF_PTR; +typedef __uint16 UHALF_PTR, *PUHALF_PTR; + +#define MAXUHALF_PTR 0xffff +#define MAXHALF_PTR 0x7fff +#define MINHALF_PTR 0x8000 + +typedef __int32 LONG_PTR, *PLONG_PTR; +typedef __uint32 ULONG_PTR, *PULONG_PTR; +typedef __uint32 DWORD_PTR, *PDWORD_PTR; + +#endif /* defined(_WIN64) || defined(_WIN32) */ + +typedef INT_PTR SSIZE_T, *PSSIZE_T; +typedef UINT_PTR SIZE_T, *PSIZE_T; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* !defined(__WINE_BASETSD_H) */ + + + diff --git a/linphone/win32acm/wine/debugtools.h b/linphone/win32acm/wine/debugtools.h new file mode 100644 index 000000000..ce2448db8 --- /dev/null +++ b/linphone/win32acm/wine/debugtools.h @@ -0,0 +1,93 @@ + +#ifndef __WINE_DEBUGTOOLS_H +#define __WINE_DEBUGTOOLS_H + +#ifdef __WINE__ /* Debugging interface is internal to Wine */ + +#include +#include "config.h" +#include "windef.h" + +struct _GUID; + +/* Internal definitions (do not use these directly) */ + +enum __DEBUG_CLASS { __DBCL_FIXME, __DBCL_ERR, __DBCL_WARN, __DBCL_TRACE, __DBCL_COUNT }; + +#ifndef NO_TRACE_MSGS +# define __GET_DEBUGGING_trace(dbch) ((dbch)[0] & (1 << __DBCL_TRACE)) +#else +# define __GET_DEBUGGING_trace(dbch) 0 +#endif + +#ifndef NO_DEBUG_MSGS +# define __GET_DEBUGGING_warn(dbch) ((dbch)[0] & (1 << __DBCL_WARN)) +# define __GET_DEBUGGING_fixme(dbch) ((dbch)[0] & (1 << __DBCL_FIXME)) +#else +# define __GET_DEBUGGING_warn(dbch) 0 +# define __GET_DEBUGGING_fixme(dbch) 0 +#endif + +/* define error macro regardless of what is configured */ +#define __GET_DEBUGGING_err(dbch) ((dbch)[0] & (1 << __DBCL_ERR)) + +#define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING_##dbcl(dbch) +#define __SET_DEBUGGING(dbcl,dbch,on) \ + ((on) ? ((dbch)[0] |= 1 << (dbcl)) : ((dbch)[0] &= ~(1 << (dbcl)))) + +#ifndef __GNUC__ +#define __FUNCTION__ "" +#endif + +#define __DPRINTF(dbcl,dbch) \ + (!__GET_DEBUGGING(dbcl,(dbch)) || (dbg_header_##dbcl((dbch),__FUNCTION__),0)) ? \ + (void)0 : (void)dbg_printf + +/* Exported definitions and macros */ + +/* These function return a printable version of a string, including + quotes. The string will be valid for some time, but not indefinitely + as strings are re-used. */ +extern LPCSTR debugstr_an (LPCSTR s, int n); +extern LPCSTR debugstr_wn (LPCWSTR s, int n); +extern LPCSTR debugres_a (LPCSTR res); +extern LPCSTR debugres_w (LPCWSTR res); +extern LPCSTR debugstr_guid( const struct _GUID *id ); +extern LPCSTR debugstr_hex_dump (const void *ptr, int len); +extern int dbg_header_err( const char *dbg_channel, const char *func ); +extern int dbg_header_warn( const char *dbg_channel, const char *func ); +extern int dbg_header_fixme( const char *dbg_channel, const char *func ); +extern int dbg_header_trace( const char *dbg_channel, const char *func ); +extern int dbg_vprintf( const char *format, va_list args ); + +static inline LPCSTR debugstr_a( LPCSTR s ) { return debugstr_an( s, 80 ); } +static inline LPCSTR debugstr_w( LPCWSTR s ) { return debugstr_wn( s, 80 ); } + +#ifdef __GNUC__ +extern int dbg_printf(const char *format, ...) __attribute__((format (printf,1,2))); +#else +extern int dbg_printf(const char *format, ...); +#endif + +#define TRACE_(X) TRACE +#define WARN_(X) TRACE +#define WARN TRACE +#define ERR_(X) printf +#define ERR printf +#define FIXME_(X) TRACE +#define FIXME TRACE + +#define TRACE_ON(X) 1 +#define ERR_ON(X) 1 + +#define DECLARE_DEBUG_CHANNEL(ch) \ + extern char dbch_##ch[]; +#define DEFAULT_DEBUG_CHANNEL(ch) \ + extern char dbch_##ch[]; static char * const __dbch_default = dbch_##ch; + +#define DPRINTF dbg_printf +#define MESSAGE dbg_printf + +#endif /* __WINE__ */ + +#endif /* __WINE_DEBUGTOOLS_H */ diff --git a/linphone/win32acm/wine/driver.h b/linphone/win32acm/wine/driver.h new file mode 100644 index 000000000..dc8661aa3 --- /dev/null +++ b/linphone/win32acm/wine/driver.h @@ -0,0 +1,112 @@ +/* + * Drivers definitions + */ + +#ifndef __WINE_DRIVER_H +#define __WINE_DRIVER_H + +#include "windef.h" + +#define MMSYSERR_BASE 0 + +#define MMSYSERR_NOERROR 0 /* no error */ +#define MMSYSERR_ERROR (MMSYSERR_BASE + 1) /* unspecified error */ +#define MMSYSERR_BADDEVICEID (MMSYSERR_BASE + 2) /* device ID out of range */ +#define MMSYSERR_NOTENABLED (MMSYSERR_BASE + 3) /* driver failed enable */ +#define MMSYSERR_ALLOCATED (MMSYSERR_BASE + 4) /* device already allocated */ +#define MMSYSERR_INVALHANDLE (MMSYSERR_BASE + 5) /* device handle is invalid */ +#define MMSYSERR_NODRIVER (MMSYSERR_BASE + 6) /* no device driver present */ +#define MMSYSERR_NOMEM (MMSYSERR_BASE + 7) /* memory allocation error */ +#define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8) /* function isn't supported */ +#define MMSYSERR_BADERRNUM (MMSYSERR_BASE + 9) /* error value out of range */ +#define MMSYSERR_INVALFLAG (MMSYSERR_BASE + 10) /* invalid flag passed */ +#define MMSYSERR_INVALPARAM (MMSYSERR_BASE + 11) /* invalid parameter passed */ +#define MMSYSERR_LASTERROR (MMSYSERR_BASE + 11) /* last error in range */ + +#define DRV_LOAD 0x0001 +#define DRV_ENABLE 0x0002 +#define DRV_OPEN 0x0003 +#define DRV_CLOSE 0x0004 +#define DRV_DISABLE 0x0005 +#define DRV_FREE 0x0006 +#define DRV_CONFIGURE 0x0007 +#define DRV_QUERYCONFIGURE 0x0008 +#define DRV_INSTALL 0x0009 +#define DRV_REMOVE 0x000A +#define DRV_EXITSESSION 0x000B +#define DRV_EXITAPPLICATION 0x000C +#define DRV_POWER 0x000F + +#define DRV_RESERVED 0x0800 +#define DRV_USER 0x4000 + +#define DRVCNF_CANCEL 0x0000 +#define DRVCNF_OK 0x0001 +#define DRVCNF_RESTART 0x0002 + +#define DRVEA_NORMALEXIT 0x0001 +#define DRVEA_ABNORMALEXIT 0x0002 + +#define DRV_SUCCESS 0x0001 +#define DRV_FAILURE 0x0000 + +#define GND_FIRSTINSTANCEONLY 0x00000001 + +#define GND_FORWARD 0x00000000 +#define GND_REVERSE 0x00000002 + +typedef struct { + DWORD dwDCISize; + LPCSTR lpszDCISectionName; + LPCSTR lpszDCIAliasName; +} DRVCONFIGINFO16, *LPDRVCONFIGINFO16; + +typedef struct { + DWORD dwDCISize; + LPCWSTR lpszDCISectionName; + LPCWSTR lpszDCIAliasName; +} DRVCONFIGINFO, *LPDRVCONFIGINFO; + + +/* GetDriverInfo16 references this structure, so this a struct defined + * in the Win16 API. + * GetDriverInfo has been deprecated in Win32. + */ +typedef struct +{ + UINT16 length; + HDRVR16 hDriver; + HINSTANCE16 hModule; + CHAR szAliasName[128]; +} DRIVERINFOSTRUCT16, *LPDRIVERINFOSTRUCT16; + +LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, + LPARAM dwParam1, LPARAM dwParam2); +LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hdrvr, + UINT Msg, LPARAM lParam1, LPARAM lParam2); +HDRVR16 WINAPI OpenDriver16(LPCSTR szDriverName, LPCSTR szSectionName, + LPARAM lParam2); +HDRVR WINAPI OpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, + LPARAM lParam2); +HDRVR WINAPI OpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName, + LPARAM lParam2); +#define OpenDriver WINELIB_NAME_AW(OpenDriver) +LRESULT WINAPI CloseDriver16(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2); +LRESULT WINAPI CloseDriver(HDRVR hDriver, LPARAM lParam1, LPARAM lParam2); +LRESULT WINAPI SendDriverMessage16( HDRVR16 hDriver, UINT16 message, + LPARAM lParam1, LPARAM lParam2 ); +LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message, + LPARAM lParam1, LPARAM lParam2 ); +HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDriver); +HMODULE WINAPI GetDriverModuleHandle(HDRVR hDriver); + +DWORD WINAPI GetDriverFlags( HDRVR hDriver ); +#ifdef __WINE__ +/* this call (GetDriverFlags) is not documented, nor the flags returned. + * here are Wine only definitions + */ +#define WINE_GDF_EXIST 0x80000000 +#define WINE_GDF_16BIT 0x10000000 +#endif + +#endif /* __WINE_DRIVER_H */ diff --git a/linphone/win32acm/wine/elfdll.h b/linphone/win32acm/wine/elfdll.h new file mode 100644 index 000000000..1f356856f --- /dev/null +++ b/linphone/win32acm/wine/elfdll.h @@ -0,0 +1,14 @@ +#ifndef __WINE_ELFDLL_H +#define __WINE_ELFDLL_H + +#include "module.h" +#include "windef.h" + +WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR libname, DWORD flags); +HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname); +void ELFDLL_UnloadLibrary(WINE_MODREF *wm); + +void *ELFDLL_dlopen(const char *libname, int flags); +extern char *extra_ld_library_path; + +#endif diff --git a/linphone/win32acm/wine/heap.h b/linphone/win32acm/wine/heap.h new file mode 100644 index 000000000..bd0604b75 --- /dev/null +++ b/linphone/win32acm/wine/heap.h @@ -0,0 +1,56 @@ +/* + * Win32 heap definitions + * + * Copyright 1996 Alexandre Julliard + */ + +#ifndef __WINE_HEAP_H +#define __WINE_HEAP_H + +#include "config.h" + +#include "winbase.h" + +extern HANDLE SystemHeap; +extern HANDLE SegptrHeap; + +extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr ); +extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr ); +extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str ); +extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str ); +extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str ); +extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str ); + +/* SEGPTR helper macros */ + +#define SEGPTR_ALLOC(size) \ + (HeapAlloc( SegptrHeap, 0, (size) )) +#define SEGPTR_NEW(type) \ + ((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) )) +#define SEGPTR_STRDUP(str) \ + (HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) +#define SEGPTR_STRDUP_WtoA(str) \ + (HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) + /* define an inline function, a macro won't do */ +static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) { + return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr); +} +#define SEGPTR_GET(ptr) SEGPTR_Get(ptr) +#define SEGPTR_FREE(ptr) \ + (HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0) + +/* system heap private data */ +/* you must lock the system heap before using this structure */ +typedef struct +{ + void *gdi; /* GDI heap */ + void *user; /* USER handle table */ + void *cursor; /* cursor information */ + void *queue; /* message queues descriptor */ + void *win; /* windows descriptor */ + void *root; /* X11 root window */ +} SYSTEM_HEAP_DESCR; + +extern SYSTEM_HEAP_DESCR *SystemHeapDescr; + +#endif /* __WINE_HEAP_H */ diff --git a/linphone/win32acm/wine/ldt.h b/linphone/win32acm/wine/ldt.h new file mode 100644 index 000000000..f87ecc14e --- /dev/null +++ b/linphone/win32acm/wine/ldt.h @@ -0,0 +1,98 @@ +/* + * LDT copy + * + * Copyright 1995 Alexandre Julliard + */ + +#ifndef __WINE_LDT_H +#define __WINE_LDT_H + +#include "windef.h" +enum seg_type +{ + SEGMENT_DATA = 0, + SEGMENT_STACK = 1, + SEGMENT_CODE = 2 +}; + + /* This structure represents a real LDT entry. */ + /* It is used by get_ldt_entry() and set_ldt_entry(). */ +typedef struct +{ + unsigned long base; /* base address */ + unsigned long limit; /* segment limit (in pages or bytes) */ + int seg_32bit; /* is segment 32-bit? */ + int read_only; /* is segment read-only? */ + int limit_in_pages; /* is the limit in pages or bytes? */ + enum seg_type type; /* segment type */ +} ldt_entry; +#ifdef __cplusplus +extern "C" +{ +#endif +extern void LDT_BytesToEntry( const unsigned long *buffer, ldt_entry *content); +extern void LDT_EntryToBytes( unsigned long *buffer, const ldt_entry *content); +extern int LDT_GetEntry( int entry, ldt_entry *content ); +extern int LDT_SetEntry( int entry, const ldt_entry *content ); +extern void LDT_Print( int start, int length ); + + + /* This structure is used to build the local copy of the LDT. */ +typedef struct +{ + unsigned long base; /* base address or 0 if entry is free */ + unsigned long limit; /* limit in bytes or 0 if entry is free */ +} ldt_copy_entry; + +#define LDT_SIZE 8192 + +extern ldt_copy_entry ldt_copy[LDT_SIZE]; + +#define __AHSHIFT 3 /* don't change! */ +#define __AHINCR (1 << __AHSHIFT) + +#define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT) +#define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0) +#define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED)) +#define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel))) +#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base) +#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit) + +/* Convert a segmented ptr (16:16) to a linear (32) pointer */ + +#define PTR_SEG_OFF_TO_LIN(seg,off) \ + ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off))) +#define PTR_SEG_TO_LIN(ptr) \ + PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr)) +#define PTR_SEG_OFF_TO_SEGPTR(seg,off) \ + ((SEGPTR)MAKELONG(off,seg)) +#define PTR_SEG_OFF_TO_HUGEPTR(seg,off) \ + PTR_SEG_OFF_TO_SEGPTR( (seg) + (HIWORD(off) << __AHSHIFT), LOWORD(off) ) + +#define W32S_APPLICATION() (PROCESS_Current()->flags & PDB32_WIN32S_PROC) +#define W32S_OFFSET 0x10000 +#define W32S_APP2WINE(addr, offset) ((addr)? (DWORD)(addr) + (DWORD)(offset) : 0) +#define W32S_WINE2APP(addr, offset) ((addr)? (DWORD)(addr) - (DWORD)(offset) : 0) + +extern unsigned char ldt_flags_copy[LDT_SIZE]; + +#define LDT_FLAGS_TYPE 0x03 /* Mask for segment type */ +#define LDT_FLAGS_READONLY 0x04 /* Segment is read-only (data) */ +#define LDT_FLAGS_EXECONLY 0x04 /* Segment is execute-only (code) */ +#define LDT_FLAGS_32BIT 0x08 /* Segment is 32-bit (code or stack) */ +#define LDT_FLAGS_BIG 0x10 /* Segment is big (limit is in pages) */ +#define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */ + +#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)]) + +#define FIRST_LDT_ENTRY_TO_ALLOC 17 + +/* Determine if sel is a system selector (i.e. not managed by Wine) */ +#define IS_SELECTOR_SYSTEM(sel) \ + (!((sel) & 4) || (SELECTOR_TO_ENTRY(sel) < FIRST_LDT_ENTRY_TO_ALLOC)) +#define IS_SELECTOR_32BIT(sel) \ + (IS_SELECTOR_SYSTEM(sel) || (GET_SEL_FLAGS(sel) & LDT_FLAGS_32BIT)) +#ifdef __cplusplus +} +#endif +#endif /* __WINE_LDT_H */ diff --git a/linphone/win32acm/wine/mmreg.h b/linphone/win32acm/wine/mmreg.h new file mode 100644 index 000000000..e59ae0a47 --- /dev/null +++ b/linphone/win32acm/wine/mmreg.h @@ -0,0 +1,242 @@ +/* + * mmreg.h - Declarations for ??? + */ + +#ifndef __WINE_MMREG_H +#define __WINE_MMREG_H + +/*********************************************************************** + * Defines/Enums + */ + +#ifndef _ACM_WAVEFILTER +#define _ACM_WAVEFILTER + +#include "windef.h" + +#define WAVE_FILTER_UNKNOWN 0x0000 +#define WAVE_FILTER_DEVELOPMENT 0xFFFF + +typedef struct __attribute__((__packed__)) _WAVEFILTER { + DWORD cbStruct; + DWORD dwFilterTag; + DWORD fdwFilter; + DWORD dwReserved[5]; +} WAVEFILTER, *PWAVEFILTER, *NPWAVEFILTER, *LPWAVEFILTER; +#endif /* _ACM_WAVEFILTER */ + +#ifndef WAVE_FILTER_VOLUME +#define WAVE_FILTER_VOLUME 0x0001 + +typedef struct __attribute__((__packed__)) _WAVEFILTER_VOLUME { + WAVEFILTER wfltr; + DWORD dwVolume; +} VOLUMEWAVEFILTER, *PVOLUMEWAVEFILTER, *NPVOLUMEWAVEFILTER, *LPVOLUMEWAVEFILTER; +#endif /* WAVE_FILTER_VOLUME */ + +#ifndef WAVE_FILTER_ECHO +#define WAVE_FILTER_ECHO 0x0002 + +typedef struct __attribute__((__packed__)) WAVEFILTER_ECHO { + WAVEFILTER wfltr; + DWORD dwVolume; + DWORD dwDelay; +} ECHOWAVEFILTER, *PECHOWAVEFILTER, *NPECHOWAVEFILTER, *LPECHOWAVEFILTER; +#endif /* WAVEFILTER_ECHO */ + +#ifndef _WAVEFORMATEX_ +#define _WAVEFORMATEX_ +typedef struct __attribute__((__packed__)) _WAVEFORMATEX { + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +} WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX; +#endif /* _WAVEFORMATEX_ */ + +#ifndef GUID_TYPE +#define GUID_TYPE +typedef struct +{ + unsigned long f1; + unsigned short f2; + unsigned short f3; + unsigned char f4[8]; +} GUID; +#endif + +#ifndef _WAVEFORMATEXTENSIBLE_ +#define _WAVEFORMATEXTENSIBLE_ +typedef struct { + WAVEFORMATEX Format; + union { + WORD wValidBitsPerSample; /* bits of precision */ + WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */ + WORD wReserved; /* If neither applies, set to zero. */ + } Samples; + DWORD dwChannelMask; /* which channels are */ + /* present in stream */ + GUID SubFormat; +} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; +#endif // !_WAVEFORMATEXTENSIBLE_ + +typedef struct mpeglayer3waveformat_tag { + WORD wFormatTag WINE_PACKED; + WORD nChannels WINE_PACKED; + DWORD nSamplesPerSec WINE_PACKED; + DWORD nAvgBytesPerSec WINE_PACKED; + WORD nBlockAlign WINE_PACKED; + WORD wBitsPerSample WINE_PACKED; + WORD cbSize WINE_PACKED; + WORD wID WINE_PACKED; + DWORD fdwFlags WINE_PACKED; + WORD nBlockSize WINE_PACKED; + WORD nFramesPerBlock WINE_PACKED; + WORD nCodecDelay WINE_PACKED; +} MPEGLAYER3WAVEFORMAT; + +/* WAVE form wFormatTag IDs */ + +#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */ +#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */ +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 /* Microsoft Corporation */ +#define WAVE_FORMAT_VSELP 0x0004 /* Compaq Computer Corp. */ +#define WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */ +#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */ +#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */ +#define WAVE_FORMAT_DTS 0x0008 /* Microsoft Corporation */ +#define WAVE_FORMAT_OKI_ADPCM 0x0010 /* OKI */ +#define WAVE_FORMAT_DVI_ADPCM 0x0011 /* Intel Corporation */ +#define WAVE_FORMAT_IMA_ADPCM (WAVE_FORMAT_DVI_ADPCM) /* Intel Corporation */ +#define WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 /* Videologic */ +#define WAVE_FORMAT_SIERRA_ADPCM 0x0013 /* Sierra Semiconductor Corp */ +#define WAVE_FORMAT_G723_ADPCM 0x0014 /* Antex Electronics Corporation */ +#define WAVE_FORMAT_DIGISTD 0x0015 /* DSP Solutions, Inc. */ +#define WAVE_FORMAT_DIGIFIX 0x0016 /* DSP Solutions, Inc. */ +#define WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 /* Dialogic Corporation */ +#define WAVE_FORMAT_MEDIAVISION_ADPCM 0x0018 /* Media Vision, Inc. */ +#define WAVE_FORMAT_CU_CODEC 0x0019 /* Hewlett-Packard Company */ +#define WAVE_FORMAT_YAMAHA_ADPCM 0x0020 /* Yamaha Corporation of America */ +#define WAVE_FORMAT_SONARC 0x0021 /* Speech Compression */ +#define WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 /* DSP Group, Inc */ +#define WAVE_FORMAT_ECHOSC1 0x0023 /* Echo Speech Corporation */ +#define WAVE_FORMAT_AUDIOFILE_AF36 0x0024 /* Virtual Music, Inc. */ +#define WAVE_FORMAT_APTX 0x0025 /* Audio Processing Technology */ +#define WAVE_FORMAT_AUDIOFILE_AF10 0x0026 /* Virtual Music, Inc. */ +#define WAVE_FORMAT_PROSODY_1612 0x0027 /* Aculab plc */ +#define WAVE_FORMAT_LRC 0x0028 /* Merging Technologies S.A. */ +#define WAVE_FORMAT_DOLBY_AC2 0x0030 /* Dolby Laboratories */ +#define WAVE_FORMAT_GSM610 0x0031 /* Microsoft Corporation */ +#define WAVE_FORMAT_MSNAUDIO 0x0032 /* Microsoft Corporation */ +#define WAVE_FORMAT_ANTEX_ADPCME 0x0033 /* Antex Electronics Corporation */ +#define WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 /* Control Resources Limited */ +#define WAVE_FORMAT_DIGIREAL 0x0035 /* DSP Solutions, Inc. */ +#define WAVE_FORMAT_DIGIADPCM 0x0036 /* DSP Solutions, Inc. */ +#define WAVE_FORMAT_CONTROL_RES_CR10 0x0037 /* Control Resources Limited */ +#define WAVE_FORMAT_NMS_VBXADPCM 0x0038 /* Natural MicroSystems */ +#define WAVE_FORMAT_CS_IMAADPCM 0x0039 /* Crystal Semiconductor IMA ADPCM */ +#define WAVE_FORMAT_ECHOSC3 0x003A /* Echo Speech Corporation */ +#define WAVE_FORMAT_ROCKWELL_ADPCM 0x003B /* Rockwell International */ +#define WAVE_FORMAT_ROCKWELL_DIGITALK 0x003C /* Rockwell International */ +#define WAVE_FORMAT_XEBEC 0x003D /* Xebec Multimedia Solutions Limited */ +#define WAVE_FORMAT_G721_ADPCM 0x0040 /* Antex Electronics Corporation */ +#define WAVE_FORMAT_G728_CELP 0x0041 /* Antex Electronics Corporation */ +#define WAVE_FORMAT_MSG723 0x0042 /* Microsoft Corporation */ +#define WAVE_FORMAT_MPEG 0x0050 /* Microsoft Corporation */ +#define WAVE_FORMAT_RT24 0x0052 /* InSoft, Inc. */ +#define WAVE_FORMAT_PAC 0x0053 /* InSoft, Inc. */ +#define WAVE_FORMAT_MPEGLAYER3 0x0055 /* ISO/MPEG Layer3 Format Tag */ +#define WAVE_FORMAT_LUCENT_G723 0x0059 /* Lucent Technologies */ +#define WAVE_FORMAT_CIRRUS 0x0060 /* Cirrus Logic */ +#define WAVE_FORMAT_ESPCM 0x0061 /* ESS Technology */ +#define WAVE_FORMAT_VOXWARE 0x0062 /* Voxware Inc */ +#define WAVE_FORMAT_CANOPUS_ATRAC 0x0063 /* Canopus, co., Ltd. */ +#define WAVE_FORMAT_G726_ADPCM 0x0064 /* APICOM */ +#define WAVE_FORMAT_G722_ADPCM 0x0065 /* APICOM */ +#define WAVE_FORMAT_DSAT_DISPLAY 0x0067 /* Microsoft Corporation */ +#define WAVE_FORMAT_VOXWARE_BYTE_ALIGNED 0x0069 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_AC8 0x0070 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_AC10 0x0071 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_AC16 0x0072 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_AC20 0x0073 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_RT24 0x0074 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_RT29 0x0075 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_RT29HW 0x0076 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_VR12 0x0077 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_VR18 0x0078 /* Voxware Inc */ +#define WAVE_FORMAT_VOXWARE_TQ40 0x0079 /* Voxware Inc */ +#define WAVE_FORMAT_SOFTSOUND 0x0080 /* Softsound, Ltd. */ +#define WAVE_FORMAT_VOXWARE_TQ60 0x0081 /* Voxware Inc */ +#define WAVE_FORMAT_MSRT24 0x0082 /* Microsoft Corporation */ +#define WAVE_FORMAT_G729A 0x0083 /* AT&T Labs, Inc. */ +#define WAVE_FORMAT_MVI_MVI2 0x0084 /* Motion Pixels */ +#define WAVE_FORMAT_DF_G726 0x0085 /* DataFusion Systems (Pty) (Ltd) */ +#define WAVE_FORMAT_DF_GSM610 0x0086 /* DataFusion Systems (Pty) (Ltd) */ +#define WAVE_FORMAT_ISIAUDIO 0x0088 /* Iterated Systems, Inc. */ +#define WAVE_FORMAT_ONLIVE 0x0089 /* OnLive! Technologies, Inc. */ +#define WAVE_FORMAT_SBC24 0x0091 /* Siemens Business Communications Sys */ +#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 /* Sonic Foundry */ +#define WAVE_FORMAT_MEDIASONIC_G723 0x0093 /* MediaSonic */ +#define WAVE_FORMAT_PROSODY_8KBPS 0x0094 /* Aculab plc */ +#define WAVE_FORMAT_ZYXEL_ADPCM 0x0097 /* ZyXEL Communications, Inc. */ +#define WAVE_FORMAT_PHILIPS_LPCBB 0x0098 /* Philips Speech Processing */ +#define WAVE_FORMAT_PACKED 0x0099 /* Studer Professional Audio AG */ +#define WAVE_FORMAT_MALDEN_PHONYTALK 0x00A0 /* Malden Electronics Ltd. */ +#define WAVE_FORMAT_RHETOREX_ADPCM 0x0100 /* Rhetorex Inc. */ +#define WAVE_FORMAT_IRAT 0x0101 /* BeCubed Software Inc. */ +#define WAVE_FORMAT_VIVO_G723 0x0111 /* Vivo Software */ +#define WAVE_FORMAT_VIVO_SIREN 0x0112 /* Vivo Software */ +#define WAVE_FORMAT_DIGITAL_G723 0x0123 /* Digital Equipment Corporation */ +#define WAVE_FORMAT_SANYO_LD_ADPCM 0x0125 /* Sanyo Electric Co., Ltd. */ +#define WAVE_FORMAT_SIPROLAB_ACEPLNET 0x0130 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_SIPROLAB_ACELP4800 0x0131 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_SIPROLAB_ACELP8V3 0x0132 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_SIPROLAB_G729 0x0133 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_SIPROLAB_G729A 0x0134 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_SIPROLAB_KELVIN 0x0135 /* Sipro Lab Telecom Inc. */ +#define WAVE_FORMAT_G726ADPCM 0x0140 /* Dictaphone Corporation */ +#define WAVE_FORMAT_QUALCOMM_PUREVOICE 0x0150 /* Qualcomm, Inc. */ +#define WAVE_FORMAT_QUALCOMM_HALFRATE 0x0151 /* Qualcomm, Inc. */ +#define WAVE_FORMAT_TUBGSM 0x0155 /* Ring Zero Systems, Inc. */ +#define WAVE_FORMAT_MSAUDIO1 0x0160 /* Microsoft Corporation */ +#define WAVE_FORMAT_CREATIVE_ADPCM 0x0200 /* Creative Labs, Inc */ +#define WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 /* Creative Labs, Inc */ +#define WAVE_FORMAT_CREATIVE_FASTSPEECH10 0x0203 /* Creative Labs, Inc */ +#define WAVE_FORMAT_UHER_ADPCM 0x0210 /* UHER informatic GmbH */ +#define WAVE_FORMAT_QUARTERDECK 0x0220 /* Quarterdeck Corporation */ +#define WAVE_FORMAT_ILINK_VC 0x0230 /* I-link Worldwide */ +#define WAVE_FORMAT_RAW_SPORT 0x0240 /* Aureal Semiconductor */ +#define WAVE_FORMAT_IPI_HSX 0x0250 /* Interactive Products, Inc. */ +#define WAVE_FORMAT_IPI_RPELP 0x0251 /* Interactive Products, Inc. */ +#define WAVE_FORMAT_CS2 0x0260 /* Consistent Software */ +#define WAVE_FORMAT_SONY_SCX 0x0270 /* Sony Corp. */ +#define WAVE_FORMAT_FM_TOWNS_SND 0x0300 /* Fujitsu Corp. */ +#define WAVE_FORMAT_BTV_DIGITAL 0x0400 /* Brooktree Corporation */ +#define WAVE_FORMAT_QDESIGN_MUSIC 0x0450 /* QDesign Corporation */ +#define WAVE_FORMAT_VME_VMPCM 0x0680 /* AT&T Labs, Inc. */ +#define WAVE_FORMAT_TPC 0x0681 /* AT&T Labs, Inc. */ +#define WAVE_FORMAT_OLIGSM 0x1000 /* Ing C. Olivetti & C., S.p.A. */ +#define WAVE_FORMAT_OLIADPCM 0x1001 /* Ing C. Olivetti & C., S.p.A. */ +#define WAVE_FORMAT_OLICELP 0x1002 /* Ing C. Olivetti & C., S.p.A. */ +#define WAVE_FORMAT_OLISBC 0x1003 /* Ing C. Olivetti & C., S.p.A. */ +#define WAVE_FORMAT_OLIOPR 0x1004 /* Ing C. Olivetti & C., S.p.A. */ +#define WAVE_FORMAT_LH_CODEC 0x1100 /* Lernout & Hauspie */ +#define WAVE_FORMAT_NORRIS 0x1400 /* Norris Communications, Inc. */ +#define WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS 0x1500 /* AT&T Labs, Inc. */ +#define WAVE_FORMAT_DVM 0x2000 /* FAST Multimedia AG */ + +#if !defined(WAVE_FORMAT_EXTENSIBLE) +#define WAVE_FORMAT_EXTENSIBLE 0xFFFE /* Microsoft */ +#endif // !defined(WAVE_FORMAT_EXTENSIBLE) +// +// the WAVE_FORMAT_DEVELOPMENT format tag can be used during the +// development phase of a new wave format. Before shipping, you MUST +// acquire an official format tag from Microsoft. +// +#define WAVE_FORMAT_DEVELOPMENT (0xFFFF) + + +#endif /* __WINE_MMREG_H */ diff --git a/linphone/win32acm/wine/module.h b/linphone/win32acm/wine/module.h new file mode 100644 index 000000000..6f6b31a0a --- /dev/null +++ b/linphone/win32acm/wine/module.h @@ -0,0 +1,149 @@ +/* + * Module definitions + * + * Copyright 1995 Alexandre Julliard + */ + +#ifndef __WINE_MODULE_H +#define __WINE_MODULE_H + +#include "windef.h" +#include "pe_image.h" + + +typedef struct { + BYTE type; + BYTE flags; + BYTE segnum; + WORD offs WINE_PACKED; +} ET_ENTRY; + +typedef struct { + WORD first; /* ordinal */ + WORD last; /* ordinal */ + WORD next; /* bundle */ +} ET_BUNDLE; + + + /* In-memory segment table */ +typedef struct +{ + WORD filepos; /* Position in file, in sectors */ + WORD size; /* Segment size on disk */ + WORD flags; /* Segment flags */ + WORD minsize; /* Min. size of segment in memory */ + HANDLE16 hSeg; /* Selector or handle (selector - 1) */ + /* of segment in memory */ +} SEGTABLEENTRY; + + + /* Self-loading modules contain this structure in their first segment */ + +#include "pshpack1.h" + +typedef struct +{ + WORD version; /* Must be "A0" (0x3041) */ + WORD reserved; + FARPROC16 BootApp; /* startup procedure */ + FARPROC16 LoadAppSeg; /* procedure to load a segment */ + FARPROC16 reserved2; + FARPROC16 MyAlloc; /* memory allocation procedure, + * wine must write this field */ + FARPROC16 EntryAddrProc; + FARPROC16 ExitProc; /* exit procedure */ + WORD reserved3[4]; + FARPROC16 SetOwner; /* Set Owner procedure, exported by wine */ +} SELFLOADHEADER; + + /* Parameters for LoadModule() */ +typedef struct +{ + HGLOBAL16 hEnvironment; /* Environment segment */ + SEGPTR cmdLine WINE_PACKED; /* Command-line */ + SEGPTR showCmd WINE_PACKED; /* Code for ShowWindow() */ + SEGPTR reserved WINE_PACKED; +} LOADPARAMS16; + +typedef struct +{ + LPSTR lpEnvAddress; + LPSTR lpCmdLine; + UINT16 *lpCmdShow; + DWORD dwReserved; +} LOADPARAMS; + +#include "poppack.h" + +/* internal representation of 32bit modules. per process. */ +typedef enum { + MODULE32_PE = 1, + MODULE32_ELF, + MODULE32_ELFDLL +} MODULE32_TYPE; + +typedef struct _wine_modref +{ + struct _wine_modref *next; + struct _wine_modref *prev; + MODULE32_TYPE type; + union { + PE_MODREF pe; + ELF_MODREF elf; + } binfmt; + + HMODULE module; + + int nDeps; + struct _wine_modref **deps; + + int flags; + int refCount; + + char *filename; + char *modname; + char *short_filename; + char *short_modname; +} WINE_MODREF; + +#define WINE_MODREF_INTERNAL 0x00000001 +#define WINE_MODREF_NO_DLL_CALLS 0x00000002 +#define WINE_MODREF_PROCESS_ATTACHED 0x00000004 +#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010 +#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020 +#define WINE_MODREF_MARKER 0x80000000 + + + +/* Resource types */ +typedef struct resource_typeinfo_s NE_TYPEINFO; +typedef struct resource_nameinfo_s NE_NAMEINFO; + +#define NE_SEG_TABLE(pModule) \ + ((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->seg_table)) + +#define NE_MODULE_TABLE(pModule) \ + ((WORD *)((char *)(pModule) + (pModule)->modref_table)) + +#define NE_MODULE_NAME(pModule) \ + (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName) + +struct modref_list_t; + +typedef struct modref_list_t +{ + WINE_MODREF* wm; + struct modref_list_t *next; + struct modref_list_t *prev; +} modref_list; + + +/* module.c */ +extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, WIN_BOOL snoop ); +extern WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hModule ); +extern WINE_MODREF *MODULE_FindModule( LPCSTR path ); + +/* resource.c */ +extern INT WINAPI AccessResource(HMODULE,HRSRC); + +#endif /* __WINE_MODULE_H */ diff --git a/linphone/win32acm/wine/msacm.h b/linphone/win32acm/wine/msacm.h new file mode 100644 index 000000000..10e87e61a --- /dev/null +++ b/linphone/win32acm/wine/msacm.h @@ -0,0 +1,943 @@ +/* + * msacm.h - Declarations for MSACM + */ + +#ifndef __WINE_MSACM_H +#define __WINE_MSACM_H + +#include "windef.h" +#include "driver.h" +#include "mmreg.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +//typedef WORD VERSION; /* major (high byte), minor (low byte) */ + +typedef UINT16 MMVERSION16; +typedef UINT MMVERSION; +typedef UINT16 MCIDEVICEID16; +typedef UINT MCIDEVICEID; +typedef UINT16 MMRESULT16; +typedef UINT MMRESULT; +typedef DWORD FOURCC; /* a four character code */ + + + +#if !defined(WAVE_FORMAT_PCM) +#define WAVE_FORMAT_PCM 1 +#endif + +/*********************************************************************** + * Defines/Enums + */ + +#define ACMERR_BASE 512 +#define ACMERR_NOTPOSSIBLE (ACMERR_BASE + 0) +#define ACMERR_BUSY (ACMERR_BASE + 1) +#define ACMERR_UNPREPARED (ACMERR_BASE + 2) +#define ACMERR_CANCELED (ACMERR_BASE + 3) + +#define MM_ACM_OPEN MM_STREAM_OPEN +#define MM_ACM_CLOSE MM_STREAM_CLOSE +#define MM_ACM_DONE MM_STREAM_DONE + +#define ACM_DRIVERADDF_FUNCTION 0x00000003L +#define ACM_DRIVERADDF_NOTIFYHWND 0x00000004L +#define ACM_DRIVERADDF_TYPEMASK 0x00000007L +#define ACM_DRIVERADDF_LOCAL 0x00000000L +#define ACM_DRIVERADDF_GLOBAL 0x00000008L + +#define ACMDRIVERDETAILS_SHORTNAME_CHARS 32 +#define ACMDRIVERDETAILS_LONGNAME_CHARS 128 +#define ACMDRIVERDETAILS_COPYRIGHT_CHARS 80 +#define ACMDRIVERDETAILS_LICENSING_CHARS 128 +#define ACMDRIVERDETAILS_FEATURES_CHARS 512 + +#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC mmioFOURCC('a', 'u', 'd', 'c') +#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED mmioFOURCC('\0', '\0', '\0', '\0') + +#define ACMDRIVERDETAILS_SUPPORTF_CODEC 0x00000001L +#define ACMDRIVERDETAILS_SUPPORTF_CONVERTER 0x00000002L +#define ACMDRIVERDETAILS_SUPPORTF_FILTER 0x00000004L +#define ACMDRIVERDETAILS_SUPPORTF_HARDWARE 0x00000008L +#define ACMDRIVERDETAILS_SUPPORTF_ASYNC 0x00000010L +#define ACMDRIVERDETAILS_SUPPORTF_LOCAL 0x40000000L +#define ACMDRIVERDETAILS_SUPPORTF_DISABLED 0x80000000L + +#define ACM_DRIVERENUMF_NOLOCAL 0x40000000L +#define ACM_DRIVERENUMF_DISABLED 0x80000000L + +#define ACM_DRIVERPRIORITYF_ENABLE 0x00000001L +#define ACM_DRIVERPRIORITYF_DISABLE 0x00000002L +#define ACM_DRIVERPRIORITYF_ABLEMASK 0x00000003L +#define ACM_DRIVERPRIORITYF_BEGIN 0x00010000L +#define ACM_DRIVERPRIORITYF_END 0x00020000L +#define ACM_DRIVERPRIORITYF_DEFERMASK 0x00030000L + +#define MM_ACM_FILTERCHOOSE 0x8000 + +#define FILTERCHOOSE_MESSAGE 0 +#define FILTERCHOOSE_FILTERTAG_VERIFY (FILTERCHOOSE_MESSAGE+0) +#define FILTERCHOOSE_FILTER_VERIFY (FILTERCHOOSE_MESSAGE+1) +#define FILTERCHOOSE_CUSTOM_VERIFY (FILTERCHOOSE_MESSAGE+2) + +#define ACMFILTERCHOOSE_STYLEF_SHOWHELP 0x00000004L +#define ACMFILTERCHOOSE_STYLEF_ENABLEHOOK 0x00000008L +#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L +#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L +#define ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT 0x00000040L +#define ACMFILTERCHOOSE_STYLEF_CONTEXTHELP 0x00000080L + +#define ACMFILTERDETAILS_FILTER_CHARS 128 + +#define ACM_FILTERDETAILSF_INDEX 0x00000000L +#define ACM_FILTERDETAILSF_FILTER 0x00000001L +#define ACM_FILTERDETAILSF_QUERYMASK 0x0000000FL + +#define ACMFILTERTAGDETAILS_FILTERTAG_CHARS 48 + +#define ACM_FILTERTAGDETAILSF_INDEX 0x00000000L +#define ACM_FILTERTAGDETAILSF_FILTERTAG 0x00000001L +#define ACM_FILTERTAGDETAILSF_LARGESTSIZE 0x00000002L +#define ACM_FILTERTAGDETAILSF_QUERYMASK 0x0000000FL + +#define ACM_FILTERENUMF_DWFILTERTAG 0x00010000L + +#define ACMHELPMSGSTRINGA "acmchoose_help" +#define ACMHELPMSGSTRINGW L"acmchoose_help" +#define ACMHELPMSGSTRING16 "acmchoose_help" + +#define ACMHELPMSGCONTEXTMENUA "acmchoose_contextmenu" +#define ACMHELPMSGCONTEXTMENUW L"acmchoose_contextmenu" +#define ACMHELPMSGCONTEXTMENU16 "acmchoose_contextmenu" + +#define ACMHELPMSGCONTEXTHELPA "acmchoose_contexthelp" +#define ACMHELPMSGCONTEXTHELPW L"acmchoose_contexthelp" +#define ACMHELPMSGCONTEXTHELP16 "acmchoose_contexthelp" + +#define MM_ACM_FORMATCHOOSE 0x8000 + +#define FORMATCHOOSE_MESSAGE 0 +#define FORMATCHOOSE_FORMATTAG_VERIFY (FORMATCHOOSE_MESSAGE+0) +#define FORMATCHOOSE_FORMAT_VERIFY (FORMATCHOOSE_MESSAGE+1) +#define FORMATCHOOSE_CUSTOM_VERIFY (FORMATCHOOSE_MESSAGE+2) + +#define ACMFORMATCHOOSE_STYLEF_SHOWHELP 0x00000004L +#define ACMFORMATCHOOSE_STYLEF_ENABLEHOOK 0x00000008L +#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L +#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L +#define ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT 0x00000040L +#define ACMFORMATCHOOSE_STYLEF_CONTEXTHELP 0x00000080L + +#define ACMFORMATDETAILS_FORMAT_CHARS 128 + +#define ACM_FORMATDETAILSF_INDEX 0x00000000L +#define ACM_FORMATDETAILSF_FORMAT 0x00000001L +#define ACM_FORMATDETAILSF_QUERYMASK 0x0000000FL + +#define ACM_FORMATENUMF_WFORMATTAG 0x00010000L +#define ACM_FORMATENUMF_NCHANNELS 0x00020000L +#define ACM_FORMATENUMF_NSAMPLESPERSEC 0x00040000L +#define ACM_FORMATENUMF_WBITSPERSAMPLE 0x00080000L +#define ACM_FORMATENUMF_CONVERT 0x00100000L +#define ACM_FORMATENUMF_SUGGEST 0x00200000L +#define ACM_FORMATENUMF_HARDWARE 0x00400000L +#define ACM_FORMATENUMF_INPUT 0x00800000L +#define ACM_FORMATENUMF_OUTPUT 0x01000000L + +#define ACM_FORMATSUGGESTF_WFORMATTAG 0x00010000L +#define ACM_FORMATSUGGESTF_NCHANNELS 0x00020000L +#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC 0x00040000L +#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE 0x00080000L +#define ACM_FORMATSUGGESTF_TYPEMASK 0x00FF0000L + +#define ACMFORMATTAGDETAILS_FORMATTAG_CHARS 48 + +#define ACM_FORMATTAGDETAILSF_INDEX 0x00000000L +#define ACM_FORMATTAGDETAILSF_FORMATTAG 0x00000001L +#define ACM_FORMATTAGDETAILSF_LARGESTSIZE 0x00000002L +#define ACM_FORMATTAGDETAILSF_QUERYMASK 0x0000000FL + +#define ACM_METRIC_COUNT_DRIVERS 1 +#define ACM_METRIC_COUNT_CODECS 2 +#define ACM_METRIC_COUNT_CONVERTERS 3 +#define ACM_METRIC_COUNT_FILTERS 4 +#define ACM_METRIC_COUNT_DISABLED 5 +#define ACM_METRIC_COUNT_HARDWARE 6 +#define ACM_METRIC_COUNT_LOCAL_DRIVERS 20 +#define ACM_METRIC_COUNT_LOCAL_CODECS 21 +#define ACM_METRIC_COUNT_LOCAL_CONVERTERS 22 +#define ACM_METRIC_COUNT_LOCAL_FILTERS 23 +#define ACM_METRIC_COUNT_LOCAL_DISABLED 24 +#define ACM_METRIC_HARDWARE_WAVE_INPUT 30 +#define ACM_METRIC_HARDWARE_WAVE_OUTPUT 31 +#define ACM_METRIC_MAX_SIZE_FORMAT 50 +#define ACM_METRIC_MAX_SIZE_FILTER 51 +#define ACM_METRIC_DRIVER_SUPPORT 100 +#define ACM_METRIC_DRIVER_PRIORITY 101 + +#define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004 +#define ACM_STREAMCONVERTF_START 0x00000010 +#define ACM_STREAMCONVERTF_END 0x00000020 + +#define ACMSTREAMHEADER_STATUSF_DONE 0x00010000L +#define ACMSTREAMHEADER_STATUSF_PREPARED 0x00020000L +#define ACMSTREAMHEADER_STATUSF_INQUEUE 0x00100000L + +#define ACM_STREAMOPENF_QUERY 0x00000001 +#define ACM_STREAMOPENF_ASYNC 0x00000002 +#define ACM_STREAMOPENF_NONREALTIME 0x00000004 + +#define ACM_STREAMSIZEF_SOURCE 0x00000000L +#define ACM_STREAMSIZEF_DESTINATION 0x00000001L +#define ACM_STREAMSIZEF_QUERYMASK 0x0000000FL + +#define ACMDM_USER (DRV_USER + 0x0000) +#define ACMDM_RESERVED_LOW (DRV_USER + 0x2000) +#define ACMDM_RESERVED_HIGH (DRV_USER + 0x2FFF) + +#define ACMDM_BASE ACMDM_RESERVED_LOW + +#define ACMDM_DRIVER_ABOUT (ACMDM_BASE + 11) + +/*********************************************************************** + * Callbacks + */ + +typedef WIN_BOOL CALLBACK ( *ACMDRIVERENUMCB)( + HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL16 CALLBACK ( *ACMDRIVERENUMCB16)( + HACMDRIVERID16 hadid, DWORD dwInstance, DWORD fdwSupport +); + +typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCA)( + HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam +); + +typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCW)( + HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam +); + +typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROC16)( + HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam +); + +typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCA)( + HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam +); + +typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCW)( + HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam +); + +typedef UINT16 CALLBACK ( *ACMFORMATCHOOSEHOOKPROC16)( + HWND16 hwnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam +); + +/*********************************************************************** + * Structures + */ + +typedef struct _ACMDRIVERDETAILSA +{ + DWORD cbStruct; + + FOURCC fccType; + FOURCC fccComp; + + WORD wMid; + WORD wPid; + + DWORD vdwACM; + DWORD vdwDriver; + + DWORD fdwSupport; + DWORD cFormatTags; + DWORD cFilterTags; + + HICON hicon; + + CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; + CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; + CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; + CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; + CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; +} ACMDRIVERDETAILSA, *PACMDRIVERDETAILSA; + +typedef struct _ACMDRIVERDETAILSW +{ + DWORD cbStruct; + + FOURCC fccType; + FOURCC fccComp; + + WORD wMid; + WORD wPid; + + DWORD vdwACM; + DWORD vdwDriver; + + DWORD fdwSupport; + DWORD cFormatTags; + DWORD cFilterTags; + + HICON hicon; + + WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; + WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; + WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; + WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; + WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; +} ACMDRIVERDETAILSW, *PACMDRIVERDETAILSW; + +typedef struct _ACMDRIVERDETAILS16 +{ + DWORD cbStruct; + + FOURCC fccType; + FOURCC fccComp; + + WORD wMid; + WORD wPid; + + DWORD vdwACM; + DWORD vdwDriver; + + DWORD fdwSupport; + DWORD cFormatTags; + DWORD cFilterTags; + + HICON16 hicon; + + CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; + CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; + CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; + CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; + CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; +} ACMDRIVERDETAILS16, *NPACMDRIVERDETAILS16, *LPACMDRIVERDETAILS16; + +typedef struct _ACMFILTERCHOOSEA +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND hwndOwner; + + PWAVEFILTER pwfltr; + DWORD cbwfltr; + + LPCSTR pszTitle; + + CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; + CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; + LPSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + PWAVEFILTER pwfltrEnum; + + HINSTANCE hInstance; + LPCSTR pszTemplateName; + LPARAM lCustData; + ACMFILTERCHOOSEHOOKPROCA pfnHook; +} ACMFILTERCHOOSEA, *PACMFILTERCHOOSEA; + +typedef struct _ACMFILTERCHOOSEW +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND hwndOwner; + + PWAVEFILTER pwfltr; + DWORD cbwfltr; + + LPCWSTR pszTitle; + + WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; + WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; + LPWSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + PWAVEFILTER pwfltrEnum; + + HINSTANCE hInstance; + LPCWSTR pszTemplateName; + LPARAM lCustData; + ACMFILTERCHOOSEHOOKPROCW pfnHook; +} ACMFILTERCHOOSEW, *PACMFILTERCHOOSEW; + +typedef struct _ACMFILTERCHOOSE16 +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND16 hwndOwner; + + LPWAVEFILTER pwfltr; + DWORD cbwfltr; + + LPCSTR pszTitle; + + char szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; + char szFilter[ACMFILTERDETAILS_FILTER_CHARS]; + LPSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + LPWAVEFILTER pwfltrEnum; + + HINSTANCE16 hInstance; + LPCSTR pszTemplateName; + LPARAM lCustData; + ACMFILTERCHOOSEHOOKPROC16 pfnHook; +} ACMFILTERCHOOSE16, *NPACMFILTERCHOOSE16, *LPACMFILTERCHOOSE16; + +typedef struct _ACMFILTERDETAILSA +{ + DWORD cbStruct; + DWORD dwFilterIndex; + DWORD dwFilterTag; + DWORD fdwSupport; + PWAVEFILTER pwfltr; + DWORD cbwfltr; + CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; +} ACMFILTERDETAILSA, *PACMFILTERDETAILSA; + +typedef struct _ACMFILTERDETAILSW +{ + DWORD cbStruct; + DWORD dwFilterIndex; + DWORD dwFilterTag; + DWORD fdwSupport; + PWAVEFILTER pwfltr; + DWORD cbwfltr; + WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; +} ACMFILTERDETAILSW, *PACMFILTERDETAILSW; + +typedef struct _ACMFILTERDETAILS16 +{ + DWORD cbStruct; + DWORD dwFilterIndex; + DWORD dwFilterTag; + DWORD fdwSupport; + LPWAVEFILTER pwfltr; + DWORD cbwfltr; + CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; +} ACMFILTERDETAILS16, *NPACMFILTERDETAILS16, *LPACMFILTERDETAILS16; + +typedef struct _ACMFILTERTAGDETAILSA +{ + DWORD cbStruct; + DWORD dwFilterTagIndex; + DWORD dwFilterTag; + DWORD cbFilterSize; + DWORD fdwSupport; + DWORD cStandardFilters; + CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; +} ACMFILTERTAGDETAILSA, *PACMFILTERTAGDETAILSA; + +typedef struct _ACMFILTERTAGDETAILSW +{ + DWORD cbStruct; + DWORD dwFilterTagIndex; + DWORD dwFilterTag; + DWORD cbFilterSize; + DWORD fdwSupport; + DWORD cStandardFilters; + WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; +} ACMFILTERTAGDETAILSW, *PACMFILTERTAGDETAILSW; + +typedef struct _ACMFILTERTAGDETAILS16 +{ + DWORD cbStruct; + DWORD dwFilterTagIndex; + DWORD dwFilterTag; + DWORD cbFilterSize; + DWORD fdwSupport; + DWORD cStandardFilters; + CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; +} ACMFILTERTAGDETAILS16, *NPACMFILTERTAGDETAILS16, *LPACMFILTERTAGDETAILS16; + +typedef struct _ACMFORMATCHOOSEA +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND hwndOwner; + + PWAVEFORMATEX pwfx; + DWORD cbwfx; + LPCSTR pszTitle; + + CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; + CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; + + LPSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + PWAVEFORMATEX pwfxEnum; + + HINSTANCE hInstance; + LPCSTR pszTemplateName; + LPARAM lCustData; + ACMFORMATCHOOSEHOOKPROCA pfnHook; +} ACMFORMATCHOOSEA, *PACMFORMATCHOOSEA; + +typedef struct _ACMFORMATCHOOSEW +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND hwndOwner; + + PWAVEFORMATEX pwfx; + DWORD cbwfx; + LPCWSTR pszTitle; + + WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; + WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; + + LPWSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + LPWAVEFORMATEX pwfxEnum; + + HINSTANCE hInstance; + LPCWSTR pszTemplateName; + LPARAM lCustData; + ACMFORMATCHOOSEHOOKPROCW pfnHook; +} ACMFORMATCHOOSEW, *PACMFORMATCHOOSEW; + +typedef struct _ACMFORMATCHOOSE16 +{ + DWORD cbStruct; + DWORD fdwStyle; + + HWND16 hwndOwner; + + LPWAVEFORMATEX pwfx; + DWORD cbwfx; + LPCSTR pszTitle; + + CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; + CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; + + LPSTR pszName; + DWORD cchName; + + DWORD fdwEnum; + LPWAVEFORMATEX pwfxEnum; + + HINSTANCE16 hInstance; + LPCSTR pszTemplateName; + LPARAM lCustData; + ACMFORMATCHOOSEHOOKPROC16 pfnHook; +} ACMFORMATCHOOSE16, *NPACMFORMATCHOOSE16, *LPACMFORMATCHOOSE16; + +typedef struct _ACMFORMATDETAILSA +{ + DWORD cbStruct; + DWORD dwFormatIndex; + DWORD dwFormatTag; + DWORD fdwSupport; + PWAVEFORMATEX pwfx; + DWORD cbwfx; + CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; +} ACMFORMATDETAILSA, *PACMFORMATDETAILSA; + +typedef struct _ACMFORMATDETAILSW +{ + DWORD cbStruct; + DWORD dwFormatIndex; + DWORD dwFormatTag; + DWORD fdwSupport; + PWAVEFORMATEX pwfx; + DWORD cbwfx; + WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; +} ACMFORMATDETAILSW, *PACMFORMATDETAILSW; + +typedef struct _ACMFORMATDETAILS16 +{ + DWORD cbStruct; + DWORD dwFormatIndex; + DWORD dwFormatTag; + DWORD fdwSupport; + LPWAVEFORMATEX pwfx; + DWORD cbwfx; + CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; +} ACMFORMATDETAILS16, *NPACMFORMATDETAILS16, *LPACMFORMATDETAILS16; + +typedef struct _ACMFORMATTAGDETAILSA +{ + DWORD cbStruct; + DWORD dwFormatTagIndex; + DWORD dwFormatTag; + DWORD cbFormatSize; + DWORD fdwSupport; + DWORD cStandardFormats; + CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; +} ACMFORMATTAGDETAILSA, *PACMFORMATTAGDETAILSA; + +typedef struct _ACMFORMATTAGDETAILSW +{ + DWORD cbStruct; + DWORD dwFormatTagIndex; + DWORD dwFormatTag; + DWORD cbFormatSize; + DWORD fdwSupport; + DWORD cStandardFormats; + WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; +} ACMFORMATTAGDETAILSW, *PACMFORMATTAGDETAILSW; + +typedef struct _ACMFORMATTAGDETAILS16 +{ + DWORD cbStruct; + DWORD dwFormatTagIndex; + DWORD dwFormatTag; + DWORD cbFormatSize; + DWORD fdwSupport; + DWORD cStandardFormats; + CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; +} ACMFORMATTAGDETAILS16, *NPACMFORMATTAGDETAILS16, *LPACMFORMATTAGDETAILS16; + +typedef struct _ACMSTREAMHEADER +{ + DWORD cbStruct; + DWORD fdwStatus; + DWORD dwUser; + LPBYTE pbSrc; + DWORD cbSrcLength; + DWORD cbSrcLengthUsed; + DWORD dwSrcUser; + LPBYTE pbDst; + DWORD cbDstLength; + DWORD cbDstLengthUsed; + DWORD dwDstUser; + DWORD dwReservedDriver[10]; +} ACMSTREAMHEADER16, *NPACMSTREAMHEADER16, *LPACMSTREAMHEADER16, + ACMSTREAMHEADER, *PACMSTREAMHEADER; + +/*********************************************************************** + * Callbacks 2 + */ + +typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBA)( + HACMDRIVERID hadid, PACMFILTERDETAILSA pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBW)( + HACMDRIVERID hadid, PACMFILTERDETAILSW pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL16 CALLBACK ( *ACMFILTERENUMCB16)( + HACMDRIVERID16 hadid, LPACMFILTERDETAILS16 pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBA)( + HACMDRIVERID hadid, PACMFILTERTAGDETAILSA paftd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBW)( + HACMDRIVERID hadid, PACMFILTERTAGDETAILSW paftd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL16 CALLBACK ( *ACMFILTERTAGENUMCB16)( + HACMDRIVERID16 hadid, LPACMFILTERTAGDETAILS16 paftd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBA)( + HACMDRIVERID hadid, PACMFORMATDETAILSA pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBW)( + HACMDRIVERID hadid, PACMFORMATDETAILSW pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL16 CALLBACK ( *ACMFORMATENUMCB16)( + HACMDRIVERID16 hadid, LPACMFORMATDETAILS16 pafd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBA)( + HACMDRIVERID hadid, PACMFORMATTAGDETAILSA paftd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBW)( + HACMDRIVERID hadid, PACMFORMATTAGDETAILSW paftd, + DWORD dwInstance, DWORD fdwSupport +); + +typedef WIN_BOOL16 CALLBACK ( *ACMFORMATTAGENUMCB16)( + HACMDRIVERID16 hadid, LPACMFORMATTAGDETAILS16 paftd, + DWORD dwInstance, DWORD fdwSupport +); + +/*********************************************************************** + * Functions - Win16 + */ + +DWORD WINAPI acmGetVersion16( +); +MMRESULT16 WINAPI acmMetrics16( + HACMOBJ16 hao, UINT16 uMetric, LPVOID pMetric +); +MMRESULT16 WINAPI acmDriverEnum16( + ACMDRIVERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT16 WINAPI acmDriverDetails16( + HACMDRIVERID16 hadid, LPACMDRIVERDETAILS16 padd, DWORD fdwDetails +); +MMRESULT16 WINAPI acmDriverAdd16( + LPHACMDRIVERID16 phadid, HINSTANCE16 hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd +); +MMRESULT16 WINAPI acmDriverRemove16( + HACMDRIVERID16 hadid, DWORD fdwRemove +); +MMRESULT16 WINAPI acmDriverOpen16( + LPHACMDRIVER16 phad, HACMDRIVERID16 hadid, DWORD fdwOpen +); +MMRESULT16 WINAPI acmDriverClose16( + HACMDRIVER16 had, DWORD fdwClose +); +LRESULT WINAPI acmDriverMessage16( + HACMDRIVER16 had, UINT16 uMsg, LPARAM lParam1, LPARAM lParam2 +); +MMRESULT16 WINAPI acmDriverID16( + HACMOBJ16 hao, LPHACMDRIVERID16 phadid, DWORD fdwDriverID +); +MMRESULT16 WINAPI acmDriverPriority16( + HACMDRIVERID16 hadid, DWORD dwPriority, DWORD fdwPriority +); +MMRESULT16 WINAPI acmFormatTagDetails16( + HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, DWORD fdwDetails +); +MMRESULT16 WINAPI acmFormatTagEnum16( + HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, + ACMFORMATTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT16 WINAPI acmFormatChoose16( + LPACMFORMATCHOOSE16 pafmtc +); +MMRESULT16 WINAPI acmFormatDetails16( + HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, DWORD fdwDetails +); +MMRESULT16 WINAPI acmFormatEnum16( + HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, + ACMFORMATENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT16 WINAPI acmFormatSuggest16( + HACMDRIVER16 had, LPWAVEFORMATEX pwfxSrc, + LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest +); +MMRESULT16 WINAPI acmFilterTagDetails16( + HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, DWORD fdwDetails +); +MMRESULT16 WINAPI acmFilterTagEnum16( + HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, + ACMFILTERTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT16 WINAPI acmFilterChoose16( + LPACMFILTERCHOOSE16 pafltrc +); +MMRESULT16 WINAPI acmFilterDetails16( + HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, DWORD fdwDetails +); +MMRESULT16 WINAPI acmFilterEnum16( + HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, + ACMFILTERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT16 WINAPI acmStreamOpen16( + LPHACMSTREAM16 phas, HACMDRIVER16 had, + LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, + LPWAVEFILTER pwfltr, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen +); +MMRESULT16 WINAPI acmStreamClose16( + HACMSTREAM16 has, DWORD fdwClose +); +MMRESULT16 WINAPI acmStreamSize16( + HACMSTREAM16 has, DWORD cbInput, + LPDWORD pdwOutputBytes, DWORD fdwSize +); +MMRESULT16 WINAPI acmStreamConvert16( + HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwConvert +); +MMRESULT16 WINAPI acmStreamReset16( + HACMSTREAM16 has, DWORD fdwReset +); +MMRESULT16 WINAPI acmStreamPrepareHeader16( + HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwPrepare +); +MMRESULT16 WINAPI acmStreamUnprepareHeader16( + HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwUnprepare +); + +/*********************************************************************** + * Functions - Win32 + */ + +MMRESULT WINAPI acmDriverAddA( + PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd +); +MMRESULT WINAPI acmDriverAddW( + PHACMDRIVERID phadid, HINSTANCE hinstModule, + LPARAM lParam, DWORD dwPriority, DWORD fdwAdd +); +MMRESULT WINAPI acmDriverClose( + HACMDRIVER had, DWORD fdwClose +); +MMRESULT WINAPI acmDriverDetailsA( + HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails +); +MMRESULT WINAPI acmDriverDetailsW( + HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails +); +MMRESULT WINAPI acmDriverEnum( + ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmDriverID( + HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID +); +LRESULT WINAPI acmDriverMessage( + HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2 +); +MMRESULT WINAPI acmDriverOpen( + PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen +); +MMRESULT WINAPI acmDriverPriority( + HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority +); +MMRESULT WINAPI acmDriverRemove( + HACMDRIVERID hadid, DWORD fdwRemove +); +MMRESULT WINAPI acmFilterChooseA( + PACMFILTERCHOOSEA pafltrc +); +MMRESULT WINAPI acmFilterChooseW( + PACMFILTERCHOOSEW pafltrc +); +MMRESULT WINAPI acmFilterDetailsA( + HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterDetailsW( + HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterEnumA( + HACMDRIVER had, PACMFILTERDETAILSA pafd, + ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFilterEnumW( + HACMDRIVER had, PACMFILTERDETAILSW pafd, + ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFilterTagDetailsA( + HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterTagDetailsW( + HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails +); +MMRESULT WINAPI acmFilterTagEnumA( + HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, + ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFilterTagEnumW( + HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, + ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFormatChooseA( + PACMFORMATCHOOSEA pafmtc +); +MMRESULT WINAPI acmFormatChooseW( + PACMFORMATCHOOSEW pafmtc +); +MMRESULT WINAPI acmFormatDetailsA( + HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFormatDetailsW( + HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails +); +MMRESULT WINAPI acmFormatEnumA( + HACMDRIVER had, PACMFORMATDETAILSA pafd, + ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFormatEnumW( + HACMDRIVER had, PACMFORMATDETAILSW pafd, + ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFormatSuggest( + HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, + DWORD cbwfxDst, DWORD fdwSuggest +); +MMRESULT WINAPI acmFormatTagDetailsA( + HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails +); +MMRESULT WINAPI acmFormatTagDetailsW( + HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails +); +MMRESULT WINAPI acmFormatTagEnumA( + HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, + ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum +); +MMRESULT WINAPI acmFormatTagEnumW( + HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, + ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum +); +DWORD WINAPI acmGetVersion( +); +MMRESULT WINAPI acmMetrics( + HACMOBJ hao, UINT uMetric, LPVOID pMetric +); +MMRESULT WINAPI acmStreamClose( + HACMSTREAM has, DWORD fdwClose +); +MMRESULT WINAPI acmStreamConvert( + HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert +); +MMRESULT WINAPI acmStreamMessage( + HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2 +); +MMRESULT WINAPI acmStreamOpen( + PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, + PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen +); +MMRESULT WINAPI acmStreamPrepareHeader( + HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare +); +MMRESULT WINAPI acmStreamReset( + HACMSTREAM has, DWORD fdwReset +); +MMRESULT WINAPI acmStreamSize( + HACMSTREAM has, DWORD cbInput, + LPDWORD pdwOutputBytes, DWORD fdwSize +); +MMRESULT WINAPI acmStreamUnprepareHeader( + HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare +); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_MSACM_H */ + + diff --git a/linphone/win32acm/wine/msacmdrv.h b/linphone/win32acm/wine/msacmdrv.h new file mode 100644 index 000000000..2e23a17d7 --- /dev/null +++ b/linphone/win32acm/wine/msacmdrv.h @@ -0,0 +1,203 @@ +/* + * msacmdrv.h - Declarations for MSACM driver + */ + +#ifndef __WINE_MSACMDRV_H +#define __WINE_MSACMDRV_H + +#include "windef.h" +#include "msacm.h" + +/*********************************************************************** + * Types + */ + +/*********************************************************************** + * Defines/Enums + */ + +#define MAKE_ACM_VERSION(mjr, mnr, bld) \ + (((long)(mjr)<<24) | ((long)(mnr)<<16) | ((long)bld)) + +#define ACMDRVOPENDESC_SECTIONNAME_CHARS + +#define ACMDM_DRIVER_NOTIFY (ACMDM_BASE + 1) +#define ACMDM_DRIVER_DETAILS (ACMDM_BASE + 10) + +#define ACMDM_HARDWARE_WAVE_CAPS_INPUT (ACMDM_BASE + 20) +#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21) + +#define ACMDM_FORMATTAG_DETAILS (ACMDM_BASE + 25) +#define ACMDM_FORMAT_DETAILS (ACMDM_BASE + 26) +#define ACMDM_FORMAT_SUGGEST (ACMDM_BASE + 27) + +#define ACMDM_FILTERTAG_DETAILS (ACMDM_BASE + 50) +#define ACMDM_FILTER_DETAILS (ACMDM_BASE + 51) + +#define ACMDM_STREAM_OPEN (ACMDM_BASE + 76) +#define ACMDM_STREAM_CLOSE (ACMDM_BASE + 77) +#define ACMDM_STREAM_SIZE (ACMDM_BASE + 78) +#define ACMDM_STREAM_CONVERT (ACMDM_BASE + 79) +#define ACMDM_STREAM_RESET (ACMDM_BASE + 80) +#define ACMDM_STREAM_PREPARE (ACMDM_BASE + 81) +#define ACMDM_STREAM_UNPREPARE (ACMDM_BASE + 82) +#define ACMDM_STREAM_UPDATE (ACMDM_BASE + 83) + +/*********************************************************************** + * Structures + */ + +typedef struct _ACMDRVOPENDESCA +{ + DWORD cbStruct; + FOURCC fccType; + FOURCC fccComp; + DWORD dwVersion; + DWORD dwFlags; + DWORD dwError; + LPCSTR pszSectionName; + LPCSTR pszAliasName; + DWORD dnDevNode; +} ACMDRVOPENDESCA, *PACMDRVOPENDESCA; + +typedef struct _ACMDRVOPENDESCW +{ + DWORD cbStruct; + FOURCC fccType; + FOURCC fccComp; + DWORD dwVersion; + DWORD dwFlags; + DWORD dwError; + LPCWSTR pszSectionName; + LPCWSTR pszAliasName; + DWORD dnDevNode; +} ACMDRVOPENDESCW, *PACMDRVOPENDESCW; + +typedef struct _ACMDRVOPENDESC16 +{ + DWORD cbStruct; + FOURCC fccType; + FOURCC fccComp; + DWORD dwVersion; + DWORD dwFlags; + DWORD dwError; + LPCSTR pszSectionName; + LPCSTR pszAliasName; + DWORD dnDevNode; +} ACMDRVOPENDESC16, *NPACMDRVOPENDESC16, *LPACMDRVOPENDESC16; + +typedef struct _ACMDRVSTREAMINSTANCE16 +{ + DWORD cbStruct; + LPWAVEFORMATEX pwfxSrc; + LPWAVEFORMATEX pwfxDst; + LPWAVEFILTER pwfltr; + DWORD dwCallback; + DWORD dwInstance; + DWORD fdwOpen; + DWORD fdwDriver; + DWORD dwDriver; + HACMSTREAM16 has; +} ACMDRVSTREAMINSTANCE16, *NPACMDRVSTREAMINSTANCE16, *LPACMDRVSTREAMINSTANCE16; + +typedef struct _ACMDRVSTREAMINSTANCE +{ + DWORD cbStruct; + PWAVEFORMATEX pwfxSrc; + PWAVEFORMATEX pwfxDst; + PWAVEFILTER pwfltr; + DWORD dwCallback; + DWORD dwInstance; + DWORD fdwOpen; + DWORD fdwDriver; + DWORD dwDriver; + HACMSTREAM has; +} ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE; + + +typedef struct _ACMDRVSTREAMHEADER16 *LPACMDRVSTREAMHEADER16; +typedef struct _ACMDRVSTREAMHEADER16 { + DWORD cbStruct; + DWORD fdwStatus; + DWORD dwUser; + LPBYTE pbSrc; + DWORD cbSrcLength; + DWORD cbSrcLengthUsed; + DWORD dwSrcUser; + LPBYTE pbDst; + DWORD cbDstLength; + DWORD cbDstLengthUsed; + DWORD dwDstUser; + + DWORD fdwConvert; + LPACMDRVSTREAMHEADER16 *padshNext; + DWORD fdwDriver; + DWORD dwDriver; + + /* Internal fields for ACM */ + DWORD fdwPrepared; + DWORD dwPrepared; + LPBYTE pbPreparedSrc; + DWORD cbPreparedSrcLength; + LPBYTE pbPreparedDst; + DWORD cbPreparedDstLength; +} ACMDRVSTREAMHEADER16, *NPACMDRVSTREAMHEADER16; + +typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER; +typedef struct _ACMDRVSTREAMHEADER { + DWORD cbStruct; + DWORD fdwStatus; + DWORD dwUser; + LPBYTE pbSrc; + DWORD cbSrcLength; + DWORD cbSrcLengthUsed; + DWORD dwSrcUser; + LPBYTE pbDst; + DWORD cbDstLength; + DWORD cbDstLengthUsed; + DWORD dwDstUser; + + DWORD fdwConvert; + PACMDRVSTREAMHEADER *padshNext; + DWORD fdwDriver; + DWORD dwDriver; + + /* Internal fields for ACM */ + DWORD fdwPrepared; + DWORD dwPrepared; + LPBYTE pbPreparedSrc; + DWORD cbPreparedSrcLength; + LPBYTE pbPreparedDst; + DWORD cbPreparedDstLength; +} ACMDRVSTREAMHEADER; + +typedef struct _ACMDRVSTREAMSIZE +{ + DWORD cbStruct; + DWORD fdwSize; + DWORD cbSrcLength; + DWORD cbDstLength; +} ACMDRVSTREAMSIZE16, *NPACMDRVSTREAMSIZE16, *LPACMDRVSTREAMSIZE16, + ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE; + +typedef struct _ACMDRVFORMATSUGGEST16 +{ + DWORD cbStruct; + DWORD fdwSuggest; + LPWAVEFORMATEX pwfxSrc; + DWORD cbwfxSrc; + LPWAVEFORMATEX pwfxDst; + DWORD cbwfxDst; +} ACMDRVFORMATSUGGEST16, *NPACMDRVFORMATSUGGEST, *LPACMDRVFORMATSUGGEST; + +typedef struct _ACMDRVFORMATSUGGEST +{ + DWORD cbStruct; + DWORD fdwSuggest; + PWAVEFORMATEX pwfxSrc; + DWORD cbwfxSrc; + PWAVEFORMATEX pwfxDst; + DWORD cbwfxDst; +} ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST; + +#endif /* __WINE_MSACMDRV_H */ diff --git a/linphone/win32acm/wine/ntdef.h b/linphone/win32acm/wine/ntdef.h new file mode 100644 index 000000000..edf0af86c --- /dev/null +++ b/linphone/win32acm/wine/ntdef.h @@ -0,0 +1,101 @@ +#ifndef __WINE_NTDEF_H +#define __WINE_NTDEF_H + +#include "basetsd.h" +#include "windef.h" + +#include "pshpack1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NTAPI __stdcall + +#ifndef IN +#define IN +#endif + +#ifndef OUT +#define OUT +#endif + +#ifndef OPTIONAL +#define OPTIONAL +#endif + +#ifndef VOID +#define VOID void +#endif + +typedef LONG NTSTATUS; +typedef NTSTATUS *PNTSTATUS; + +typedef short CSHORT; +typedef CSHORT *PCSHORT; + +typedef WCHAR * PWCHAR; + +/* NT lowlevel Strings (handled by Rtl* functions in NTDLL) + * If they are zero terminated, Length does not include the terminating 0. + */ + +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; + PSTR Buffer; +} STRING,*PSTRING,ANSI_STRING,*PANSI_STRING; + +typedef struct _CSTRING { + USHORT Length; + USHORT MaximumLength; + PCSTR Buffer; +} CSTRING,*PCSTRING; + +typedef struct _UNICODE_STRING { + USHORT Length; /* bytes */ + USHORT MaximumLength; /* bytes */ + PWSTR Buffer; +} UNICODE_STRING,*PUNICODE_STRING; + +/* + Objects +*/ + +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_VALID_ATTRIBUTES 0x000003F2L + +typedef struct _OBJECT_ATTRIBUTES +{ ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */ + PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */ +} OBJECT_ATTRIBUTES; + +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +#define InitializeObjectAttributes(p,n,a,r,s) \ +{ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ + (p)->RootDirectory = r; \ + (p)->Attributes = a; \ + (p)->ObjectName = n; \ + (p)->SecurityDescriptor = s; \ + (p)->SecurityQualityOfService = NULL; \ +} + + +#ifdef __cplusplus +} +#endif + +#include "poppack.h" + +#endif diff --git a/linphone/win32acm/wine/pe_image.h b/linphone/win32acm/wine/pe_image.h new file mode 100644 index 000000000..3f550ba46 --- /dev/null +++ b/linphone/win32acm/wine/pe_image.h @@ -0,0 +1,81 @@ +#ifndef __WINE_PE_IMAGE_H +#define __WINE_PE_IMAGE_H + +#include "winnt.h" +#include "winbase.h" + +#define PE_HEADER(module) \ + ((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \ + (((IMAGE_DOS_HEADER*)(module))->e_lfanew))) + +#define PE_SECTIONS(module) \ + ((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \ + PE_HEADER(module)->FileHeader.SizeOfOptionalHeader)) + +#define RVA_PTR(module,field) ((LPBYTE)(module) + PE_HEADER(module)->field) + +/* modreference used for attached processes + * all section are calculated here, relocations etc. + */ +typedef struct { + PIMAGE_IMPORT_DESCRIPTOR pe_import; + PIMAGE_EXPORT_DIRECTORY pe_export; + PIMAGE_RESOURCE_DIRECTORY pe_resource; + int tlsindex; +} PE_MODREF; + +struct _wine_modref; +extern int PE_unloadImage(HMODULE hModule); +extern FARPROC PE_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName, WIN_BOOL snoop); +extern WIN_BOOL PE_EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG); +extern WIN_BOOL PE_EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG); +extern WIN_BOOL PE_EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG); +extern WIN_BOOL PE_EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG); +extern WIN_BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG); +extern WIN_BOOL PE_EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG); +extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD); +extern DWORD PE_SizeofResource(HMODULE,HRSRC); +extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD); +extern void PE_UnloadLibrary(struct _wine_modref *); +extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC); +extern HMODULE PE_LoadImage( int hFile, LPCSTR filename, WORD *version ); +extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename, + DWORD flags, WIN_BOOL builtin ); +extern WIN_BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, + LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, + WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, + LPPROCESS_INFORMATION info ); + +extern void PE_InitTls(void); +extern WIN_BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved); + +extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,WIN_BOOL); +extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,WIN_BOOL); + +typedef DWORD CALLBACK (*DLLENTRYPROC)(HMODULE,DWORD,LPVOID); + +typedef struct { + WORD popl WINE_PACKED; /* 0x8f 0x05 */ + DWORD addr_popped WINE_PACKED;/* ... */ + BYTE pushl1 WINE_PACKED; /* 0x68 */ + DWORD newret WINE_PACKED; /* ... */ + BYTE pushl2 WINE_PACKED; /* 0x68 */ + DWORD origfun WINE_PACKED; /* original function */ + BYTE ret1 WINE_PACKED; /* 0xc3 */ + WORD addesp WINE_PACKED; /* 0x83 0xc4 */ + BYTE nrofargs WINE_PACKED; /* nr of arguments to add esp, */ + BYTE pushl3 WINE_PACKED; /* 0x68 */ + DWORD oldret WINE_PACKED; /* Filled out from popl above */ + BYTE ret2 WINE_PACKED; /* 0xc3 */ +} ELF_STDCALL_STUB; + +typedef struct { + void* dlhandle; + ELF_STDCALL_STUB *stubs; +} ELF_MODREF; + +extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags); +extern void ELF_UnloadLibrary(struct _wine_modref *); +extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName); + +#endif /* __WINE_PE_IMAGE_H */ diff --git a/linphone/win32acm/wine/poppack.h b/linphone/win32acm/wine/poppack.h new file mode 100644 index 000000000..710479159 --- /dev/null +++ b/linphone/win32acm/wine/poppack.h @@ -0,0 +1,15 @@ +#ifdef __WINE_PSHPACK_H +#undef __WINE_PSHPACK_H + +#if defined(__GNUC__) || defined(__SUNPRO_C) +#pragma pack() +#elif defined(__SUNPRO_CC) +#warning "Assumes default alignment is 4" +#pragma pack(4) +#elif !defined(RC_INVOKED) +#error "Restoration of the previous alignment isn't supported by the compiler" +#endif /* defined(__GNUC__) || defined(__SUNPRO_C) ; !defined(RC_INVOKED) */ + +#else /* defined(__WINE_PSHPACK_H) */ +#error "Popping alignment isn't possible since no alignment has been pushed" +#endif /* defined(__WINE_PSHPACK_H) */ diff --git a/linphone/win32acm/wine/pshpack1.h b/linphone/win32acm/wine/pshpack1.h new file mode 100644 index 000000000..e560250c2 --- /dev/null +++ b/linphone/win32acm/wine/pshpack1.h @@ -0,0 +1,13 @@ +#ifndef __WINE_PSHPACK_H +#define __WINE_PSHPACK_H 1 + +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +//#pragma pack(1) +#elif !defined(RC_INVOKED) +#error "1 as alignment isn't supported by the compiler" +#endif /* defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ + +#else /* !defined(__WINE_PSHPACK_H) */ +#error "Nested pushing of alignment isn't supported by the compiler" +#endif /* !defined(__WINE_PSHPACK_H) */ + diff --git a/linphone/win32acm/wine/pshpack2.h b/linphone/win32acm/wine/pshpack2.h new file mode 100644 index 000000000..887b1e17b --- /dev/null +++ b/linphone/win32acm/wine/pshpack2.h @@ -0,0 +1,12 @@ +#ifndef __WINE_PSHPACK_H +#define __WINE_PSHPACK_H 2 + +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +//#pragma pack(2) +#elif !defined(RC_INVOKED) +#error "2 as alignment isn't supported by the compiler" +#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ + +#else /* !defined(__WINE_PSHPACK_H) */ +#error "Nested pushing of alignment isn't supported by the compiler" +#endif /* !defined(__WINE_PSHPACK_H) */ diff --git a/linphone/win32acm/wine/pshpack4.h b/linphone/win32acm/wine/pshpack4.h new file mode 100644 index 000000000..9fdaf70a7 --- /dev/null +++ b/linphone/win32acm/wine/pshpack4.h @@ -0,0 +1,15 @@ +#ifndef __WINE_PSHPACK_H +#define __WINE_PSHPACK_H 4 + +#if defined(__GNUC__) || defined(__SUNPRO_CC) +//#pragma pack(4) +#elif defined(__SUNPRO_C) +//#pragma pack() +#elif !defined(RC_INVOKED) +#error "4 as alignment isn't supported by the compiler" +#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ + +#else /* !defined(__WINE_PSHPACK_H) */ +#error "Nested pushing of alignment isn't supported by the compiler" +#endif /* !defined(__WINE_PSHPACK_H) */ + diff --git a/linphone/win32acm/wine/pshpack8.h b/linphone/win32acm/wine/pshpack8.h new file mode 100644 index 000000000..74d13a472 --- /dev/null +++ b/linphone/win32acm/wine/pshpack8.h @@ -0,0 +1,12 @@ +#ifndef __WINE_PSHPACK_H +#define __WINE_PSHPACK_H 8 + +#if 0 +//#pragma pack(8) +#elif !defined(RC_INVOKED) +#error "8 as alignment is not supported" +#endif /* 0 ; !defined(RC_INVOKED) */ + +#else /* !defined(__WINE_PSHPACK_H) */ +#error "Nested pushing of alignment isn't supported by the compiler" +#endif /* !defined(__WINE_PSHPACK_H) */ diff --git a/linphone/win32acm/wine/vfw.h b/linphone/win32acm/wine/vfw.h new file mode 100644 index 000000000..cfaf46ee8 --- /dev/null +++ b/linphone/win32acm/wine/vfw.h @@ -0,0 +1,668 @@ +#ifndef __WINE_VFW_H +#define __WINE_VFW_H +//#include "pshpack1.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifndef __WINE_WINGDI_H + +typedef struct __attribute__((__packed__)) +{ + short bfType; + long bfSize; + short bfReserved1; + short bfReserved2; + long bfOffBits; +} BITMAPFILEHEADER; + +#ifndef _BITMAPINFOHEADER_ +#define _BITMAPINFOHEADER_ +typedef struct __attribute__((__packed__)) +{ + int biSize; + int biWidth; + int biHeight; + short biPlanes; + short biBitCount; + int biCompression; + int biSizeImage; + int biXPelsPerMeter; + int biYPelsPerMeter; + int biClrUsed; + int biClrImportant; +} BITMAPINFOHEADER, *PBITMAPINFOHEADER, *LPBITMAPINFOHEADER; +typedef struct { + BITMAPINFOHEADER bmiHeader; + int bmiColors[1]; +} BITMAPINFO, *LPBITMAPINFO; +#endif + +#endif +#define VFWAPI +#define VFWAPIV +#ifndef __WINE_WINDEF_H +typedef long (__stdcall__ *DRIVERPROC)(long,HDRVR,unsigned int,long,long); +#endif + + + +#ifndef mmioFOURCC +#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ + ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \ + ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) ) +#endif + +#ifndef aviTWOCC +#define aviTWOCC(ch0, ch1) ((short)(unsigned char)(ch0) | ((short)(unsigned char)(ch1) << 8)) +#endif + +#define ICTYPE_VIDEO mmioFOURCC('v', 'i', 'd', 'c') +#define ICTYPE_AUDIO mmioFOURCC('a', 'u', 'd', 'c') + + +/* Installable Compressor M? */ + +/* HIC struct (same layout as Win95 one) */ +typedef struct tagWINE_HIC { + long magic; /* 00: 'Smag' */ + HANDLE curthread; /* 04: */ + long type; /* 08: */ + long handler; /* 0C: */ + HDRVR hdrv; /* 10: */ + long driverid; /* 14:(handled by SendDriverMessage)*/ + DRIVERPROC driverproc; /* 18:(handled by SendDriverMessage)*/ + long x1; /* 1c: name? */ + short x2; /* 20: */ + long x3; /* 22: */ + /* 26: */ +} WINE_HIC; + +/* error return codes */ +#define ICERR_OK 0 +#define ICERR_DONTDRAW 1 +#define ICERR_NEWPALETTE 2 +#define ICERR_GOTOKEYFRAME 3 +#define ICERR_STOPDRAWING 4 + +#define ICERR_UNSUPPORTED -1 +#define ICERR_BADFORMAT -2 +#define ICERR_MEMORY -3 +#define ICERR_INTERNAL -4 +#define ICERR_BADFLAGS -5 +#define ICERR_BADPARAM -6 +#define ICERR_BADSIZE -7 +#define ICERR_BADHANDLE -8 +#define ICERR_CANTUPDATE -9 +#define ICERR_ABORT -10 +#define ICERR_ERROR -100 +#define ICERR_BADBITDEPTH -200 +#define ICERR_BADIMAGESIZE -201 + +#define ICERR_CUSTOM -400 + +/* ICM Messages */ +#define ICM_USER (DRV_USER+0x0000) + +/* ICM driver message range */ +#define ICM_RESERVED_LOW (DRV_USER+0x1000) +#define ICM_RESERVED_HIGH (DRV_USER+0x2000) +#define ICM_RESERVED ICM_RESERVED_LOW + +#define ICM_GETSTATE (ICM_RESERVED+0) +#define ICM_SETSTATE (ICM_RESERVED+1) +#define ICM_GETINFO (ICM_RESERVED+2) + +#define ICM_CONFIGURE (ICM_RESERVED+10) +#define ICM_ABOUT (ICM_RESERVED+11) +/* */ + +#define ICM_GETDEFAULTQUALITY (ICM_RESERVED+30) +#define ICM_GETQUALITY (ICM_RESERVED+31) +#define ICM_SETQUALITY (ICM_RESERVED+32) + +#define ICM_SET (ICM_RESERVED+40) +#define ICM_GET (ICM_RESERVED+41) + +/* 2 constant FOURCC codes */ +#define ICM_FRAMERATE mmioFOURCC('F','r','m','R') +#define ICM_KEYFRAMERATE mmioFOURCC('K','e','y','R') + +#define ICM_COMPRESS_GET_FORMAT (ICM_USER+4) +#define ICM_COMPRESS_GET_SIZE (ICM_USER+5) +#define ICM_COMPRESS_QUERY (ICM_USER+6) +#define ICM_COMPRESS_BEGIN (ICM_USER+7) +#define ICM_COMPRESS (ICM_USER+8) +#define ICM_COMPRESS_END (ICM_USER+9) + +#define ICM_DECOMPRESS_GET_FORMAT (ICM_USER+10) +#define ICM_DECOMPRESS_QUERY (ICM_USER+11) +#define ICM_DECOMPRESS_BEGIN (ICM_USER+12) +#define ICM_DECOMPRESS (ICM_USER+13) +#define ICM_DECOMPRESS_END (ICM_USER+14) +#define ICM_DECOMPRESS_SET_PALETTE (ICM_USER+29) +#define ICM_DECOMPRESS_GET_PALETTE (ICM_USER+30) + +#define ICM_DRAW_QUERY (ICM_USER+31) +#define ICM_DRAW_BEGIN (ICM_USER+15) +#define ICM_DRAW_GET_PALETTE (ICM_USER+16) +#define ICM_DRAW_START (ICM_USER+18) +#define ICM_DRAW_STOP (ICM_USER+19) +#define ICM_DRAW_END (ICM_USER+21) +#define ICM_DRAW_GETTIME (ICM_USER+32) +#define ICM_DRAW (ICM_USER+33) +#define ICM_DRAW_WINDOW (ICM_USER+34) +#define ICM_DRAW_SETTIME (ICM_USER+35) +#define ICM_DRAW_REALIZE (ICM_USER+36) +#define ICM_DRAW_FLUSH (ICM_USER+37) +#define ICM_DRAW_RENDERBUFFER (ICM_USER+38) + +#define ICM_DRAW_START_PLAY (ICM_USER+39) +#define ICM_DRAW_STOP_PLAY (ICM_USER+40) + +#define ICM_DRAW_SUGGESTFORMAT (ICM_USER+50) +#define ICM_DRAW_CHANGEPALETTE (ICM_USER+51) + +#define ICM_GETBUFFERSWANTED (ICM_USER+41) + +#define ICM_GETDEFAULTKEYFRAMERATE (ICM_USER+42) + +#define ICM_DECOMPRESSEX_BEGIN (ICM_USER+60) +#define ICM_DECOMPRESSEX_QUERY (ICM_USER+61) +#define ICM_DECOMPRESSEX (ICM_USER+62) +#define ICM_DECOMPRESSEX_END (ICM_USER+63) + +#define ICM_COMPRESS_FRAMES_INFO (ICM_USER+70) +#define ICM_SET_STATUS_PROC (ICM_USER+72) + +/* structs */ + +typedef struct { + long dwSize; /* 00: size */ + long fccType; /* 04: type 'vidc' usually */ + long fccHandler; /* 08: */ + long dwVersion; /* 0c: version of compman opening you */ + long dwFlags; /* 10: LOshort is type specific */ + LRESULT dwError; /* 14: */ + void* pV1Reserved; /* 18: */ + void* pV2Reserved; /* 1c: */ + long dnDevNode; /* 20: */ + /* 24: */ +} ICOPEN,*LPICOPEN; + +#define ICCOMPRESS_KEYFRAME 0x00000001L + +typedef struct { + long dwFlags; + LPBITMAPINFOHEADER lpbiOutput; + void* lpOutput; + LPBITMAPINFOHEADER lpbiInput; + const void* lpInput; + long* lpckid; + long* lpdwFlags; + long lFrameNum; + long dwFrameSize; + long dwQuality; + LPBITMAPINFOHEADER lpbiPrev; + void* lpPrev; +} ICCOMPRESS; + +long VFWAPIV ICCompress( + HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData, + LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid, + long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality, + LPBITMAPINFOHEADER lpbiPrev,void* lpPrev +); + + +#define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL) + +#define ICGetDefaultKeyFrameRate(hic,lpint) \ + ICSendMessage( \ + hic, ICM_GETDEFAULTKEYFRAMERATE, \ + (long)(void*)(lpint), \ + 0 ) + +#define ICGetDefaultQuality(hic,lpint) \ + ICSendMessage( \ + hic, ICM_GETDEFAULTQUALITY, \ + (long)(void*)(lpint), \ + 0 ) + + +#define ICCompressBegin(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICCompressQuery(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + + +#define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0) + +/* ICCOMPRESSFRAMES.dwFlags */ +#define ICCOMPRESSFRAMES_PADDING 0x00000001 +typedef struct { + long dwFlags; + LPBITMAPINFOHEADER lpbiOutput; + LPARAM lOutput; + LPBITMAPINFOHEADER lpbiInput; + LPARAM lInput; + long lStartFrame; + long lFrameCount; + long lQuality; + long lDataRate; + long lKeyRate; + long dwRate; + long dwScale; + long dwOverheadPerFrame; + long dwReserved2; + long CALLBACK (*GetData)(LPARAM lInput,long lFrame,void* lpBits,long len); + long CALLBACK (*PutData)(LPARAM lOutput,long lFrame,void* lpBits,long len); +} ICCOMPRESSFRAMES; + +/* Values for wMode of ICOpen() */ +#define ICMODE_COMPRESS 1 +#define ICMODE_DECOMPRESS 2 +#define ICMODE_FASTDECOMPRESS 3 +#define ICMODE_QUERY 4 +#define ICMODE_FASTCOMPRESS 5 +#define ICMODE_DRAW 8 + +/* quality flags */ +#define ICQUALITY_LOW 0 +#define ICQUALITY_HIGH 10000 +#define ICQUALITY_DEFAULT -1 + +typedef struct { + long dwSize; /* 00: */ + long fccType; /* 04:compressor type 'vidc' 'audc' */ + long fccHandler; /* 08:compressor sub-type 'rle ' 'jpeg' 'pcm '*/ + long dwFlags; /* 0c:flags LOshort is type specific */ + long dwVersion; /* 10:version of the driver */ + long dwVersionICM; /* 14:version of the ICM used */ + /* + * under Win32, the driver always returns UNICODE strings. + */ + WCHAR szName[16]; /* 18:short name */ + WCHAR szDescription[128]; /* 38:long name */ + WCHAR szDriver[128]; /* 138:driver that contains compressor*/ + /* 238: */ +} ICINFO; + +/* ICINFO.dwFlags */ +#define VIDCF_QUALITY 0x0001 /* supports quality */ +#define VIDCF_CRUNCH 0x0002 /* supports crunching to a frame size */ +#define VIDCF_TEMPORAL 0x0004 /* supports inter-frame compress */ +#define VIDCF_COMPRESSFRAMES 0x0008 /* wants the compress all frames message */ +#define VIDCF_DRAW 0x0010 /* supports drawing */ +#define VIDCF_FASTTEMPORALC 0x0020 /* does not need prev frame on compress */ +#define VIDCF_FASTTEMPORALD 0x0080 /* does not need prev frame on decompress */ +#define VIDCF_QUALITYTIME 0x0040 /* supports temporal quality */ + +#define VIDCF_FASTTEMPORAL (VIDCF_FASTTEMPORALC|VIDCF_FASTTEMPORALD) + + +/* function shortcuts */ +/* ICM_ABOUT */ +#define ICMF_ABOUT_QUERY 0x00000001 + +#define ICQueryAbout(hic) \ + (ICSendMessage(hic,ICM_ABOUT,(long)-1,ICMF_ABOUT_QUERY)==ICERR_OK) + +#define ICAbout(hic, hwnd) ICSendMessage(hic,ICM_ABOUT,(long)(unsigned int)(hwnd),0) + +/* ICM_CONFIGURE */ +#define ICMF_CONFIGURE_QUERY 0x00000001 +#define ICQueryConfigure(hic) \ + (ICSendMessage(hic,ICM_CONFIGURE,(long)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK) + +#define ICConfigure(hic,hwnd) \ + ICSendMessage(hic,ICM_CONFIGURE,(long)(unsigned int)(hwnd),0) + +/* Decompression stuff */ +#define ICDECOMPRESS_HURRYUP 0x80000000 /* don't draw just buffer (hurry up!) */ +#define ICDECOMPRESS_UPDATE 0x40000000 /* don't draw just update screen */ +#define ICDECOMPRESS_PREROL 0x20000000 /* this frame is before real start */ +#define ICDECOMPRESS_NULLFRAME 0x10000000 /* repeat last frame */ +#define ICDECOMPRESS_NOTKEYFRAME 0x08000000 /* this frame is not a key frame */ + +typedef struct { + long dwFlags; /* flags (from AVI index...) */ + LPBITMAPINFOHEADER lpbiInput; /* BITMAPINFO of compressed data */ + const void* lpInput; /* compressed data */ + LPBITMAPINFOHEADER lpbiOutput; /* DIB to decompress to */ + void* lpOutput; + long ckid; /* ckid from AVI file */ +} ICDECOMPRESS; + +typedef struct { + long dwFlags; + LPBITMAPINFOHEADER lpbiSrc; + const void* lpSrc; + LPBITMAPINFOHEADER lpbiDst; + void* lpDst; + + /* changed for ICM_DECOMPRESSEX */ + INT xDst; /* destination rectangle */ + INT yDst; + INT dxDst; + INT dyDst; + + INT xSrc; /* source rectangle */ + INT ySrc; + INT dxSrc; + INT dySrc; +} ICDECOMPRESSEX; + + +long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); +long VFWAPIV ICDecompressEx(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); +long VFWAPIV ICUniversalEx(HIC hic,int command,LPBITMAPINFOHEADER lpbiFormat,LPBITMAPINFOHEADER lpbi); + + +#define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICDecompressBeginEx(hic, lpbiInput, lpbiOutput) \ + ICUniversalEx( \ + hic, ICM_DECOMPRESSEX_BEGIN, (lpbiInput), \ + (lpbiOutput) \ + ) + +#define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \ + (long) (void*)(lpbiOutput) \ + ) + +#define ICDecompressQueryEx(hic, lpbiInput, lpbiOutput) \ + ICUniversalEx( \ + hic,ICM_DECOMPRESSEX_QUERY, (lpbiInput), \ + (lpbiOutput) \ + ) + +#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \ + ((long)ICSendMessage( \ + hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + )) + +#define ICDecompressGetFormatSize(hic, lpbi) \ + ICDecompressGetFormat(hic, lpbi, NULL) + +#define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \ + ICSendMessage( \ + hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \ + (long)(void*)(lpbiOutput) \ + ) + +#define ICDecompressSetPalette(hic,lpbiPalette) \ + ICSendMessage( \ + hic,ICM_DECOMPRESS_SET_PALETTE, \ + (long)(void*)(lpbiPalette),0 \ + ) + +#define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0) +#define ICDecompressEndEx(hic) ICSendMessage(hic,ICM_DECOMPRESSEX_END, 0, 0) + +#define ICDRAW_QUERY 0x00000001L /* test for support */ +#define ICDRAW_FULLSCREEN 0x00000002L /* draw to full screen */ +#define ICDRAW_HDC 0x00000004L /* draw to a HDC/HWND */ + + +WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo); +LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb); +HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode); +//HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler); + +LRESULT VFWAPI ICClose(HIC hic); +LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2); +//HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags); + +int VFWAPI ICDoSomething(void); + +long VFWAPIV ICDrawBegin( + HIC hic, + long dwFlags,/* flags */ + HPALETTE hpal, /* palette to draw with */ + HWND hwnd, /* window to draw to */ + HDC hdc, /* HDC to draw to */ + INT xDst, /* destination rectangle */ + INT yDst, + INT dxDst, + INT dyDst, + LPBITMAPINFOHEADER lpbi, /* format of frame to draw */ + INT xSrc, /* source rectangle */ + INT ySrc, + INT dxSrc, + INT dySrc, + long dwRate, /* frames/second = (dwRate/dwScale) */ + long dwScale +); + +/* as passed to ICM_DRAW_BEGIN (FIXME: correct only for Win32?) */ +typedef struct { + long dwFlags; + HPALETTE hpal; + HWND hwnd; + HDC hdc; + INT xDst; + INT yDst; + INT dxDst; + INT dyDst; + LPBITMAPINFOHEADER lpbi; + INT xSrc; + INT ySrc; + INT dxSrc; + INT dySrc; + long dwRate; + long dwScale; +} ICDRAWBEGIN; + +#define ICDRAW_HURRYUP 0x80000000L /* don't draw just buffer (hurry up!) */ +#define ICDRAW_UPDATE 0x40000000L /* don't draw just update screen */ +#define ICDRAW_PREROLL 0x20000000L /* this frame is before real start */ +#define ICDRAW_NULLFRAME 0x10000000L /* repeat last frame */ +#define ICDRAW_NOTKEYFRAME 0x08000000L /* this frame is not a key frame */ + +typedef struct { + long dwFlags; + void* lpFormat; + void* lpData; + long cbData; + long lTime; +} ICDRAW; + +long VFWAPIV ICDraw(HIC hic,long dwFlags,void* lpFormat,void* lpData,long cbData,long lTime); + + +#define AVIGETFRAMEF_BESTDISPLAYFMT 1 + +typedef struct _AVISTREAMINFOA { + long fccType; + long fccHandler; + long dwFlags; /* AVIIF_* */ + long dwCaps; + short wPriority; + short wLanguage; + long dwScale; + long dwRate; /* dwRate / dwScale == samples/second */ + long dwStart; + long dwLength; /* In units above... */ + long dwInitialFrames; + long dwSuggestedBufferSize; + long dwQuality; + long dwSampleSize; + RECT rcFrame; + long dwEditCount; + long dwFormatChangeCount; + char szName[64]; +} AVISTREAMINFOA, * LPAVISTREAMINFOA, *PAVISTREAMINFOA; + +typedef struct _AVISTREAMINFOW { + long fccType; + long fccHandler; + long dwFlags; + long dwCaps; + short wPriority; + short wLanguage; + long dwScale; + long dwRate; /* dwRate / dwScale == samples/second */ + long dwStart; + long dwLength; /* In units above... */ + long dwInitialFrames; + long dwSuggestedBufferSize; + long dwQuality; + long dwSampleSize; + RECT rcFrame; + long dwEditCount; + long dwFormatChangeCount; + short szName[64]; +} AVISTREAMINFOW, * LPAVISTREAMINFOW, *PAVISTREAMINFOW; +DECL_WINELIB_TYPE_AW(AVISTREAMINFO) +DECL_WINELIB_TYPE_AW(LPAVISTREAMINFO) +DECL_WINELIB_TYPE_AW(PAVISTREAMINFO) + +#define AVISTREAMINFO_DISABLED 0x00000001 +#define AVISTREAMINFO_FORMATCHANGES 0x00010000 + +/* AVIFILEINFO.dwFlags */ +#define AVIFILEINFO_HASINDEX 0x00000010 +#define AVIFILEINFO_MUSTUSEINDEX 0x00000020 +#define AVIFILEINFO_ISINTERLEAVED 0x00000100 +#define AVIFILEINFO_WASCAPTUREFILE 0x00010000 +#define AVIFILEINFO_COPYRIGHTED 0x00020000 + +/* AVIFILEINFO.dwCaps */ +#define AVIFILECAPS_CANREAD 0x00000001 +#define AVIFILECAPS_CANWRITE 0x00000002 +#define AVIFILECAPS_ALLKEYFRAMES 0x00000010 +#define AVIFILECAPS_NOCOMPRESSION 0x00000020 + +typedef struct _AVIFILEINFOW { + long dwMaxBytesPerSec; + long dwFlags; + long dwCaps; + long dwStreams; + long dwSuggestedBufferSize; + long dwWidth; + long dwHeight; + long dwScale; + long dwRate; + long dwLength; + long dwEditCount; + short szFileType[64]; +} AVIFILEINFOW, * LPAVIFILEINFOW, *PAVIFILEINFOW; + +typedef struct _AVIFILEINFOA { + long dwMaxBytesPerSec; + long dwFlags; + long dwCaps; + long dwStreams; + long dwSuggestedBufferSize; + long dwWidth; + long dwHeight; + long dwScale; + long dwRate; + long dwLength; + long dwEditCount; + char szFileType[64]; +} AVIFILEINFOA, * LPAVIFILEINFOA, *PAVIFILEINFOA; + +DECL_WINELIB_TYPE_AW(AVIFILEINFO) +DECL_WINELIB_TYPE_AW(PAVIFILEINFO) +DECL_WINELIB_TYPE_AW(LPAVIFILEINFO) + +/* AVICOMPRESSOPTIONS.dwFlags. determines presence of fields in below struct */ +#define AVICOMPRESSF_INTERLEAVE 0x00000001 +#define AVICOMPRESSF_DATARATE 0x00000002 +#define AVICOMPRESSF_KEYFRAMES 0x00000004 +#define AVICOMPRESSF_VALID 0x00000008 + +typedef struct { + long fccType; /* stream type, for consistency */ + long fccHandler; /* compressor */ + long dwKeyFrameEvery; /* keyframe rate */ + long dwQuality; /* compress quality 0-10,000 */ + long dwBytesPerSecond; /* unsigned chars per second */ + long dwFlags; /* flags... see below */ + void* lpFormat; /* save format */ + long cbFormat; + void* lpParms; /* compressor options */ + long cbParms; + long dwInterleaveEvery; /* for non-video streams only */ +} AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS; + + + +typedef struct { + long cbSize; // set to sizeof(COMPVARS) before + // calling ICCompressorChoose + long dwFlags; // see below... + HIC hic; // HIC of chosen compressor + long fccType; // basically ICTYPE_VIDEO + long fccHandler; // handler of chosen compressor or + // "" or "DIB " + LPBITMAPINFO lpbiIn; // input format + LPBITMAPINFO lpbiOut; // output format - will compress to this + void* lpBitsOut; + void* lpBitsPrev; + long lFrame; + long lKey; // key frames how often? + long lDataRate; // desired data rate KB/Sec + long lQ; // desired quality + long lKeyCount; + void* lpState; // state of compressor + long cbState; // size of the state +} COMPVARS, *PCOMPVARS; + +// FLAGS for dwFlags element of COMPVARS structure: + + +#define AVIERR_OK 0 +#define MAKE_AVIERR(error) MAKE_SCODE(SEVERITY_ERROR,FACILITY_ITF,0x4000+error) + +#define AVIERR_UNSUPPORTED MAKE_AVIERR(101) +#define AVIERR_BADFORMAT MAKE_AVIERR(102) +#define AVIERR_MEMORY MAKE_AVIERR(103) +#define AVIERR_INTERNAL MAKE_AVIERR(104) +#define AVIERR_BADFLAGS MAKE_AVIERR(105) +#define AVIERR_BADPARAM MAKE_AVIERR(106) +#define AVIERR_BADSIZE MAKE_AVIERR(107) +#define AVIERR_BADHANDLE MAKE_AVIERR(108) +#define AVIERR_FILEREAD MAKE_AVIERR(109) +#define AVIERR_FILEWRITE MAKE_AVIERR(110) +#define AVIERR_FILEOPEN MAKE_AVIERR(111) +#define AVIERR_COMPRESSOR MAKE_AVIERR(112) +#define AVIERR_NOCOMPRESSOR MAKE_AVIERR(113) +#define AVIERR_READONLY MAKE_AVIERR(114) +#define AVIERR_NODATA MAKE_AVIERR(115) +#define AVIERR_BUFFERTOOSMALL MAKE_AVIERR(116) +#define AVIERR_CANTCOMPRESS MAKE_AVIERR(117) +#define AVIERR_USERABORT MAKE_AVIERR(198) +#define AVIERR_ERROR MAKE_AVIERR(199) + +#ifdef __cplusplus +} +#endif +#endif /* __WINE_VFW_H */ diff --git a/linphone/win32acm/wine/winbase.h b/linphone/win32acm/wine/winbase.h new file mode 100644 index 000000000..8746da891 --- /dev/null +++ b/linphone/win32acm/wine/winbase.h @@ -0,0 +1,1791 @@ +#ifndef __WINE_WINBASE_H +#define __WINE_WINBASE_H + +#include "basetsd.h" +#include "winnt.h" +#include "winestring.h" +#include "pshpack1.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct tagCOORD { + INT16 x; + INT16 y; +} COORD, *LPCOORD; + + + /* Windows Exit Procedure flag values */ +#define WEP_FREE_DLL 0 +#define WEP_SYSTEM_EXIT 1 + +typedef DWORD CALLBACK (*LPTHREAD_START_ROUTINE)(LPVOID); + +#define EXCEPTION_DEBUG_EVENT 1 +#define CREATE_THREAD_DEBUG_EVENT 2 +#define CREATE_PROCESS_DEBUG_EVENT 3 +#define EXIT_THREAD_DEBUG_EVENT 4 +#define EXIT_PROCESS_DEBUG_EVENT 5 +#define LOAD_DLL_DEBUG_EVENT 6 +#define UNLOAD_DLL_DEBUG_EVENT 7 +#define OUTPUT_DEBUG_STRING_EVENT 8 +#define RIP_EVENT 9 + +typedef struct _EXCEPTION_DEBUG_INFO { + EXCEPTION_RECORD ExceptionRecord; + DWORD dwFirstChance; +} EXCEPTION_DEBUG_INFO; + +typedef struct _CREATE_THREAD_DEBUG_INFO { + HANDLE hThread; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; +} CREATE_THREAD_DEBUG_INFO; + +typedef struct _CREATE_PROCESS_DEBUG_INFO { + HANDLE hFile; + HANDLE hProcess; + HANDLE hThread; + LPVOID lpBaseOfImage; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; + LPVOID lpImageName; + WORD fUnicode; +} CREATE_PROCESS_DEBUG_INFO; + +typedef struct _EXIT_THREAD_DEBUG_INFO { + DWORD dwExitCode; +} EXIT_THREAD_DEBUG_INFO; + +typedef struct _EXIT_PROCESS_DEBUG_INFO { + DWORD dwExitCode; +} EXIT_PROCESS_DEBUG_INFO; + +typedef struct _LOAD_DLL_DEBUG_INFO { + HANDLE hFile; + LPVOID lpBaseOfDll; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpImageName; + WORD fUnicode; +} LOAD_DLL_DEBUG_INFO; + +typedef struct _UNLOAD_DLL_DEBUG_INFO { + LPVOID lpBaseOfDll; +} UNLOAD_DLL_DEBUG_INFO; + +typedef struct _OUTPUT_DEBUG_STRING_INFO { + LPSTR lpDebugStringData; + WORD fUnicode; + WORD nDebugStringLength; +} OUTPUT_DEBUG_STRING_INFO; + +typedef struct _RIP_INFO { + DWORD dwError; + DWORD dwType; +} RIP_INFO; + +typedef struct _DEBUG_EVENT { + DWORD dwDebugEventCode; + DWORD dwProcessId; + DWORD dwThreadId; + union { + EXCEPTION_DEBUG_INFO Exception; + CREATE_THREAD_DEBUG_INFO CreateThread; + CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; + EXIT_THREAD_DEBUG_INFO ExitThread; + EXIT_PROCESS_DEBUG_INFO ExitProcess; + LOAD_DLL_DEBUG_INFO LoadDll; + UNLOAD_DLL_DEBUG_INFO UnloadDll; + OUTPUT_DEBUG_STRING_INFO DebugString; + RIP_INFO RipInfo; + } u; +} DEBUG_EVENT, *LPDEBUG_EVENT; + +#define OFS_MAXPATHNAME 128 +typedef struct +{ + BYTE cBytes; + BYTE fFixedDisk; + WORD nErrCode; + BYTE reserved[4]; + BYTE szPathName[OFS_MAXPATHNAME]; +} OFSTRUCT, *LPOFSTRUCT; + +#define OF_READ 0x0000 +#define OF_WRITE 0x0001 +#define OF_READWRITE 0x0002 +#define OF_SHARE_COMPAT 0x0000 +#define OF_SHARE_EXCLUSIVE 0x0010 +#define OF_SHARE_DENY_WRITE 0x0020 +#define OF_SHARE_DENY_READ 0x0030 +#define OF_SHARE_DENY_NONE 0x0040 +#define OF_PARSE 0x0100 +#define OF_DELETE 0x0200 +#define OF_VERIFY 0x0400 /* Used with OF_REOPEN */ +#define OF_SEARCH 0x0400 /* Used without OF_REOPEN */ +#define OF_CANCEL 0x0800 +#define OF_CREATE 0x1000 +#define OF_PROMPT 0x2000 +#define OF_EXIST 0x4000 +#define OF_REOPEN 0x8000 + +/* SetErrorMode values */ +#define SEM_FAILCRITICALERRORS 0x0001 +#define SEM_NOGPFAULTERRORBOX 0x0002 +#define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 +#define SEM_NOOPENFILEERRORBOX 0x8000 + +/* CopyFileEx flags */ +#define COPY_FILE_FAIL_IF_EXISTS 0x00000001 +#define COPY_FILE_RESTARTABLE 0x00000002 +#define COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x00000004 + +/* GetTempFileName() Flags */ +#define TF_FORCEDRIVE 0x80 + +#define DRIVE_CANNOTDETERMINE 0 +#define DRIVE_DOESNOTEXIST 1 +#define DRIVE_REMOVABLE 2 +#define DRIVE_FIXED 3 +#define DRIVE_REMOTE 4 +/* Win32 additions */ +#define DRIVE_CDROM 5 +#define DRIVE_RAMDISK 6 + +/* The security attributes structure */ +typedef struct _SECURITY_ATTRIBUTES +{ + DWORD nLength; + LPVOID lpSecurityDescriptor; + WIN_BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + +#ifndef _FILETIME_ +#define _FILETIME_ +/* 64 bit number of 100 nanoseconds intervals since January 1, 1601 */ +typedef struct +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *LPFILETIME; +#endif /* _FILETIME_ */ + +/* Find* structures */ +typedef struct +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + CHAR cFileName[260]; + CHAR cAlternateFileName[14]; +} WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; + +typedef struct +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[260]; + WCHAR cAlternateFileName[14]; +} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + +DECL_WINELIB_TYPE_AW(WIN32_FIND_DATA) +DECL_WINELIB_TYPE_AW(LPWIN32_FIND_DATA) + +typedef struct +{ + LPVOID lpData; + DWORD cbData; + BYTE cbOverhead; + BYTE iRegionIndex; + WORD wFlags; + union { + struct { + HANDLE hMem; + DWORD dwReserved[3]; + } Block; + struct { + DWORD dwCommittedSize; + DWORD dwUnCommittedSize; + LPVOID lpFirstBlock; + LPVOID lpLastBlock; + } Region; + } Foo; +} PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY; + +#define PROCESS_HEAP_REGION 0x0001 +#define PROCESS_HEAP_UNCOMMITTED_RANGE 0x0002 +#define PROCESS_HEAP_ENTRY_BUSY 0x0004 +#define PROCESS_HEAP_ENTRY_MOVEABLE 0x0010 +#define PROCESS_HEAP_ENTRY_DDESHARE 0x0020 + +#define INVALID_HANDLE_VALUE16 ((HANDLE16) -1) +#define INVALID_HANDLE_VALUE ((HANDLE) -1) + +#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) + +/* comm */ + +#define CBR_110 0xFF10 +#define CBR_300 0xFF11 +#define CBR_600 0xFF12 +#define CBR_1200 0xFF13 +#define CBR_2400 0xFF14 +#define CBR_4800 0xFF15 +#define CBR_9600 0xFF16 +#define CBR_14400 0xFF17 +#define CBR_19200 0xFF18 +#define CBR_38400 0xFF1B +#define CBR_56000 0xFF1F +#define CBR_128000 0xFF23 +#define CBR_256000 0xFF27 + +#define NOPARITY 0 +#define ODDPARITY 1 +#define EVENPARITY 2 +#define MARKPARITY 3 +#define SPACEPARITY 4 +#define ONESTOPBIT 0 +#define ONE5STOPBITS 1 +#define TWOSTOPBITS 2 + +#define IGNORE 0 +#define INFINITE16 0xFFFF +#define INFINITE 0xFFFFFFFF + +#define CE_RXOVER 0x0001 +#define CE_OVERRUN 0x0002 +#define CE_RXPARITY 0x0004 +#define CE_FRAME 0x0008 +#define CE_BREAK 0x0010 +#define CE_CTSTO 0x0020 +#define CE_DSRTO 0x0040 +#define CE_RLSDTO 0x0080 +#define CE_TXFULL 0x0100 +#define CE_PTO 0x0200 +#define CE_IOE 0x0400 +#define CE_DNS 0x0800 +#define CE_OOP 0x1000 +#define CE_MODE 0x8000 + +#define IE_BADID -1 +#define IE_OPEN -2 +#define IE_NOPEN -3 +#define IE_MEMORY -4 +#define IE_DEFAULT -5 +#define IE_HARDWARE -10 +#define IE_BYTESIZE -11 +#define IE_BAUDRATE -12 + +#define EV_RXCHAR 0x0001 +#define EV_RXFLAG 0x0002 +#define EV_TXEMPTY 0x0004 +#define EV_CTS 0x0008 +#define EV_DSR 0x0010 +#define EV_RLSD 0x0020 +#define EV_BREAK 0x0040 +#define EV_ERR 0x0080 +#define EV_RING 0x0100 +#define EV_PERR 0x0200 +#define EV_CTSS 0x0400 +#define EV_DSRS 0x0800 +#define EV_RLSDS 0x1000 +#define EV_RINGTE 0x2000 +#define EV_RingTe EV_RINGTE + +#define SETXOFF 1 +#define SETXON 2 +#define SETRTS 3 +#define CLRRTS 4 +#define SETDTR 5 +#define CLRDTR 6 +#define RESETDEV 7 +#define SETBREAK 8 +#define CLRBREAK 9 + +#define GETBASEIRQ 10 + +/* Purge functions for Comm Port */ +#define PURGE_TXABORT 0x0001 /* Kill the pending/current writes to the + comm port */ +#define PURGE_RXABORT 0x0002 /*Kill the pending/current reads to + the comm port */ +#define PURGE_TXCLEAR 0x0004 /* Kill the transmit queue if there*/ +#define PURGE_RXCLEAR 0x0008 /* Kill the typeahead buffer if there*/ + + +/* Modem Status Flags */ +#define MS_CTS_ON ((DWORD)0x0010) +#define MS_DSR_ON ((DWORD)0x0020) +#define MS_RING_ON ((DWORD)0x0040) +#define MS_RLSD_ON ((DWORD)0x0080) + +#define RTS_CONTROL_DISABLE 0 +#define RTS_CONTROL_ENABLE 1 +#define RTS_CONTROL_HANDSHAKE 2 +#define RTS_CONTROL_TOGGLE 3 + +#define DTR_CONTROL_DISABLE 0 +#define DTR_CONTROL_ENABLE 1 +#define DTR_CONTROL_HANDSHAKE 2 + +#define CSTF_CTSHOLD 0x01 +#define CSTF_DSRHOLD 0x02 +#define CSTF_RLSDHOLD 0x04 +#define CSTF_XOFFHOLD 0x08 +#define CSTF_XOFFSENT 0x10 +#define CSTF_EOF 0x20 +#define CSTF_TXIM 0x40 + +#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i))) +#define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i))) +#define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE) + +/* Predefined resource types */ +#define RT_CURSORA MAKEINTRESOURCEA(1) +#define RT_CURSORW MAKEINTRESOURCEW(1) +#define RT_CURSOR WINELIB_NAME_AW(RT_CURSOR) +#define RT_BITMAPA MAKEINTRESOURCEA(2) +#define RT_BITMAPW MAKEINTRESOURCEW(2) +#define RT_BITMAP WINELIB_NAME_AW(RT_BITMAP) +#define RT_ICONA MAKEINTRESOURCEA(3) +#define RT_ICONW MAKEINTRESOURCEW(3) +#define RT_ICON WINELIB_NAME_AW(RT_ICON) +#define RT_MENUA MAKEINTRESOURCEA(4) +#define RT_MENUW MAKEINTRESOURCEW(4) +#define RT_MENU WINELIB_NAME_AW(RT_MENU) +#define RT_DIALOGA MAKEINTRESOURCEA(5) +#define RT_DIALOGW MAKEINTRESOURCEW(5) +#define RT_DIALOG WINELIB_NAME_AW(RT_DIALOG) +#define RT_STRINGA MAKEINTRESOURCEA(6) +#define RT_STRINGW MAKEINTRESOURCEW(6) +#define RT_STRING WINELIB_NAME_AW(RT_STRING) +#define RT_FONTDIRA MAKEINTRESOURCEA(7) +#define RT_FONTDIRW MAKEINTRESOURCEW(7) +#define RT_FONTDIR WINELIB_NAME_AW(RT_FONTDIR) +#define RT_FONTA MAKEINTRESOURCEA(8) +#define RT_FONTW MAKEINTRESOURCEW(8) +#define RT_FONT WINELIB_NAME_AW(RT_FONT) +#define RT_ACCELERATORA MAKEINTRESOURCEA(9) +#define RT_ACCELERATORW MAKEINTRESOURCEW(9) +#define RT_ACCELERATOR WINELIB_NAME_AW(RT_ACCELERATOR) +#define RT_RCDATAA MAKEINTRESOURCEA(10) +#define RT_RCDATAW MAKEINTRESOURCEW(10) +#define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA) +#define RT_MESSAGELISTA MAKEINTRESOURCEA(11) +#define RT_MESSAGELISTW MAKEINTRESOURCEW(11) +#define RT_MESSAGELIST WINELIB_NAME_AW(RT_MESSAGELIST) +#define RT_GROUP_CURSORA MAKEINTRESOURCEA(12) +#define RT_GROUP_CURSORW MAKEINTRESOURCEW(12) +#define RT_GROUP_CURSOR WINELIB_NAME_AW(RT_GROUP_CURSOR) +#define RT_GROUP_ICONA MAKEINTRESOURCEA(14) +#define RT_GROUP_ICONW MAKEINTRESOURCEW(14) +#define RT_GROUP_ICON WINELIB_NAME_AW(RT_GROUP_ICON) + + +#define LMEM_FIXED 0 +#define LMEM_MOVEABLE 0x0002 +#define LMEM_NOCOMPACT 0x0010 +#define LMEM_NODISCARD 0x0020 +#define LMEM_ZEROINIT 0x0040 +#define LMEM_MODIFY 0x0080 +#define LMEM_DISCARDABLE 0x0F00 +#define LMEM_DISCARDED 0x4000 +#define LMEM_LOCKCOUNT 0x00FF + +#define LPTR (LMEM_FIXED | LMEM_ZEROINIT) + +#define GMEM_FIXED 0x0000 +#define GMEM_MOVEABLE 0x0002 +#define GMEM_NOCOMPACT 0x0010 +#define GMEM_NODISCARD 0x0020 +#define GMEM_ZEROINIT 0x0040 +#define GMEM_MODIFY 0x0080 +#define GMEM_DISCARDABLE 0x0100 +#define GMEM_NOT_BANKED 0x1000 +#define GMEM_SHARE 0x2000 +#define GMEM_DDESHARE 0x2000 +#define GMEM_NOTIFY 0x4000 +#define GMEM_LOWER GMEM_NOT_BANKED +#define GMEM_DISCARDED 0x4000 +#define GMEM_LOCKCOUNT 0x00ff +#define GMEM_INVALID_HANDLE 0x8000 + +#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT) +#define GPTR (GMEM_FIXED | GMEM_ZEROINIT) + + +typedef struct tagMEMORYSTATUS +{ + DWORD dwLength; + DWORD dwMemoryLoad; + DWORD dwTotalPhys; + DWORD dwAvailPhys; + DWORD dwTotalPageFile; + DWORD dwAvailPageFile; + DWORD dwTotalVirtual; + DWORD dwAvailVirtual; +} MEMORYSTATUS, *LPMEMORYSTATUS; + + +#ifndef NOLOGERROR + +/* LogParamError and LogError values */ + +/* Error modifier bits */ +#define ERR_WARNING 0x8000 +#define ERR_PARAM 0x4000 + +#define ERR_SIZE_MASK 0x3000 +#define ERR_BYTE 0x1000 +#define ERR_WORD 0x2000 +#define ERR_DWORD 0x3000 + +/* LogParamError() values */ + +/* Generic parameter values */ +#define ERR_BAD_VALUE 0x6001 +#define ERR_BAD_FLAGS 0x6002 +#define ERR_BAD_INDEX 0x6003 +#define ERR_BAD_DVALUE 0x7004 +#define ERR_BAD_DFLAGS 0x7005 +#define ERR_BAD_DINDEX 0x7006 +#define ERR_BAD_PTR 0x7007 +#define ERR_BAD_FUNC_PTR 0x7008 +#define ERR_BAD_SELECTOR 0x6009 +#define ERR_BAD_STRING_PTR 0x700a +#define ERR_BAD_HANDLE 0x600b + +/* KERNEL parameter errors */ +#define ERR_BAD_HINSTANCE 0x6020 +#define ERR_BAD_HMODULE 0x6021 +#define ERR_BAD_GLOBAL_HANDLE 0x6022 +#define ERR_BAD_LOCAL_HANDLE 0x6023 +#define ERR_BAD_ATOM 0x6024 +#define ERR_BAD_HFILE 0x6025 + +/* USER parameter errors */ +#define ERR_BAD_HWND 0x6040 +#define ERR_BAD_HMENU 0x6041 +#define ERR_BAD_HCURSOR 0x6042 +#define ERR_BAD_HICON 0x6043 +#define ERR_BAD_HDWP 0x6044 +#define ERR_BAD_CID 0x6045 +#define ERR_BAD_HDRVR 0x6046 + +/* GDI parameter errors */ +#define ERR_BAD_COORDS 0x7060 +#define ERR_BAD_GDI_OBJECT 0x6061 +#define ERR_BAD_HDC 0x6062 +#define ERR_BAD_HPEN 0x6063 +#define ERR_BAD_HFONT 0x6064 +#define ERR_BAD_HBRUSH 0x6065 +#define ERR_BAD_HBITMAP 0x6066 +#define ERR_BAD_HRGN 0x6067 +#define ERR_BAD_HPALETTE 0x6068 +#define ERR_BAD_HMETAFILE 0x6069 + + +/* LogError() values */ + +/* KERNEL errors */ +#define ERR_GALLOC 0x0001 +#define ERR_GREALLOC 0x0002 +#define ERR_GLOCK 0x0003 +#define ERR_LALLOC 0x0004 +#define ERR_LREALLOC 0x0005 +#define ERR_LLOCK 0x0006 +#define ERR_ALLOCRES 0x0007 +#define ERR_LOCKRES 0x0008 +#define ERR_LOADMODULE 0x0009 + +/* USER errors */ +#define ERR_CREATEDLG 0x0040 +#define ERR_CREATEDLG2 0x0041 +#define ERR_REGISTERCLASS 0x0042 +#define ERR_DCBUSY 0x0043 +#define ERR_CREATEWND 0x0044 +#define ERR_STRUCEXTRA 0x0045 +#define ERR_LOADSTR 0x0046 +#define ERR_LOADMENU 0x0047 +#define ERR_NESTEDBEGINPAINT 0x0048 +#define ERR_BADINDEX 0x0049 +#define ERR_CREATEMENU 0x004a + +/* GDI errors */ +#define ERR_CREATEDC 0x0080 +#define ERR_CREATEMETA 0x0081 +#define ERR_DELOBJSELECTED 0x0082 +#define ERR_SELBITMAP 0x0083 + + + +/* Debugging support (DEBUG SYSTEM ONLY) */ +typedef struct +{ + UINT16 flags; + DWORD dwOptions WINE_PACKED; + DWORD dwFilter WINE_PACKED; + CHAR achAllocModule[8] WINE_PACKED; + DWORD dwAllocBreak WINE_PACKED; + DWORD dwAllocCount WINE_PACKED; +} WINDEBUGINFO, *LPWINDEBUGINFO; + +/* WINDEBUGINFO flags values */ +#define WDI_OPTIONS 0x0001 +#define WDI_FILTER 0x0002 +#define WDI_ALLOCBREAK 0x0004 + +/* dwOptions values */ +#define DBO_CHECKHEAP 0x0001 +#define DBO_BUFFERFILL 0x0004 +#define DBO_DISABLEGPTRAPPING 0x0010 +#define DBO_CHECKFREE 0x0020 + +#define DBO_SILENT 0x8000 + +#define DBO_TRACEBREAK 0x2000 +#define DBO_WARNINGBREAK 0x1000 +#define DBO_NOERRORBREAK 0x0800 +#define DBO_NOFATALBREAK 0x0400 +#define DBO_INT3BREAK 0x0100 + +/* DebugOutput flags values */ +#define DBF_TRACE 0x0000 +#define DBF_WARNING 0x4000 +#define DBF_ERROR 0x8000 +#define DBF_FATAL 0xc000 + +/* dwFilter values */ +#define DBF_KERNEL 0x1000 +#define DBF_KRN_MEMMAN 0x0001 +#define DBF_KRN_LOADMODULE 0x0002 +#define DBF_KRN_SEGMENTLOAD 0x0004 +#define DBF_USER 0x0800 +#define DBF_GDI 0x0400 +#define DBF_MMSYSTEM 0x0040 +#define DBF_PENWIN 0x0020 +#define DBF_APPLICATION 0x0008 +#define DBF_DRIVER 0x0010 + +#endif /* NOLOGERROR */ + +typedef struct { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} SYSTEMTIME, *LPSYSTEMTIME; + +/* The 'overlapped' data structure used by async I/O functions. + */ +typedef struct { + DWORD Internal; + DWORD InternalHigh; + DWORD Offset; + DWORD OffsetHigh; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; + +/* Process startup information. + */ + +/* STARTUPINFO.dwFlags */ +#define STARTF_USESHOWWINDOW 0x00000001 +#define STARTF_USESIZE 0x00000002 +#define STARTF_USEPOSITION 0x00000004 +#define STARTF_USECOUNTCHARS 0x00000008 +#define STARTF_USEFILLATTRIBUTE 0x00000010 +#define STARTF_RUNFULLSCREEN 0x00000020 +#define STARTF_FORCEONFEEDBACK 0x00000040 +#define STARTF_FORCEOFFFEEDBACK 0x00000080 +#define STARTF_USESTDHANDLES 0x00000100 +#define STARTF_USEHOTKEY 0x00000200 + +typedef struct { + DWORD cb; /* 00: size of struct */ + LPSTR lpReserved; /* 04: */ + LPSTR lpDesktop; /* 08: */ + LPSTR lpTitle; /* 0c: */ + DWORD dwX; /* 10: */ + DWORD dwY; /* 14: */ + DWORD dwXSize; /* 18: */ + DWORD dwYSize; /* 1c: */ + DWORD dwXCountChars; /* 20: */ + DWORD dwYCountChars; /* 24: */ + DWORD dwFillAttribute; /* 28: */ + DWORD dwFlags; /* 2c: */ + WORD wShowWindow; /* 30: */ + WORD cbReserved2; /* 32: */ + BYTE *lpReserved2; /* 34: */ + HANDLE hStdInput; /* 38: */ + HANDLE hStdOutput; /* 3c: */ + HANDLE hStdError; /* 40: */ +} STARTUPINFOA, *LPSTARTUPINFOA; + +typedef struct { + DWORD cb; + LPWSTR lpReserved; + LPWSTR lpDesktop; + LPWSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} STARTUPINFOW, *LPSTARTUPINFOW; + +DECL_WINELIB_TYPE_AW(STARTUPINFO) +DECL_WINELIB_TYPE_AW(LPSTARTUPINFO) + +typedef struct { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; +} PROCESS_INFORMATION,*LPPROCESS_INFORMATION; + +typedef struct { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; +} TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + +#define TIME_ZONE_ID_UNKNOWN 0 +#define TIME_ZONE_ID_STANDARD 1 +#define TIME_ZONE_ID_DAYLIGHT 2 + +/* CreateProcess: dwCreationFlag values + */ +#define DEBUG_PROCESS 0x00000001 +#define DEBUG_ONLY_THIS_PROCESS 0x00000002 +#define CREATE_SUSPENDED 0x00000004 +#define DETACHED_PROCESS 0x00000008 +#define CREATE_NEW_CONSOLE 0x00000010 +#define NORMAL_PRIORITY_CLASS 0x00000020 +#define IDLE_PRIORITY_CLASS 0x00000040 +#define HIGH_PRIORITY_CLASS 0x00000080 +#define REALTIME_PRIORITY_CLASS 0x00000100 +#define CREATE_NEW_PROCESS_GROUP 0x00000200 +#define CREATE_UNICODE_ENVIRONMENT 0x00000400 +#define CREATE_SEPARATE_WOW_VDM 0x00000800 +#define CREATE_SHARED_WOW_VDM 0x00001000 +#define CREATE_DEFAULT_ERROR_MODE 0x04000000 +#define CREATE_NO_WINDOW 0x08000000 +#define PROFILE_USER 0x10000000 +#define PROFILE_KERNEL 0x20000000 +#define PROFILE_SERVER 0x40000000 + + +/* File object type definitions + */ +#define FILE_TYPE_UNKNOWN 0 +#define FILE_TYPE_DISK 1 +#define FILE_TYPE_CHAR 2 +#define FILE_TYPE_PIPE 3 +#define FILE_TYPE_REMOTE 32768 + +/* File creation flags + */ +#define FILE_FLAG_WRITE_THROUGH 0x80000000UL +#define FILE_FLAG_OVERLAPPED 0x40000000L +#define FILE_FLAG_NO_BUFFERING 0x20000000L +#define FILE_FLAG_RANDOM_ACCESS 0x10000000L +#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L +#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L +#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L +#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + +/* Standard handle identifiers + */ +#define STD_INPUT_HANDLE ((DWORD) -10) +#define STD_OUTPUT_HANDLE ((DWORD) -11) +#define STD_ERROR_HANDLE ((DWORD) -12) + +typedef struct +{ + int dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + int dwVolumeSerialNumber; + int nFileSizeHigh; + int nFileSizeLow; + int nNumberOfLinks; + int nFileIndexHigh; + int nFileIndexLow; +} BY_HANDLE_FILE_INFORMATION ; + + +typedef struct _SYSTEM_POWER_STATUS +{ + WIN_BOOL16 ACLineStatus; + BYTE BatteryFlag; + BYTE BatteryLifePercent; + BYTE reserved; + DWORD BatteryLifeTime; + DWORD BatteryFullLifeTime; +} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS; + +typedef struct _MEMORY_BASIC_INFORMATION +{ + LPVOID BaseAddress; + LPVOID AllocationBase; + DWORD AllocationProtect; + DWORD RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; +} MEMORY_BASIC_INFORMATION,*LPMEMORY_BASIC_INFORMATION; + + +typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCA)(LPSTR); +typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCW)(LPWSTR); +DECL_WINELIB_TYPE_AW(CODEPAGE_ENUMPROC) +typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCA)(LPSTR); +typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCW)(LPWSTR); +DECL_WINELIB_TYPE_AW(LOCALE_ENUMPROC) + +typedef struct tagSYSTEM_INFO +{ + union { + DWORD dwOemId; /* Obsolete field - do not use */ + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + LPVOID lpMinimumApplicationAddress; + LPVOID lpMaximumApplicationAddress; + DWORD dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; +} SYSTEM_INFO, *LPSYSTEM_INFO; + +/* {G,S}etPriorityClass */ +#define NORMAL_PRIORITY_CLASS 0x00000020 +#define IDLE_PRIORITY_CLASS 0x00000040 +#define HIGH_PRIORITY_CLASS 0x00000080 +#define REALTIME_PRIORITY_CLASS 0x00000100 + +typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCA)(HMODULE,LPSTR,LONG); +typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCW)(HMODULE,LPWSTR,LONG); +typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCA)(HMODULE,LPCSTR,LPSTR,LONG); +typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCW)(HMODULE,LPCWSTR,LPWSTR,LONG); +typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCA)(HMODULE,LPCSTR,LPCSTR,WORD,LONG); +typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCW)(HMODULE,LPCWSTR,LPCWSTR,WORD,LONG); + +DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC) +DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC) +DECL_WINELIB_TYPE_AW(ENUMRESLANGPROC) + +/* flags that can be passed to LoadLibraryEx */ +#define DONT_RESOLVE_DLL_REFERENCES 0x00000001 +#define LOAD_LIBRARY_AS_DATAFILE 0x00000002 +#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 + +/* ifdef _x86_ ... */ +typedef struct _LDT_ENTRY { + WORD LimitLow; + WORD BaseLow; + union { + struct { + BYTE BaseMid; + BYTE Flags1;/*Declare as bytes to avoid alignment problems */ + BYTE Flags2; + BYTE BaseHi; + } Bytes; + struct { + unsigned BaseMid : 8; + unsigned Type : 5; + unsigned Dpl : 2; + unsigned Pres : 1; + unsigned LimitHi : 4; + unsigned Sys : 1; + unsigned Reserved_0 : 1; + unsigned Default_Big : 1; + unsigned Granularity : 1; + unsigned BaseHi : 8; + } Bits; + } HighWord; +} LDT_ENTRY, *LPLDT_ENTRY; + + +typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard +} GET_FILEEX_INFO_LEVELS; + +typedef struct _WIN32_FILE_ATTRIBUTES_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + +typedef struct _DllVersionInfo { + DWORD cbSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformID; +} DLLVERSIONINFO; + +/* + * This one seems to be a Win32 only definition. It also is defined with + * WINAPI instead of CALLBACK in the windows headers. + */ +typedef DWORD WINAPI (*LPPROGRESS_ROUTINE)(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, + LARGE_INTEGER, DWORD, DWORD, HANDLE, + HANDLE, LPVOID); + + +#define WAIT_FAILED 0xffffffff +#define WAIT_OBJECT_0 0 +#define WAIT_ABANDONED STATUS_ABANDONED_WAIT_0 +#define WAIT_ABANDONED_0 STATUS_ABANDONED_WAIT_0 +#define WAIT_IO_COMPLETION STATUS_USER_APC +#define WAIT_TIMEOUT STATUS_TIMEOUT +#define STILL_ACTIVE STATUS_PENDING + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 + +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_PRIVATE 0x00020000 +#define MEM_MAPPED 0x00040000 +#define MEM_TOP_DOWN 0x00100000 +#ifdef __WINE__ +#define MEM_SYSTEM 0x80000000 +#endif + +#define SEC_FILE 0x00800000 +#define SEC_IMAGE 0x01000000 +#define SEC_RESERVE 0x04000000 +#define SEC_COMMIT 0x08000000 +#define SEC_NOCACHE 0x10000000 + +#define FILE_BEGIN 0 +#define FILE_CURRENT 1 +#define FILE_END 2 + +#define FILE_CASE_SENSITIVE_SEARCH 0x00000001 +#define FILE_CASE_PRESERVED_NAMES 0x00000002 +#define FILE_UNICODE_ON_DISK 0x00000004 +#define FILE_PERSISTENT_ACLS 0x00000008 + +#define FILE_MAP_COPY 0x00000001 +#define FILE_MAP_WRITE 0x00000002 +#define FILE_MAP_READ 0x00000004 +#define FILE_MAP_ALL_ACCESS 0x000f001f + +#define MOVEFILE_REPLACE_EXISTING 0x00000001 +#define MOVEFILE_COPY_ALLOWED 0x00000002 +#define MOVEFILE_DELAY_UNTIL_REBOOT 0x00000004 + +#define FS_CASE_SENSITIVE FILE_CASE_SENSITIVE_SEARCH +#define FS_CASE_IS_PRESERVED FILE_CASE_PRESERVED_NAMES +#define FS_UNICODE_STORED_ON_DISK FILE_UNICODE_ON_DISK + +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION +#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT +#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT +#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP +#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED +#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND +#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO +#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT +#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION +#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW +#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK +#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW +#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO +#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW +#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION +#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR +#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION +#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION +#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW +#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION +#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION +#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE +#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT + +/* Wine extension; Windows doesn't have a name for this code */ +#define EXCEPTION_CRITICAL_SECTION_WAIT 0xc0000194 + +#define DUPLICATE_CLOSE_SOURCE 0x00000001 +#define DUPLICATE_SAME_ACCESS 0x00000002 + +#define HANDLE_FLAG_INHERIT 0x00000001 +#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + +#define HINSTANCE_ERROR 32 + +#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN +#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX +#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) +#define THREAD_PRIORITY_ERROR_RETURN (0x7fffffff) +#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT +#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE + +/* Could this type be considered opaque? */ +typedef struct { + LPVOID DebugInfo; + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; + HANDLE LockSemaphore; + DWORD Reserved; +}CRITICAL_SECTION; + +#ifdef __WINE__ +#define CRITICAL_SECTION_INIT { 0, -1, 0, 0, 0, 0 } +#endif + +typedef struct { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; +} OSVERSIONINFO16; + +typedef struct { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; +} OSVERSIONINFOA; + +typedef struct { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; +} OSVERSIONINFOW; + +DECL_WINELIB_TYPE_AW(OSVERSIONINFO) + +#define VER_PLATFORM_WIN32s 0 +#define VER_PLATFORM_WIN32_WINDOWS 1 +#define VER_PLATFORM_WIN32_NT 2 + +typedef struct tagCOMSTAT +{ + DWORD status; + DWORD cbInQue; + DWORD cbOutQue; +} COMSTAT,*LPCOMSTAT; + +typedef struct tagDCB +{ + DWORD DCBlength; + DWORD BaudRate; + unsigned fBinary :1; + unsigned fParity :1; + unsigned fOutxCtsFlow :1; + unsigned fOutxDsrFlow :1; + unsigned fDtrControl :2; + unsigned fDsrSensitivity :1; + unsigned fTXContinueOnXoff :1; + unsigned fOutX :1; + unsigned fInX :1; + unsigned fErrorChar :1; + unsigned fNull :1; + unsigned fRtsControl :2; + unsigned fAbortOnError :1; + unsigned fDummy2 :17; + WORD wReserved; + WORD XonLim; + WORD XoffLim; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + char XonChar; + char XoffChar; + char ErrorChar; + char EofChar; + char EvtChar; +} DCB, *LPDCB; + + + +typedef struct tagCOMMTIMEOUTS { + DWORD ReadIntervalTimeout; + DWORD ReadTotalTimeoutMultiplier; + DWORD ReadTotalTimeoutConstant; + DWORD WriteTotalTimeoutMultiplier; + DWORD WriteTotalTimeoutConstant; +} COMMTIMEOUTS,*LPCOMMTIMEOUTS; + +#include "poppack.h" + +typedef void CALLBACK (*PAPCFUNC)(ULONG_PTR); +typedef void CALLBACK (*PTIMERAPCROUTINE)(LPVOID,DWORD,DWORD); + +WIN_BOOL WINAPI ClearCommError(INT,LPDWORD,LPCOMSTAT); +WIN_BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB); +WIN_BOOL WINAPI BuildCommDCBW(LPCWSTR,LPDCB); +#define BuildCommDCB WINELIB_NAME_AW(BuildCommDCB) +WIN_BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR,LPDCB,LPCOMMTIMEOUTS); +WIN_BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR,LPDCB,LPCOMMTIMEOUTS); +#define BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts) +WIN_BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); +WIN_BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); +WIN_BOOL WINAPI GetCommState(INT,LPDCB); +WIN_BOOL WINAPI SetCommState(INT,LPDCB); +WIN_BOOL WINAPI TransmitCommChar(INT,CHAR); +WIN_BOOL WINAPI SetupComm(HANDLE, DWORD, DWORD); +WIN_BOOL WINAPI GetCommProperties(HANDLE, LPDCB *); + +/*DWORD WINAPI GetVersion( void );*/ +WIN_BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16*); +WIN_BOOL WINAPI GetVersionExA(OSVERSIONINFOA*); +WIN_BOOL WINAPI GetVersionExW(OSVERSIONINFOW*); +#define GetVersionEx WINELIB_NAME_AW(GetVersionEx) + +/*int WinMain(HINSTANCE, HINSTANCE prev, char *cmd, int show);*/ + +void WINAPI DeleteCriticalSection(CRITICAL_SECTION *lpCrit); +void WINAPI EnterCriticalSection(CRITICAL_SECTION *lpCrit); +WIN_BOOL WINAPI TryEnterCriticalSection(CRITICAL_SECTION *lpCrit); +void WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit); +void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit); +void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit); +WIN_BOOL WINAPI GetProcessWorkingSetSize(HANDLE,LPDWORD,LPDWORD); +DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR); +void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD); +WIN_BOOL WINAPI SetProcessWorkingSetSize(HANDLE,DWORD,DWORD); +WIN_BOOL WINAPI TerminateProcess(HANDLE,DWORD); +WIN_BOOL WINAPI TerminateThread(HANDLE,DWORD); +WIN_BOOL WINAPI GetExitCodeThread(HANDLE,LPDWORD); + +/* GetBinaryType return values. + */ + +#define SCS_32BIT_BINARY 0 +#define SCS_DOS_BINARY 1 +#define SCS_WOW_BINARY 2 +#define SCS_PIF_BINARY 3 +#define SCS_POSIX_BINARY 4 +#define SCS_OS216_BINARY 5 + +WIN_BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ); +WIN_BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType ); +#define GetBinaryType WINELIB_NAME_AW(GetBinaryType) + +WIN_BOOL16 WINAPI GetWinDebugInfo16(LPWINDEBUGINFO,UINT16); +WIN_BOOL16 WINAPI SetWinDebugInfo16(LPWINDEBUGINFO); +/* Declarations for functions that exist only in Win32 */ + + +WIN_BOOL WINAPI AttachThreadInput(DWORD,DWORD,WIN_BOOL); +WIN_BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,LPDWORD,LPDWORD,LPWIN_BOOL); +WIN_BOOL WINAPI AdjustTokenPrivileges(HANDLE,WIN_BOOL,LPVOID,DWORD,LPVOID,LPDWORD); +WIN_BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *); +WIN_BOOL WINAPI AllocateLocallyUniqueId(PLUID); +WIN_BOOL WINAPI AllocConsole(void); +WIN_BOOL WINAPI AreFileApisANSI(void); +WIN_BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR); +WIN_BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR); +#define BackupEventLog WINELIB_NAME_AW(BackupEventLog) +WIN_BOOL WINAPI Beep(DWORD,DWORD); +WIN_BOOL WINAPI CancelWaitableTimer(HANDLE); +WIN_BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR); +WIN_BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR); +#define ClearEventLog WINELIB_NAME_AW(ClearEventLog) +WIN_BOOL WINAPI CloseEventLog(HANDLE); +WIN_BOOL WINAPI CloseHandle(HANDLE); +WIN_BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD); +HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc); +WIN_BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,WIN_BOOL); +WIN_BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,WIN_BOOL); +#define CopyFile WINELIB_NAME_AW(CopyFile) +WIN_BOOL WINAPI CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD); +WIN_BOOL WINAPI CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD); +#define CopyFileEx WINELIB_NAME_AW(CopyFileEx) +WIN_BOOL WINAPI CopySid(DWORD,PSID,PSID); +INT WINAPI CompareFileTime(LPFILETIME,LPFILETIME); +HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCSTR); +HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCWSTR); +#define CreateEvent WINELIB_NAME_AW(CreateEvent) +HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES, + DWORD,DWORD,HANDLE); +HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES, + DWORD,DWORD,HANDLE); +#define CreateFile WINELIB_NAME_AW(CreateFile) +HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD, + DWORD,DWORD,LPCSTR); +HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD, + DWORD,DWORD,LPCWSTR); +#define CreateFileMapping WINELIB_NAME_AW(CreateFileMapping) +HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR); +HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR); +#define CreateMutex WINELIB_NAME_AW(CreateMutex) +WIN_BOOL WINAPI CreatePipe(PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD); +WIN_BOOL WINAPI CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCSTR, + LPSTARTUPINFOA,LPPROCESS_INFORMATION); +WIN_BOOL WINAPI CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCWSTR, + LPSTARTUPINFOW,LPPROCESS_INFORMATION); +#define CreateProcess WINELIB_NAME_AW(CreateProcess) +HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR); +HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR); +#define CreateSemaphore WINELIB_NAME_AW(CreateSemaphore) +HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD); +HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR); +HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR); +#define CreateWaitableTimer WINELIB_NAME_AW(CreateWaitableTimer) +WIN_BOOL WINAPI DebugActiveProcess(DWORD); +void WINAPI DebugBreak(void); +WIN_BOOL WINAPI DeregisterEventSource(HANDLE); +WIN_BOOL WINAPI DisableThreadLibraryCalls(HMODULE); +WIN_BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME); +WIN_BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,HANDLE*,DWORD,WIN_BOOL,DWORD); +WIN_BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA lpDateFmtEnumProc, LCID Locale, DWORD dwFlags); +WIN_BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags); +#define EnumDateFormats WINELIB_NAME_AW(EnumDateFormats) +WIN_BOOL WINAPI EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR, + ENUMRESLANGPROCA,LONG); +WIN_BOOL WINAPI EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR, + ENUMRESLANGPROCW,LONG); +#define EnumResourceLanguages WINELIB_NAME_AW(EnumResourceLanguages) +WIN_BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA, + LONG); +WIN_BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW, + LONG); +#define EnumResourceNames WINELIB_NAME_AW(EnumResourceNames) +WIN_BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG); +WIN_BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG); +#define EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes) +WIN_BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA,DWORD); +WIN_BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW,DWORD); +#define EnumSystemCodePages WINELIB_NAME_AW(EnumSystemCodePages) +WIN_BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD); +WIN_BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD); +#define EnumSystemLocales WINELIB_NAME_AW(EnumSystemLocales) +WIN_BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags); +WIN_BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags); +#define EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats) +WIN_BOOL WINAPI EqualSid(PSID, PSID); +WIN_BOOL WINAPI EqualPrefixSid(PSID,PSID); +VOID WINAPI ExitProcess(DWORD) WINE_NORETURN; +VOID WINAPI ExitThread(DWORD) WINE_NORETURN; +DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD); +DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD); +#define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings) +WIN_BOOL WINAPI FileTimeToDosDateTime(const FILETIME*,LPWORD,LPWORD); +WIN_BOOL WINAPI FileTimeToLocalFileTime(const FILETIME*,LPFILETIME); +WIN_BOOL WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME); +HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR,WIN_BOOL,DWORD); +HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR,WIN_BOOL,DWORD); +#define FindFirstChangeNotification WINELIB_NAME_AW(FindFirstChangeNotification) +WIN_BOOL WINAPI FindNextChangeNotification(HANDLE); +WIN_BOOL WINAPI FindCloseChangeNotification(HANDLE); +HRSRC WINAPI FindResourceExA(HMODULE,LPCSTR,LPCSTR,WORD); +HRSRC WINAPI FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD); +#define FindResourceEx WINELIB_NAME_AW(FindResourceEx) +WIN_BOOL WINAPI FlushConsoleInputBuffer(HANDLE); +WIN_BOOL WINAPI FlushFileBuffers(HANDLE); +WIN_BOOL WINAPI FlushViewOfFile(LPCVOID, DWORD); +DWORD WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR, + DWORD,LPDWORD); +DWORD WINAPI FormatMessageW(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, + DWORD,LPDWORD); +#define FormatMessage WINELIB_NAME_AW(FormatMessage) +WIN_BOOL WINAPI FreeConsole(void); +WIN_BOOL WINAPI FreeEnvironmentStringsA(LPSTR); +WIN_BOOL WINAPI FreeEnvironmentStringsW(LPWSTR); +#define FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings) +PVOID WINAPI FreeSid(PSID); +UINT WINAPI GetACP(void); +LPCSTR WINAPI GetCommandLineA(void); +LPCWSTR WINAPI GetCommandLineW(void); +#define GetCommandLine WINELIB_NAME_AW(GetCommandLine) +WIN_BOOL WINAPI GetComputerNameA(LPSTR,LPDWORD); +WIN_BOOL WINAPI GetComputerNameW(LPWSTR,LPDWORD); +#define GetComputerName WINELIB_NAME_AW(GetComputerName) +UINT WINAPI GetConsoleCP(void); +WIN_BOOL WINAPI GetConsoleMode(HANDLE,LPDWORD); +UINT WINAPI GetConsoleOutputCP(void); +DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD); +DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD); +#define GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle) +WIN_BOOL WINAPI GetCommMask(HANDLE, LPDWORD); +WIN_BOOL WINAPI GetCommModemStatus(HANDLE, LPDWORD); +HANDLE WINAPI GetCurrentProcess(void); +HANDLE WINAPI GetCurrentThread(void); +INT WINAPI GetDateFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT); +INT WINAPI GetDateFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT); +#define GetDateFormat WINELIB_NAME_AW(GetDateFormat) +LPSTR WINAPI GetEnvironmentStringsA(void); +LPWSTR WINAPI GetEnvironmentStringsW(void); +#define GetEnvironmentStrings WINELIB_NAME_AW(GetEnvironmentStrings) +DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD); +DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD); +#define GetEnvironmentVariable WINELIB_NAME_AW(GetEnvironmentVariable) +WIN_BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID); +WIN_BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID); +#define GetFileattributesEx WINELIB_NAME_AW(GetFileAttributesEx) +DWORD WINAPI GetFileInformationByHandle(HANDLE,BY_HANDLE_FILE_INFORMATION*); +WIN_BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD); +WIN_BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD); +#define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity) +DWORD WINAPI GetFileSize(HANDLE,LPDWORD); +WIN_BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME); +DWORD WINAPI GetFileType(HANDLE); +DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*); +DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*); +#define GetFullPathName WINELIB_NAME_AW(GetFullPathName) +WIN_BOOL WINAPI GetHandleInformation(HANDLE,LPDWORD); +COORD WINAPI GetLargestConsoleWindowSize(HANDLE); +DWORD WINAPI GetLengthSid(PSID); +VOID WINAPI GetLocalTime(LPSYSTEMTIME); +DWORD WINAPI GetLogicalDrives(void); +DWORD WINAPI GetLongPathNameA(LPCSTR,LPSTR,DWORD); +DWORD WINAPI GetLongPathNameW(LPCWSTR,LPWSTR,DWORD); +#define GetLongPathName WINELIB_NAME_AW(GetLongPathName) +WIN_BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,LPDWORD); +WIN_BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD); +WIN_BOOL WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD); +UINT WINAPI GetOEMCP(void); +WIN_BOOL WINAPI GetOldestEventLogRecord(HANDLE,PDWORD); +DWORD WINAPI GetPriorityClass(HANDLE); +DWORD WINAPI GetProcessVersion(DWORD); +WIN_BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,LPDWORD); +WIN_BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL); +WIN_BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL); +DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR); +WIN_BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL); +WIN_BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL); +PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID); +DWORD WINAPI GetSidLengthRequired(BYTE); +PDWORD WINAPI GetSidSubAuthority(PSID,DWORD); +PUCHAR WINAPI GetSidSubAuthorityCount(PSID); +DWORD WINAPI GetShortPathNameA(LPCSTR,LPSTR,DWORD); +DWORD WINAPI GetShortPathNameW(LPCWSTR,LPWSTR,DWORD); +#define GetShortPathName WINELIB_NAME_AW(GetShortPathName) +HFILE WINAPI GetStdHandle(DWORD); +WIN_BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,INT,LPWORD); +WIN_BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,INT,LPWORD); +#define GetStringTypeEx WINELIB_NAME_AW(GetStringTypeEx) +VOID WINAPI GetSystemInfo(LPSYSTEM_INFO); +WIN_BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS); +VOID WINAPI GetSystemTime(LPSYSTEMTIME); +VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME); +INT WINAPI GetTimeFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT); +INT WINAPI GetTimeFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT); +#define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat) +WIN_BOOL WINAPI GetThreadContext(HANDLE,CONTEXT *); +LCID WINAPI GetThreadLocale(void); +INT WINAPI GetThreadPriority(HANDLE); +WIN_BOOL WINAPI GetThreadSelectorEntry(HANDLE,DWORD,LPLDT_ENTRY); +WIN_BOOL WINAPI GetThreadTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME); +WIN_BOOL WINAPI GetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,LPVOID,DWORD,LPDWORD); +WIN_BOOL WINAPI GetUserNameA(LPSTR,LPDWORD); +WIN_BOOL WINAPI GetUserNameW(LPWSTR,LPDWORD); +#define GetUserName WINELIB_NAME_AW(GetUserName) +VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS); +LPVOID WINAPI HeapAlloc(HANDLE,DWORD,DWORD); +DWORD WINAPI HeapCompact(HANDLE,DWORD); +HANDLE WINAPI HeapCreate(DWORD,DWORD,DWORD); +WIN_BOOL WINAPI HeapDestroy(HANDLE); +WIN_BOOL WINAPI HeapFree(HANDLE,DWORD,LPVOID); +WIN_BOOL WINAPI HeapLock(HANDLE); +LPVOID WINAPI HeapReAlloc(HANDLE,DWORD,LPVOID,DWORD); +DWORD WINAPI HeapSize(HANDLE,DWORD,LPVOID); +WIN_BOOL WINAPI HeapUnlock(HANDLE); +WIN_BOOL WINAPI HeapValidate(HANDLE,DWORD,LPCVOID); +WIN_BOOL WINAPI HeapWalk(HANDLE,LPPROCESS_HEAP_ENTRY); +WIN_BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); +WIN_BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); +WIN_BOOL WINAPI IsValidSid(PSID); +WIN_BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL); +WIN_BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE); +WIN_BOOL WINAPI IsProcessorFeaturePresent(DWORD); +WIN_BOOL WINAPI IsValidLocale(DWORD,DWORD); +WIN_BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE); +WIN_BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,LPDWORD,LPWSTR,LPDWORD,PSID_NAME_USE); +#define LookupAccountSid WINELIB_NAME_AW(LookupAccountSidW) +WIN_BOOL WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME); +WIN_BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); +WIN_BOOL WINAPI LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED); +WIN_BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,LPVOID); +WIN_BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,LPVOID); +#define LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue) +WIN_BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD); +HMODULE WINAPI MapHModuleSL(HMODULE16); +HMODULE16 WINAPI MapHModuleLS(HMODULE); +SEGPTR WINAPI MapLS(LPVOID); +LPVOID WINAPI MapSL(SEGPTR); +LPVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD); +LPVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPVOID); +WIN_BOOL WINAPI MoveFileA(LPCSTR,LPCSTR); +WIN_BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR); +#define MoveFile WINELIB_NAME_AW(MoveFile) +WIN_BOOL WINAPI MoveFileExA(LPCSTR,LPCSTR,DWORD); +WIN_BOOL WINAPI MoveFileExW(LPCWSTR,LPCWSTR,DWORD); +#define MoveFileEx WINELIB_NAME_AW(MoveFileEx) +INT WINAPI MultiByteToWideChar(UINT,DWORD,LPCSTR,INT,LPWSTR,INT); +WIN_BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE); +INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,WIN_BOOL*); +HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR); +HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR); +#define OpenBackupEventLog WINELIB_NAME_AW(OpenBackupEventLog) +HANDLE WINAPI OpenEventA(DWORD,WIN_BOOL,LPCSTR); +HANDLE WINAPI OpenEventW(DWORD,WIN_BOOL,LPCWSTR); +#define OpenEvent WINELIB_NAME_AW(OpenEvent) +HANDLE WINAPI OpenEventLogA(LPCSTR,LPCSTR); +HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR); +#define OpenEventLog WINELIB_NAME_AW(OpenEventLog) +HANDLE WINAPI OpenFileMappingA(DWORD,WIN_BOOL,LPCSTR); +HANDLE WINAPI OpenFileMappingW(DWORD,WIN_BOOL,LPCWSTR); +#define OpenFileMapping WINELIB_NAME_AW(OpenFileMapping) +HANDLE WINAPI OpenMutexA(DWORD,WIN_BOOL,LPCSTR); +HANDLE WINAPI OpenMutexW(DWORD,WIN_BOOL,LPCWSTR); +#define OpenMutex WINELIB_NAME_AW(OpenMutex) +HANDLE WINAPI OpenProcess(DWORD,WIN_BOOL,DWORD); +WIN_BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE); +HANDLE WINAPI OpenSemaphoreA(DWORD,WIN_BOOL,LPCSTR); +HANDLE WINAPI OpenSemaphoreW(DWORD,WIN_BOOL,LPCWSTR); +#define OpenSemaphore WINELIB_NAME_AW(OpenSemaphore) +WIN_BOOL WINAPI OpenThreadToken(HANDLE,DWORD,WIN_BOOL,PHANDLE); +HANDLE WINAPI OpenWaitableTimerA(DWORD,WIN_BOOL,LPCSTR); +HANDLE WINAPI OpenWaitableTimerW(DWORD,WIN_BOOL,LPCWSTR); +#define OpenWaitableTimer WINELIB_NAME_AW(OpenWaitableTimer) +WIN_BOOL WINAPI PulseEvent(HANDLE); +WIN_BOOL WINAPI PurgeComm(HANDLE,DWORD); +DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD); +DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD); +#define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice) +WIN_BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER); +WIN_BOOL WINAPI ReadConsoleA(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID); +WIN_BOOL WINAPI ReadConsoleW(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID); +#define ReadConsole WINELIB_NAME_AW(ReadConsole) +WIN_BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE,LPSTR,DWORD, + COORD,LPDWORD); +#define ReadConsoleOutputCharacter WINELIB_NAME_AW(ReadConsoleOutputCharacter) +WIN_BOOL WINAPI ReadEventLogA(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *); +WIN_BOOL WINAPI ReadEventLogW(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *); +#define ReadEventLog WINELIB_NAME_AW(ReadEventLog) +WIN_BOOL WINAPI ReadFile(HANDLE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED); +HANDLE WINAPI RegisterEventSourceA(LPCSTR,LPCSTR); +HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR); +#define RegisterEventSource WINELIB_NAME_AW(RegisterEventSource) +WIN_BOOL WINAPI ReleaseMutex(HANDLE); +WIN_BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG); +WIN_BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR *,LPVOID); +WIN_BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID); +#define ReportEvent WINELIB_NAME_AW(ReportEvent) +WIN_BOOL WINAPI ResetEvent(HANDLE); +DWORD WINAPI ResumeThread(HANDLE); +WIN_BOOL WINAPI RevertToSelf(void); +DWORD WINAPI SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*); +DWORD WINAPI SearchPathW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*); +#define SearchPath WINELIB_NAME_AW(SearchPath) +WIN_BOOL WINAPI SetCommMask(INT,DWORD); +WIN_BOOL WINAPI SetComputerNameA(LPCSTR); +WIN_BOOL WINAPI SetComputerNameW(LPCWSTR); +#define SetComputerName WINELIB_NAME_AW(SetComputerName) +WIN_BOOL WINAPI SetConsoleCursorPosition(HANDLE,COORD); +WIN_BOOL WINAPI SetConsoleMode(HANDLE,DWORD); +WIN_BOOL WINAPI SetConsoleTitleA(LPCSTR); +WIN_BOOL WINAPI SetConsoleTitleW(LPCWSTR); +#define SetConsoleTitle WINELIB_NAME_AW(SetConsoleTitle) +WIN_BOOL WINAPI SetEndOfFile(HANDLE); +WIN_BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR); +WIN_BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR); +#define SetEnvironmentVariable WINELIB_NAME_AW(SetEnvironmentVariable) +WIN_BOOL WINAPI SetEvent(HANDLE); +VOID WINAPI SetFileApisToANSI(void); +VOID WINAPI SetFileApisToOEM(void); +DWORD WINAPI SetFilePointer(HANDLE,LONG,LPLONG,DWORD); +WIN_BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); +WIN_BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); +#define SetFileSecurity WINELIB_NAME_AW(SetFileSecurity) +WIN_BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*); +WIN_BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD); +WIN_BOOL WINAPI SetPriorityClass(HANDLE,DWORD); +WIN_BOOL WINAPI SetLocalTime(const SYSTEMTIME*); +WIN_BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL); +WIN_BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL); +WIN_BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL); +WIN_BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL); +WIN_BOOL WINAPI SetStdHandle(DWORD,HANDLE); +WIN_BOOL WINAPI SetSystemPowerState(WIN_BOOL,WIN_BOOL); +WIN_BOOL WINAPI SetSystemTime(const SYSTEMTIME*); +DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD); +WIN_BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT *); +WIN_BOOL WINAPI SetThreadLocale(LCID); +WIN_BOOL WINAPI SetThreadPriority(HANDLE,INT); +WIN_BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION); +WIN_BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,WIN_BOOL); +VOID WINAPI Sleep(DWORD); +DWORD WINAPI SleepEx(DWORD,WIN_BOOL); +DWORD WINAPI SuspendThread(HANDLE); +WIN_BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME); +DWORD WINAPI TlsAlloc(void); +WIN_BOOL WINAPI TlsFree(DWORD); +LPVOID WINAPI TlsGetValue(DWORD); +WIN_BOOL WINAPI TlsSetValue(DWORD,LPVOID); +VOID WINAPI UnMapLS(SEGPTR); +WIN_BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); +WIN_BOOL WINAPI UnmapViewOfFile(LPVOID); +LPVOID WINAPI VirtualAlloc(LPVOID,DWORD,DWORD,DWORD); +WIN_BOOL WINAPI VirtualFree(LPVOID,SIZE_T,DWORD); +WIN_BOOL WINAPI VirtualLock(LPVOID,DWORD); +WIN_BOOL WINAPI VirtualProtect(LPVOID,DWORD,DWORD,LPDWORD); +WIN_BOOL WINAPI VirtualProtectEx(HANDLE,LPVOID,DWORD,DWORD,LPDWORD); +DWORD WINAPI VirtualQuery(LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); +DWORD WINAPI VirtualQueryEx(HANDLE,LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); +WIN_BOOL WINAPI VirtualUnlock(LPVOID,DWORD); +WIN_BOOL WINAPI WaitCommEvent(HANDLE,LPDWORD,LPOVERLAPPED); +WIN_BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT,DWORD); +DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,WIN_BOOL,DWORD); +DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,WIN_BOOL,DWORD,WIN_BOOL); +DWORD WINAPI WaitForSingleObject(HANDLE,DWORD); +DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,WIN_BOOL); +WIN_BOOL WINAPI WriteConsoleA(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID); +WIN_BOOL WINAPI WriteConsoleW(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID); +#define WriteConsole WINELIB_NAME_AW(WriteConsole) +WIN_BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED); +LANGID WINAPI GetSystemDefaultLangID(void); +LCID WINAPI GetSystemDefaultLCID(void); +LANGID WINAPI GetUserDefaultLangID(void); +LCID WINAPI GetUserDefaultLCID(void); +ATOM WINAPI AddAtomA(LPCSTR); +ATOM WINAPI AddAtomW(LPCWSTR); +#define AddAtom WINELIB_NAME_AW(AddAtom) +UINT WINAPI CompareStringA(DWORD,DWORD,LPCSTR,DWORD,LPCSTR,DWORD); +UINT WINAPI CompareStringW(DWORD,DWORD,LPCWSTR,DWORD,LPCWSTR,DWORD); +#define CompareString WINELIB_NAME_AW(CompareString) +WIN_BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES); +WIN_BOOL WINAPI CreateDirectoryW(LPCWSTR,LPSECURITY_ATTRIBUTES); +#define CreateDirectory WINELIB_NAME_AW(CreateDirectory) +WIN_BOOL WINAPI CreateDirectoryExA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES); +WIN_BOOL WINAPI CreateDirectoryExW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES); +#define CreateDirectoryEx WINELIB_NAME_AW(CreateDirectoryEx) +WIN_BOOL WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR); +#define DefineHandleTable(w) ((w),TRUE) +ATOM WINAPI DeleteAtom(ATOM); +WIN_BOOL WINAPI DeleteFileA(LPCSTR); +WIN_BOOL WINAPI DeleteFileW(LPCWSTR); +#define DeleteFile WINELIB_NAME_AW(DeleteFile) +void WINAPI FatalAppExitA(UINT,LPCSTR); +void WINAPI FatalAppExitW(UINT,LPCWSTR); +#define FatalAppExit WINELIB_NAME_AW(FatalAppExit) +ATOM WINAPI FindAtomA(LPCSTR); +ATOM WINAPI FindAtomW(LPCWSTR); +#define FindAtom WINELIB_NAME_AW(FindAtom) +WIN_BOOL WINAPI FindClose(HANDLE); +HANDLE16 WINAPI FindFirstFile16(LPCSTR,LPWIN32_FIND_DATAA); +HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA); +HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW); +#define FindFirstFile WINELIB_NAME_AW(FindFirstFile) +WIN_BOOL16 WINAPI FindNextFile16(HANDLE16,LPWIN32_FIND_DATAA); +WIN_BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA); +WIN_BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW); +#define FindNextFile WINELIB_NAME_AW(FindNextFile) +HRSRC WINAPI FindResourceA(HMODULE,LPCSTR,LPCSTR); +HRSRC WINAPI FindResourceW(HMODULE,LPCWSTR,LPCWSTR); +#define FindResource WINELIB_NAME_AW(FindResource) +VOID WINAPI FreeLibrary16(HINSTANCE16); +WIN_BOOL WINAPI FreeLibrary(HMODULE); +#define FreeModule(handle) FreeLibrary(handle) +#define FreeProcInstance(proc) /*nothing*/ +WIN_BOOL WINAPI FreeResource(HGLOBAL); +UINT WINAPI GetAtomNameA(ATOM,LPSTR,INT); +UINT WINAPI GetAtomNameW(ATOM,LPWSTR,INT); +#define GetAtomName WINELIB_NAME_AW(GetAtomName) +UINT WINAPI GetCurrentDirectoryA(UINT,LPSTR); +UINT WINAPI GetCurrentDirectoryW(UINT,LPWSTR); +#define GetCurrentDirectory WINELIB_NAME_AW(GetCurrentDirectory) +WIN_BOOL WINAPI GetDiskFreeSpaceA(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); +WIN_BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); +#define GetDiskFreeSpace WINELIB_NAME_AW(GetDiskFreeSpace) +WIN_BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); +WIN_BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); +#define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx) +UINT WINAPI GetDriveTypeA(LPCSTR); +UINT WINAPI GetDriveTypeW(LPCWSTR); +#define GetDriveType WINELIB_NAME_AW(GetDriveType) +DWORD WINAPI GetFileAttributesA(LPCSTR); +DWORD WINAPI GetFileAttributesW(LPCWSTR); +#define GetFileAttributes WINELIB_NAME_AW(GetFileAttributes) +#define GetFreeSpace(w) (0x100000L) +UINT WINAPI GetLogicalDriveStringsA(UINT,LPSTR); +UINT WINAPI GetLogicalDriveStringsW(UINT,LPWSTR); +#define GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings) +INT WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,INT); +INT WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,INT); +#define GetLocaleInfo WINELIB_NAME_AW(GetLocaleInfo) +DWORD WINAPI GetModuleFileNameA(HMODULE,LPSTR,DWORD); +DWORD WINAPI GetModuleFileNameW(HMODULE,LPWSTR,DWORD); +#define GetModuleFileName WINELIB_NAME_AW(GetModuleFileName) +HMODULE WINAPI GetModuleHandleA(LPCSTR); +HMODULE WINAPI GetModuleHandleW(LPCWSTR); +#define GetModuleHandle WINELIB_NAME_AW(GetModuleHandle) +WIN_BOOL WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,LPDWORD,WIN_BOOL); +UINT WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR); +UINT WINAPI GetPrivateProfileIntW(LPCWSTR,LPCWSTR,INT,LPCWSTR); +#define GetPrivateProfileInt WINELIB_NAME_AW(GetPrivateProfileInt) +INT WINAPI GetPrivateProfileSectionA(LPCSTR,LPSTR,DWORD,LPCSTR); +INT WINAPI GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR); +#define GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection) +DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR,DWORD,LPCSTR); +DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR,DWORD,LPCWSTR); +#define GetPrivateProfileSectionNames WINELIB_NAME_AW(GetPrivateProfileSectionNames) +INT WINAPI GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT,LPCSTR); +INT WINAPI GetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT,LPCWSTR); +#define GetPrivateProfileString WINELIB_NAME_AW(GetPrivateProfileString) +WIN_BOOL WINAPI GetPrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); +WIN_BOOL WINAPI GetPrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); +#define GetPrivateProfileStruct WINELIB_NAME_AW(GetPrivateProfileStruct) +FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); +UINT WINAPI GetProfileIntA(LPCSTR,LPCSTR,INT); +UINT WINAPI GetProfileIntW(LPCWSTR,LPCWSTR,INT); +#define GetProfileInt WINELIB_NAME_AW(GetProfileInt) +INT WINAPI GetProfileSectionA(LPCSTR,LPSTR,DWORD); +INT WINAPI GetProfileSectionW(LPCWSTR,LPWSTR,DWORD); +#define GetProfileSection WINELIB_NAME_AW(GetProfileSection) +INT WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT); +INT WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT); +#define GetProfileString WINELIB_NAME_AW(GetProfileString) +VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA); +VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW); +#define GetStartupInfo WINELIB_NAME_AW(GetStartupInfo) +WIN_BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,INT,LPWORD); +WIN_BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,INT,LPWORD); +#define GetStringType WINELIB_NAME_AW(GetStringType) +UINT WINAPI GetSystemDirectoryA(LPSTR,UINT); +UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT); +#define GetSystemDirectory WINELIB_NAME_AW(GetSystemDirectory) +UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR); +UINT WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR); +#define GetTempFileName WINELIB_NAME_AW(GetTempFileName) +UINT WINAPI GetTempPathA(UINT,LPSTR); +UINT WINAPI GetTempPathW(UINT,LPWSTR); +#define GetTempPath WINELIB_NAME_AW(GetTempPath) +LONG WINAPI GetVersion(void); +WIN_BOOL WINAPI GetExitCodeProcess(HANDLE,LPDWORD); +WIN_BOOL WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD); +WIN_BOOL WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD); +#define GetVolumeInformation WINELIB_NAME_AW(GetVolumeInformation) +UINT WINAPI GetWindowsDirectoryA(LPSTR,UINT); +UINT WINAPI GetWindowsDirectoryW(LPWSTR,UINT); +#define GetWindowsDirectory WINELIB_NAME_AW(GetWindowsDirectory) +HGLOBAL16 WINAPI GlobalAlloc16(UINT16,DWORD); +HGLOBAL WINAPI GlobalAlloc(UINT,DWORD); +DWORD WINAPI GlobalCompact(DWORD); +UINT WINAPI GlobalFlags(HGLOBAL); +HGLOBAL16 WINAPI GlobalFree16(HGLOBAL16); +HGLOBAL WINAPI GlobalFree(HGLOBAL); +HGLOBAL WINAPI GlobalHandle(LPCVOID); +WORD WINAPI GlobalFix16(HGLOBAL16); +VOID WINAPI GlobalFix(HGLOBAL); +LPVOID WINAPI GlobalLock16(HGLOBAL16); +LPVOID WINAPI GlobalLock(HGLOBAL); +HGLOBAL WINAPI GlobalReAlloc(HGLOBAL,DWORD,UINT); +DWORD WINAPI GlobalSize16(HGLOBAL16); +DWORD WINAPI GlobalSize(HGLOBAL); +VOID WINAPI GlobalUnfix16(HGLOBAL16); +VOID WINAPI GlobalUnfix(HGLOBAL); +WIN_BOOL16 WINAPI GlobalUnlock16(HGLOBAL16); +WIN_BOOL WINAPI GlobalUnlock(HGLOBAL); +WIN_BOOL16 WINAPI GlobalUnWire16(HGLOBAL16); +WIN_BOOL WINAPI GlobalUnWire(HGLOBAL); +SEGPTR WINAPI GlobalWire16(HGLOBAL16); +LPVOID WINAPI GlobalWire(HGLOBAL); +WIN_BOOL WINAPI InitAtomTable(DWORD); +WIN_BOOL WINAPI IsBadCodePtr(FARPROC); +WIN_BOOL WINAPI IsBadHugeReadPtr(LPCVOID,UINT); +WIN_BOOL WINAPI IsBadHugeWritePtr(LPVOID,UINT); +WIN_BOOL WINAPI IsBadReadPtr(LPCVOID,UINT); +WIN_BOOL WINAPI IsBadStringPtrA(LPCSTR,UINT); +WIN_BOOL WINAPI IsBadStringPtrW(LPCWSTR,UINT); +#define IsBadStringPtr WINELIB_NAME_AW(IsBadStringPtr) +WIN_BOOL WINAPI IsBadWritePtr(LPVOID,UINT); +WIN_BOOL WINAPI IsDBCSLeadByte(BYTE); +WIN_BOOL WINAPI IsDebuggerPresent(void); +HINSTANCE16 WINAPI LoadLibrary16(LPCSTR); +HMODULE WINAPI LoadLibraryA(LPCSTR); +HMODULE WINAPI LoadLibraryW(LPCWSTR); +#define LoadLibrary WINELIB_NAME_AW(LoadLibrary) +HMODULE WINAPI LoadLibraryExA(LPCSTR,HANDLE,DWORD); +HMODULE WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD); +#define LoadLibraryEx WINELIB_NAME_AW(LoadLibraryEx) +HINSTANCE16 WINAPI LoadModule16(LPCSTR,LPVOID); +HINSTANCE WINAPI LoadModule(LPCSTR,LPVOID); +HGLOBAL WINAPI LoadResource(HMODULE,HRSRC); +HLOCAL WINAPI LocalAlloc(UINT,DWORD); +UINT WINAPI LocalCompact(UINT); +UINT WINAPI LocalFlags(HLOCAL); +HLOCAL WINAPI LocalFree(HLOCAL); +HLOCAL WINAPI LocalHandle(LPCVOID); +LPVOID WINAPI LocalLock(HLOCAL); +HLOCAL WINAPI LocalReAlloc(HLOCAL,DWORD,UINT); +UINT WINAPI LocalShrink(HGLOBAL,UINT); +UINT WINAPI LocalSize(HLOCAL); +WIN_BOOL WINAPI LocalUnlock(HLOCAL); +LPVOID WINAPI LockResource(HGLOBAL); +#define LockSegment(handle) GlobalFix((HANDLE)(handle)) +#define MakeProcInstance(proc,inst) (proc) +HFILE16 WINAPI OpenFile16(LPCSTR,OFSTRUCT*,UINT16); +HFILE WINAPI OpenFile(LPCSTR,OFSTRUCT*,UINT); +VOID WINAPI OutputDebugStringA(LPCSTR); +VOID WINAPI OutputDebugStringW(LPCWSTR); +#define OutputDebugString WINELIB_NAME_AW(OutputDebugString) +WIN_BOOL WINAPI ReadProcessMemory(HANDLE, LPCVOID, LPVOID, DWORD, LPDWORD); +WIN_BOOL WINAPI RemoveDirectoryA(LPCSTR); +WIN_BOOL WINAPI RemoveDirectoryW(LPCWSTR); +#define RemoveDirectory WINELIB_NAME_AW(RemoveDirectory) +WIN_BOOL WINAPI SetCurrentDirectoryA(LPCSTR); +WIN_BOOL WINAPI SetCurrentDirectoryW(LPCWSTR); +#define SetCurrentDirectory WINELIB_NAME_AW(SetCurrentDirectory) +UINT WINAPI SetErrorMode(UINT); +WIN_BOOL WINAPI SetFileAttributesA(LPCSTR,DWORD); +WIN_BOOL WINAPI SetFileAttributesW(LPCWSTR,DWORD); +#define SetFileAttributes WINELIB_NAME_AW(SetFileAttributes) +UINT WINAPI SetHandleCount(UINT); +#define SetSwapAreaSize(w) (w) +WIN_BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR); +WIN_BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR); +#define SetVolumeLabel WINELIB_NAME_AW(SetVolumeLabel) +DWORD WINAPI SizeofResource(HMODULE,HRSRC); +#define UnlockSegment(handle) GlobalUnfix((HANDLE)(handle)) +WIN_BOOL WINAPI WritePrivateProfileSectionA(LPCSTR,LPCSTR,LPCSTR); +WIN_BOOL WINAPI WritePrivateProfileSectionW(LPCWSTR,LPCWSTR,LPCWSTR); +#define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection) +WIN_BOOL WINAPI WritePrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPCSTR); +WIN_BOOL WINAPI WritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); +#define WritePrivateProfileString WINELIB_NAME_AW(WritePrivateProfileString) +WIN_BOOL WINAPI WriteProfileSectionA(LPCSTR,LPCSTR); +WIN_BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR); +#define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection) +WIN_BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); +WIN_BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); +#define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct) +WIN_BOOL WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD); +WIN_BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR); +WIN_BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR); +#define WriteProfileString WINELIB_NAME_AW(WriteProfileString) +#define Yield32() +LPSTR WINAPI lstrcatA(LPSTR,LPCSTR); +LPWSTR WINAPI lstrcatW(LPWSTR,LPCWSTR); +#define lstrcat WINELIB_NAME_AW(lstrcat) +LPSTR WINAPI lstrcpyA(LPSTR,LPCSTR); +LPWSTR WINAPI lstrcpyW(LPWSTR,LPCWSTR); +#define lstrcpy WINELIB_NAME_AW(lstrcpy) +LPSTR WINAPI lstrcpynA(LPSTR,LPCSTR,INT); +LPWSTR WINAPI lstrcpynW(LPWSTR,LPCWSTR,INT); +#define lstrcpyn WINELIB_NAME_AW(lstrcpyn) +INT WINAPI lstrlenA(LPCSTR); +INT WINAPI lstrlenW(LPCWSTR); +#define lstrlen WINELIB_NAME_AW(lstrlen) +HINSTANCE WINAPI WinExec(LPCSTR,UINT); +LONG WINAPI _hread(HFILE,LPVOID,LONG); +LONG WINAPI _hwrite(HFILE,LPCSTR,LONG); +HFILE WINAPI _lcreat(LPCSTR,INT); +HFILE WINAPI _lclose(HFILE); +LONG WINAPI _llseek(HFILE,LONG,INT); +HFILE WINAPI _lopen(LPCSTR,INT); +UINT WINAPI _lread(HFILE,LPVOID,UINT); +UINT WINAPI _lwrite(HFILE,LPCSTR,UINT); +SEGPTR WINAPI WIN16_GlobalLock16(HGLOBAL16); +INT WINAPI lstrcmpA(LPCSTR,LPCSTR); +INT WINAPI lstrcmpW(LPCWSTR,LPCWSTR); +#define lstrcmp WINELIB_NAME_AW(lstrcmp) +INT WINAPI lstrcmpiA(LPCSTR,LPCSTR); +INT WINAPI lstrcmpiW(LPCWSTR,LPCWSTR); +#define lstrcmpi WINELIB_NAME_AW(lstrcmpi) + +/* compatibility macros */ +#define FillMemory RtlFillMemory +#define MoveMemory RtlMoveMemory +#define ZeroMemory RtlZeroMemory +#define CopyMemory RtlCopyMemory + +DWORD WINAPI GetCurrentProcessId(void); +DWORD WINAPI GetCurrentThreadId(void); +DWORD WINAPI GetLastError(void); +HANDLE WINAPI GetProcessHeap(void); +PVOID WINAPI InterlockedCompareExchange(PVOID*,PVOID,PVOID); +LONG WINAPI InterlockedDecrement(PLONG); +LONG WINAPI InterlockedExchange(PLONG,LONG); +LONG WINAPI InterlockedExchangeAdd(PLONG,LONG); +LONG WINAPI InterlockedIncrement(PLONG); +VOID WINAPI SetLastError(DWORD); + +#ifdef __WINE__ +#define GetCurrentProcess() ((HANDLE)0xffffffff) +#define GetCurrentThread() ((HANDLE)0xfffffffe) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_WINBASE_H */ diff --git a/linphone/win32acm/wine/windef.h b/linphone/win32acm/wine/windef.h new file mode 100644 index 000000000..85b84255a --- /dev/null +++ b/linphone/win32acm/wine/windef.h @@ -0,0 +1,666 @@ +/* + * Basic types definitions + * + * Copyright 1996 Alexandre Julliard + */ + +#ifndef __WINE_WINDEF_H +#define __WINE_WINDEF_H + +#ifdef __WINE__ +# include "config.h" +# undef UNICODE +#endif + +#ifdef _EGCS_ +#define __stdcall +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Misc. constants. */ + +#ifdef FALSE +#undef FALSE +#endif +#define FALSE 0 + +#ifdef TRUE +#undef TRUE +#endif +#define TRUE 1 + +#ifdef NULL +#undef NULL +#endif +#define NULL 0 + +/* Macros to map Winelib names to the correct implementation name */ +/* depending on __WINE__ and UNICODE macros. */ +/* Note that Winelib is purely Win32. */ + +#ifdef __WINE__ +# define WINELIB_NAME_AW(func) \ + func##_must_be_suffixed_with_W_or_A_in_this_context \ + func##_must_be_suffixed_with_W_or_A_in_this_context +#else /* __WINE__ */ +# ifdef UNICODE +# define WINELIB_NAME_AW(func) func##W +# else +# define WINELIB_NAME_AW(func) func##A +# endif /* UNICODE */ +#endif /* __WINE__ */ + +#ifdef __WINE__ +# define DECL_WINELIB_TYPE_AW(type) /* nothing */ +#else /* __WINE__ */ +# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; +#endif /* __WINE__ */ + +#ifndef NONAMELESSSTRUCT +# if defined(__WINE__) || !defined(_FORCENAMELESSSTRUCT) +# define NONAMELESSSTRUCT +# endif +#endif /* !defined(NONAMELESSSTRUCT) */ + +#ifndef NONAMELESSUNION +# if defined(__WINE__) || !defined(_FORCENAMELESSUNION) || !defined(__cplusplus) +# define NONAMELESSUNION +# endif +#endif /* !defined(NONAMELESSUNION) */ + +#ifndef NONAMELESSSTRUCT +#define DUMMYSTRUCTNAME +#define DUMMYSTRUCTNAME1 +#define DUMMYSTRUCTNAME2 +#define DUMMYSTRUCTNAME3 +#define DUMMYSTRUCTNAME4 +#define DUMMYSTRUCTNAME5 +#else /* !defined(NONAMELESSSTRUCT) */ +#define DUMMYSTRUCTNAME s +#define DUMMYSTRUCTNAME1 s1 +#define DUMMYSTRUCTNAME2 s2 +#define DUMMYSTRUCTNAME3 s3 +#define DUMMYSTRUCTNAME4 s4 +#define DUMMYSTRUCTNAME5 s5 +#endif /* !defined(NONAMELESSSTRUCT) */ + +#ifndef NONAMELESSUNION +#define DUMMYUNIONNAME +#define DUMMYUNIONNAME1 +#define DUMMYUNIONNAME2 +#define DUMMYUNIONNAME3 +#define DUMMYUNIONNAME4 +#define DUMMYUNIONNAME5 +#else /* !defined(NONAMELESSUNION) */ +#define DUMMYUNIONNAME u +#define DUMMYUNIONNAME1 u1 +#define DUMMYUNIONNAME2 u2 +#define DUMMYUNIONNAME3 u3 +#define DUMMYUNIONNAME4 u4 +#define DUMMYUNIONNAME5 u5 +#endif /* !defined(NONAMELESSUNION) */ + +/* Calling conventions definitions */ + +#ifdef __i386__ +# if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7))) +# ifndef _EGCS_ +#define __stdcall __attribute__((__stdcall__)) +#define __cdecl __attribute__((__cdecl__)) +# define __RESTORE_ES __asm__ __volatile__("pushl %ds\n\tpopl %es") +# endif +# else +// # error You need gcc >= 2.7 to build Wine on a 386 +# endif +#else +# define __stdcall +# define __cdecl +# define __RESTORE_ES +#endif + +#define CALLBACK __stdcall +#define WINAPI __stdcall +#define APIPRIVATE __stdcall +#define PASCAL __stdcall +#define pascal __stdcall +#define _pascal __stdcall +#if !defined(__CYGWIN__) +#define _stdcall __stdcall +#define _fastcall __stdcall +#define __fastcall __stdcall +#endif +#define __export __stdcall +#define CDECL __cdecl +#define _CDECL __cdecl +#define cdecl __cdecl +#if !defined(__CYGWIN__) +#define _cdecl __cdecl +#endif +#define WINAPIV __cdecl +#define APIENTRY WINAPI + +#if !defined(__CYGWIN__) +#define __declspec(x) +#endif +#define dllimport +#define dllexport + +#define CONST const + +/* Standard data types. These are the same for emulator and library. */ + +typedef void VOID; +typedef int INT; +typedef unsigned int UINT; +typedef unsigned short WORD; +typedef unsigned int DWORD; +typedef unsigned int ULONG; +typedef unsigned char BYTE; +typedef long LONG; +typedef short SHORT; +typedef unsigned short USHORT; +typedef char CHAR; +typedef unsigned char UCHAR; + +typedef LONG SCODE; + +/* Some systems might have wchar_t, but we really need 16 bit characters */ +typedef unsigned short WCHAR; +typedef int WIN_BOOL; +typedef double DATE; +typedef double DOUBLE; +typedef long long LONGLONG; +typedef unsigned long long ULONGLONG; + +/* FIXME: Wine does not compile with strict on, therefore strict + * handles are presently only usable on machines where sizeof(UINT) == + * sizeof(void*). HANDLEs are supposed to be void* but a large amount + * of WINE code operates on HANDLES as if they are UINTs. So to WINE + * they exist as UINTs but to the Winelib user who turns on strict, + * they exist as void*. If there is a size difference between UINT and + * void* then things get ugly. */ +#ifdef STRICT +typedef VOID* HANDLE; +#else +typedef UINT HANDLE; +#endif + + +typedef HANDLE *LPHANDLE; + +/* Integer types. These are the same for emulator and library. */ +typedef UINT WPARAM; +typedef LONG LPARAM; +typedef LONG HRESULT; +typedef LONG LRESULT; +typedef WORD ATOM; +typedef WORD CATCHBUF[9]; +typedef WORD *LPCATCHBUF; +typedef HANDLE HHOOK; +typedef HANDLE HMONITOR; +typedef DWORD LCID; +typedef WORD LANGID; +typedef DWORD LCTYPE; +typedef float FLOAT; + +/* Pointers types. These are the same for emulator and library. */ +/* winnt types */ +typedef VOID *PVOID; +typedef const void *PCVOID; +typedef CHAR *PCHAR; +typedef UCHAR *PUCHAR; +typedef BYTE *PBYTE; +typedef WORD *PWORD; +typedef USHORT *PUSHORT; +typedef SHORT *PSHORT; +typedef ULONG *PULONG; +typedef LONG *PLONG; +typedef DWORD *PDWORD; +/* common win32 types */ +typedef CHAR *LPSTR; +typedef CHAR *PSTR; +typedef const CHAR *LPCSTR; +typedef const CHAR *PCSTR; +typedef WCHAR *LPWSTR; +typedef WCHAR *PWSTR; +typedef const WCHAR *LPCWSTR; +typedef const WCHAR *PCWSTR; +typedef BYTE *LPBYTE; +typedef WORD *LPWORD; +typedef DWORD *LPDWORD; +typedef LONG *LPLONG; +typedef VOID *LPVOID; +typedef const VOID *LPCVOID; +typedef INT *PINT; +typedef INT *LPINT; +typedef UINT *PUINT; +typedef UINT *LPUINT; +typedef FLOAT *PFLOAT; +typedef FLOAT *LPFLOAT; +typedef WIN_BOOL *PWIN_BOOL; +typedef WIN_BOOL *LPWIN_BOOL; + +/* Special case: a segmented pointer is just a pointer in the user's code. */ + +#ifdef __WINE__ +typedef DWORD SEGPTR; +#else +typedef void* SEGPTR; +#endif /* __WINE__ */ + +/* Handle types that exist both in Win16 and Win32. */ + +#ifdef STRICT +#define DECLARE_HANDLE(a) \ + typedef struct a##__ { int unused; } *a; \ + typedef a *P##a; \ + typedef a *LP##a +#else /*STRICT*/ +#define DECLARE_HANDLE(a) \ + typedef HANDLE a; \ + typedef a *P##a; \ + typedef a *LP##a +#endif /*STRICT*/ + +DECLARE_HANDLE(HACMDRIVERID); +DECLARE_HANDLE(HACMDRIVER); +DECLARE_HANDLE(HACMOBJ); +DECLARE_HANDLE(HACMSTREAM); +DECLARE_HANDLE(HMETAFILEPICT); + +DECLARE_HANDLE(HACCEL); +DECLARE_HANDLE(HBITMAP); +DECLARE_HANDLE(HBRUSH); +DECLARE_HANDLE(HCOLORSPACE); +DECLARE_HANDLE(HCURSOR); +DECLARE_HANDLE(HDC); +DECLARE_HANDLE(HDROP); +DECLARE_HANDLE(HDRVR); +DECLARE_HANDLE(HDWP); +DECLARE_HANDLE(HENHMETAFILE); +DECLARE_HANDLE(HFILE); +DECLARE_HANDLE(HFONT); +DECLARE_HANDLE(HICON); +DECLARE_HANDLE(HINSTANCE); +DECLARE_HANDLE(HKEY); +DECLARE_HANDLE(HMENU); +DECLARE_HANDLE(HMETAFILE); +DECLARE_HANDLE(HMIDI); +DECLARE_HANDLE(HMIDIIN); +DECLARE_HANDLE(HMIDIOUT); +DECLARE_HANDLE(HMIDISTRM); +DECLARE_HANDLE(HMIXER); +DECLARE_HANDLE(HMIXEROBJ); +DECLARE_HANDLE(HMMIO); +DECLARE_HANDLE(HPALETTE); +DECLARE_HANDLE(HPEN); +DECLARE_HANDLE(HQUEUE); +DECLARE_HANDLE(HRGN); +DECLARE_HANDLE(HRSRC); +DECLARE_HANDLE(HTASK); +DECLARE_HANDLE(HWAVE); +DECLARE_HANDLE(HWAVEIN); +DECLARE_HANDLE(HWAVEOUT); +DECLARE_HANDLE(HWINSTA); +DECLARE_HANDLE(HDESK); +DECLARE_HANDLE(HWND); +DECLARE_HANDLE(HKL); +DECLARE_HANDLE(HIC); +DECLARE_HANDLE(HRASCONN); + +/* Handle types that must remain interchangeable even with strict on */ + +typedef HINSTANCE HMODULE; +typedef HANDLE HGDIOBJ; +typedef HANDLE HGLOBAL; +typedef HANDLE HLOCAL; +typedef HANDLE GLOBALHANDLE; +typedef HANDLE LOCALHANDLE; + +/* Callback function pointers types */ +//WIN_BOOL CALLBACK DATEFMT_ENUMPROCA(LPSTR); + +typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCA)(LPSTR); +typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCW)(LPWSTR); +DECL_WINELIB_TYPE_AW(DATEFMT_ENUMPROC) +typedef WIN_BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM); +typedef LRESULT CALLBACK (*DRIVERPROC)(DWORD,HDRVR,UINT,LPARAM,LPARAM); +typedef INT CALLBACK (*EDITWORDBREAKPROCA)(LPSTR,INT,INT,INT); +typedef INT CALLBACK (*EDITWORDBREAKPROCW)(LPWSTR,INT,INT,INT); +DECL_WINELIB_TYPE_AW(EDITWORDBREAKPROC) +typedef LRESULT CALLBACK (*FARPROC)(); +typedef INT CALLBACK (*PROC)(); +typedef WIN_BOOL CALLBACK (*GRAYSTRINGPROC)(HDC,LPARAM,INT); +typedef LRESULT CALLBACK (*HOOKPROC)(INT,WPARAM,LPARAM); +typedef WIN_BOOL CALLBACK (*PROPENUMPROCA)(HWND,LPCSTR,HANDLE); +typedef WIN_BOOL CALLBACK (*PROPENUMPROCW)(HWND,LPCWSTR,HANDLE); +DECL_WINELIB_TYPE_AW(PROPENUMPROC) +typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXA)(HWND,LPCSTR,HANDLE,LPARAM); +typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXW)(HWND,LPCWSTR,HANDLE,LPARAM); +DECL_WINELIB_TYPE_AW(PROPENUMPROCEX) +typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCA)(LPSTR); +typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCW)(LPWSTR); +DECL_WINELIB_TYPE_AW(TIMEFMT_ENUMPROC) +typedef VOID CALLBACK (*TIMERPROC)(HWND,UINT,UINT,DWORD); +typedef WIN_BOOL CALLBACK (*WNDENUMPROC)(HWND,LPARAM); +typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM); + +/*---------------------------------------------------------------------------- +** FIXME: Better isolate Wine's reliance on the xxx16 type definitions. +** For now, we just isolate them to make the situation clear. +**--------------------------------------------------------------------------*/ +/* + * Basic type definitions for 16 bit variations on Windows types. + * These types are provided mostly to insure compatibility with + * 16 bit windows code. + */ + +#ifndef __WINE_WINDEF16_H +#define __WINE_WINDEF16_H + +#include "windef.h" + +/* Standard data types */ + + /* FIXME horrible hack! lpc10 encoder also defines INT16 */ +#ifndef __LPC10_H__ +typedef short INT16; +#endif + +typedef unsigned short UINT16; +typedef unsigned short WIN_BOOL16; + +typedef UINT16 HANDLE16; +typedef HANDLE16 *LPHANDLE16; + +typedef UINT16 WPARAM16; +typedef INT16 *LPINT16; +typedef UINT16 *LPUINT16; + +#define DECLARE_HANDLE16(a) \ + typedef HANDLE16 a##16; \ + typedef a##16 *P##a##16; \ + typedef a##16 *NP##a##16; \ + typedef a##16 *LP##a##16 + +DECLARE_HANDLE16(HACMDRIVERID); +DECLARE_HANDLE16(HACMDRIVER); +DECLARE_HANDLE16(HACMOBJ); +DECLARE_HANDLE16(HACMSTREAM); +DECLARE_HANDLE16(HMETAFILEPICT); + +DECLARE_HANDLE16(HACCEL); +DECLARE_HANDLE16(HBITMAP); +DECLARE_HANDLE16(HBRUSH); +DECLARE_HANDLE16(HCOLORSPACE); +DECLARE_HANDLE16(HCURSOR); +DECLARE_HANDLE16(HDC); +DECLARE_HANDLE16(HDROP); +DECLARE_HANDLE16(HDRVR); +DECLARE_HANDLE16(HDWP); +DECLARE_HANDLE16(HENHMETAFILE); +DECLARE_HANDLE16(HFILE); +DECLARE_HANDLE16(HFONT); +DECLARE_HANDLE16(HICON); +DECLARE_HANDLE16(HINSTANCE); +DECLARE_HANDLE16(HKEY); +DECLARE_HANDLE16(HMENU); +DECLARE_HANDLE16(HMETAFILE); +DECLARE_HANDLE16(HMIDI); +DECLARE_HANDLE16(HMIDIIN); +DECLARE_HANDLE16(HMIDIOUT); +DECLARE_HANDLE16(HMIDISTRM); +DECLARE_HANDLE16(HMIXER); +DECLARE_HANDLE16(HMIXEROBJ); +DECLARE_HANDLE16(HMMIO); +DECLARE_HANDLE16(HPALETTE); +DECLARE_HANDLE16(HPEN); +DECLARE_HANDLE16(HQUEUE); +DECLARE_HANDLE16(HRGN); +DECLARE_HANDLE16(HRSRC); +DECLARE_HANDLE16(HTASK); +DECLARE_HANDLE16(HWAVE); +DECLARE_HANDLE16(HWAVEIN); +DECLARE_HANDLE16(HWAVEOUT); +DECLARE_HANDLE16(HWINSTA); +DECLARE_HANDLE16(HDESK); +DECLARE_HANDLE16(HWND); +DECLARE_HANDLE16(HKL); +DECLARE_HANDLE16(HIC); +DECLARE_HANDLE16(HRASCONN); +#undef DECLARE_HANDLE16 + +typedef HINSTANCE16 HMODULE16; +typedef HANDLE16 HGDIOBJ16; +typedef HANDLE16 HGLOBAL16; +typedef HANDLE16 HLOCAL16; + +/* The SIZE structure */ +typedef struct +{ + INT16 cx; + INT16 cy; +} SIZE16, *PSIZE16, *LPSIZE16; + +/* The POINT structure */ + +typedef struct +{ + INT16 x; + INT16 y; +} POINT16, *PPOINT16, *LPPOINT16; + +/* The RECT structure */ + +typedef struct +{ + INT16 left; + INT16 top; + INT16 right; + INT16 bottom; +} RECT16, *LPRECT16; + +/* Callback function pointers types */ + +typedef LRESULT CALLBACK (*DRIVERPROC16)(DWORD,HDRVR16,UINT16,LPARAM,LPARAM); +typedef WIN_BOOL16 CALLBACK (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM); +typedef INT16 CALLBACK (*EDITWORDBREAKPROC16)(LPSTR,INT16,INT16,INT16); +typedef LRESULT CALLBACK (*FARPROC16)(); +typedef INT16 CALLBACK (*PROC16)(); +typedef WIN_BOOL16 CALLBACK (*GRAYSTRINGPROC16)(HDC16,LPARAM,INT16); +typedef LRESULT CALLBACK (*HOOKPROC16)(INT16,WPARAM16,LPARAM); +typedef WIN_BOOL16 CALLBACK (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16); +typedef VOID CALLBACK (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD); +typedef LRESULT CALLBACK (*WNDENUMPROC16)(HWND16,LPARAM); +typedef LRESULT CALLBACK (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM); + +#endif /* __WINE_WINDEF16_H */ + +/* Define some empty macros for compatibility with Windows code. */ + +#ifndef __WINE__ +#define NEAR +#define FAR +#define near +#define far +#define _near +#define _far +#define IN +#define OUT +#define OPTIONAL +#endif /* __WINE__ */ + +/* Macro for structure packing. */ + +#ifdef __GNUC__ +#ifndef _EGCS_ +#define WINE_PACKED __attribute__((packed)) +#define WINE_UNUSED __attribute__((unused)) +#define WINE_NORETURN __attribute__((noreturn)) +#endif +#else +#define WINE_PACKED /* nothing */ +#define WINE_UNUSED /* nothing */ +#define WINE_NORETURN /* nothing */ +#endif + +/* Macros to split words and longs. */ + +#define LOBYTE(w) ((BYTE)(WORD)(w)) +#define HIBYTE(w) ((BYTE)((WORD)(w) >> 8)) + +#define LOWORD(l) ((WORD)(DWORD)(l)) +#define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) + +#define SLOWORD(l) ((INT16)(LONG)(l)) +#define SHIWORD(l) ((INT16)((LONG)(l) >> 16)) + +#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8)) +#define MAKELONG(low,high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16))) +#define MAKELPARAM(low,high) ((LPARAM)MAKELONG(low,high)) +#define MAKEWPARAM(low,high) ((WPARAM)MAKELONG(low,high)) +#define MAKELRESULT(low,high) ((LRESULT)MAKELONG(low,high)) +#define MAKEINTATOM(atom) ((LPCSTR)MAKELONG((atom),0)) + +#define SELECTOROF(ptr) (HIWORD(ptr)) +#define OFFSETOF(ptr) (LOWORD(ptr)) + +#ifdef __WINE__ +/* macros to set parts of a DWORD (not in the Windows API) */ +#define SET_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD(val)) +#define SET_LOBYTE(dw,val) ((dw) = ((dw) & 0xffffff00) | LOBYTE(val)) +#define SET_HIBYTE(dw,val) ((dw) = ((dw) & 0xffff00ff) | (LOWORD(val) & 0xff00)) +#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val))) +#endif + +/* Macros to access unaligned or wrong-endian WORDs and DWORDs. */ +/* Note: These macros are semantically broken, at least for wrc. wrc + spits out data in the platform's current binary format, *not* in + little-endian format. These macros are used throughout the resource + code to load and store data to the resources. Since it is unlikely + that we'll ever be dealing with little-endian resource data, the + byte-swapping nature of these macros has been disabled. Rather than + remove the use of these macros from the resource loading code, the + macros have simply been disabled. In the future, someone may want + to reactivate these macros for other purposes. In that case, the + resource code will have to be modified to use different macros. */ + +#if 1 +#define PUT_WORD(ptr,w) (*(WORD *)(ptr) = (w)) +#define GET_WORD(ptr) (*(WORD *)(ptr)) +#define PUT_DWORD(ptr,dw) (*(DWORD *)(ptr) = (dw)) +#define GET_DWORD(ptr) (*(DWORD *)(ptr)) +#else +#define PUT_WORD(ptr,w) (*(BYTE *)(ptr) = LOBYTE(w), \ + *((BYTE *)(ptr) + 1) = HIBYTE(w)) +#define GET_WORD(ptr) ((WORD)(*(BYTE *)(ptr) | \ + (WORD)(*((BYTE *)(ptr)+1) << 8))) +#define PUT_DWORD(ptr,dw) (PUT_WORD((ptr),LOWORD(dw)), \ + PUT_WORD((WORD *)(ptr)+1,HIWORD(dw))) +#define GET_DWORD(ptr) ((DWORD)(GET_WORD(ptr) | \ + ((DWORD)GET_WORD((WORD *)(ptr)+1) << 16))) +#endif /* 1 */ + +/* min and max macros */ +#define __max(a,b) (((a) > (b)) ? (a) : (b)) +#define __min(a,b) (((a) < (b)) ? (a) : (b)) +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#define _MAX_PATH 260 +#define MAX_PATH 260 +#define _MAX_DRIVE 3 +#define _MAX_DIR 256 +#define _MAX_FNAME 255 +#define _MAX_EXT 256 + +#define HFILE_ERROR16 ((HFILE16)-1) +#define HFILE_ERROR ((HFILE)-1) + +/* The SIZE structure */ +typedef struct tagSIZE +{ + INT cx; + INT cy; +} SIZE, *PSIZE, *LPSIZE; + + +typedef SIZE SIZEL, *PSIZEL, *LPSIZEL; + +#define CONV_SIZE16TO32(s16,s32) \ + ((s32)->cx = (INT)(s16)->cx, (s32)->cy = (INT)(s16)->cy) +#define CONV_SIZE32TO16(s32,s16) \ + ((s16)->cx = (INT16)(s32)->cx, (s16)->cy = (INT16)(s32)->cy) + +/* The POINT structure */ +typedef struct tagPOINT +{ + LONG x; + LONG y; +} POINT, *PPOINT, *LPPOINT; + +typedef struct _POINTL +{ + LONG x; + LONG y; +} POINTL; + +#define CONV_POINT16TO32(p16,p32) \ + ((p32)->x = (INT)(p16)->x, (p32)->y = (INT)(p16)->y) +#define CONV_POINT32TO16(p32,p16) \ + ((p16)->x = (INT16)(p32)->x, (p16)->y = (INT16)(p32)->y) + +#define MAKEPOINT16(l) (*((POINT16 *)&(l))) + +/* The POINTS structure */ + +typedef struct tagPOINTS +{ + SHORT x; + SHORT y; +} POINTS, *PPOINTS, *LPPOINTS; + + +#define MAKEPOINTS(l) (*((POINTS *)&(l))) + + +/* The RECT structure */ +typedef struct tagRECT +{ + short left; + short top; + short right; + short bottom; +} RECT, *PRECT, *LPRECT; +typedef const RECT *LPCRECT; + + +typedef struct tagRECTL +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} RECTL, *PRECTL, *LPRECTL; + +typedef const RECTL *LPCRECTL; + +#define CONV_RECT16TO32(r16,r32) \ + ((r32)->left = (INT)(r16)->left, (r32)->top = (INT)(r16)->top, \ + (r32)->right = (INT)(r16)->right, (r32)->bottom = (INT)(r16)->bottom) +#define CONV_RECT32TO16(r32,r16) \ + ((r16)->left = (INT16)(r32)->left, (r16)->top = (INT16)(r32)->top, \ + (r16)->right = (INT16)(r32)->right, (r16)->bottom = (INT16)(r32)->bottom) + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_WINDEF_H */ diff --git a/linphone/win32acm/wine/windows.h b/linphone/win32acm/wine/windows.h new file mode 100644 index 000000000..cd62a0327 --- /dev/null +++ b/linphone/win32acm/wine/windows.h @@ -0,0 +1,38 @@ +#ifndef __WINE_WINDOWS_H +#define __WINE_WINDOWS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "shell.h" +#include "winreg.h" +#include "winnetwk.h" +#include "winver.h" +#include "lzexpand.h" +#include "shellapi.h" +#include "ole2.h" +#include "winnls.h" +#include "objbase.h" +#include "winspool.h" + +#if 0 + Where does this belong? Nobody uses this stuff anyway. +typedef struct { + BYTE i; /* much more .... */ +} KANJISTRUCT; +typedef KANJISTRUCT *LPKANJISTRUCT; +typedef KANJISTRUCT *NPKANJISTRUCT; +typedef KANJISTRUCT *PKANJISTRUCT; + + +#endif /* 0 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_WINDOWS_H */ diff --git a/linphone/win32acm/wine/winerror.h b/linphone/win32acm/wine/winerror.h new file mode 100644 index 000000000..0c78792b9 --- /dev/null +++ b/linphone/win32acm/wine/winerror.h @@ -0,0 +1,1658 @@ +#ifndef __WINE_WINERROR_H +#define __WINE_WINERROR_H + + +extern int WIN32_LastError; + +#define FACILITY_NULL 0 +#define FACILITY_RPC 1 +#define FACILITY_DISPATCH 2 +#define FACILITY_STORAGE 3 +#define FACILITY_ITF 4 +#define FACILITY_WIN32 7 +#define FACILITY_WINDOWS 8 +#define FACILITY_SSPI 9 +#define FACILITY_CONTROL 10 +#define FACILITY_CERT 11 +#define FACILITY_INTERNET 12 + +#define SEVERITY_ERROR 1 + + +#define MAKE_HRESULT(sev,fac,code) \ + ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) +#define MAKE_SCODE(sev,fac,code) \ + ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) +#define SUCCEEDED(stat) ((HRESULT)(stat)>=0) +#define FAILED(stat) ((HRESULT)(stat)<0) + +#define HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define SCODE_CODE(sc) ((sc) & 0xFFFF) + +#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1FFF) +#define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1FFF) + +/* ERROR_UNKNOWN is a placeholder for error conditions which haven't + * been tested yet so we're not exactly sure what will be returned. + * All instances of ERROR_UNKNOWN should be tested under Win95/NT + * and replaced. + */ +#define ERROR_UNKNOWN 99999 + +#define SEVERITY_SUCCESS 0 +#define SEVERITY_ERROR 1 + +#define NO_ERROR 0 +#define ERROR_SUCCESS 0 +#define ERROR_INVALID_FUNCTION 1 +#define ERROR_FILE_NOT_FOUND 2 +#define ERROR_PATH_NOT_FOUND 3 +#define ERROR_TOO_MANY_OPEN_FILES 4 +#define ERROR_ACCESS_DENIED 5 +#define ERROR_INVALID_HANDLE 6 +#define ERROR_ARENA_TRASHED 7 +#define ERROR_NOT_ENOUGH_MEMORY 8 +#define ERROR_INVALID_BLOCK 9 +#define ERROR_BAD_ENVIRONMENT 10 +#define ERROR_BAD_FORMAT 11 +#define ERROR_INVALID_ACCESS 12 +#define ERROR_INVALID_DATA 13 +#define ERROR_OUTOFMEMORY 14 +#define ERROR_INVALID_DRIVE 15 +#define ERROR_CURRENT_DIRECTORY 16 +#define ERROR_NOT_SAME_DEVICE 17 +#define ERROR_NO_MORE_FILES 18 +#define ERROR_WRITE_PROTECT 19 +#define ERROR_BAD_UNIT 20 +#define ERROR_NOT_READY 21 +#define ERROR_BAD_COMMAND 22 +#define ERROR_CRC 23 +#define ERROR_BAD_LENGTH 24 +#define ERROR_SEEK 25 +#define ERROR_NOT_DOS_DISK 26 +#define ERROR_SECTOR_NOT_FOUND 27 +#define ERROR_OUT_OF_PAPER 28 +#define ERROR_WRITE_FAULT 29 +#define ERROR_READ_FAULT 30 +#define ERROR_GEN_FAILURE 31 +#define ERROR_SHARING_VIOLATION 32 +#define ERROR_LOCK_VIOLATION 33 +#define ERROR_WRONG_DISK 34 +#define ERROR_SHARING_BUFFER_EXCEEDED 36 +#define ERROR_HANDLE_EOF 38 +#define ERROR_HANDLE_DISK_FULL 39 +#define ERROR_NOT_SUPPORTED 50 +#define ERROR_REM_NOT_LIST 51 +#define ERROR_DUP_NAME 52 +#define ERROR_BAD_NETPATH 53 +#define ERROR_NETWORK_BUSY 54 +#define ERROR_DEV_NOT_EXIST 55 +#define ERROR_TOO_MANY_CMDS 56 +#define ERROR_ADAP_HDW_ERR 57 +#define ERROR_BAD_NET_RESP 58 +#define ERROR_UNEXP_NET_ERR 59 +#define ERROR_BAD_REM_ADAP 60 +#define ERROR_PRINTQ_FULL 61 +#define ERROR_NO_SPOOL_SPACE 62 +#define ERROR_PRINT_CANCELLED 63 +#define ERROR_NETNAME_DELETED 64 +#define ERROR_NETWORK_ACCESS_DENIED 65 +#define ERROR_BAD_DEV_TYPE 66 +#define ERROR_BAD_NET_NAME 67 +#define ERROR_TOO_MANY_NAMES 68 +#define ERROR_TOO_MANY_SESS 69 +#define ERROR_SHARING_PAUSED 70 +#define ERROR_REQ_NOT_ACCEP 71 +#define ERROR_REDIR_PAUSED 72 +#define ERROR_FILE_EXISTS 80 +#define ERROR_CANNOT_MAKE 82 +#define ERROR_FAIL_I24 83 +#define ERROR_OUT_OF_STRUCTURES 84 +#define ERROR_ALREADY_ASSIGNED 85 +#define ERROR_INVALID_PASSWORD 86 +#define ERROR_INVALID_PARAMETER 87 +#define ERROR_NET_WRITE_FAULT 88 +#define ERROR_NO_PROC_SLOTS 89 +#define ERROR_TOO_MANY_SEMAPHORES 100 +#define ERROR_EXCL_SEM_ALREADY_OWNED 101 +#define ERROR_SEM_IS_SET 102 +#define ERROR_TOO_MANY_SEM_REQUESTS 103 +#define ERROR_INVALID_AT_INTERRUPT_TIME 104 +#define ERROR_SEM_OWNER_DIED 105 +#define ERROR_SEM_USER_LIMIT 106 +#define ERROR_DISK_CHANGE 107 +#define ERROR_DRIVE_LOCKED 108 +#define ERROR_BROKEN_PIPE 109 +#define ERROR_OPEN_FAILED 110 +#define ERROR_BUFFER_OVERFLOW 111 +#define ERROR_DISK_FULL 112 +#define ERROR_NO_MORE_SEARCH_HANDLES 113 +#define ERROR_INVALID_TARGET_HANDLE 114 +#define ERROR_INVALID_CATEGORY 117 +#define ERROR_INVALID_VERIFY_SWITCH 118 +#define ERROR_BAD_DRIVER_LEVEL 119 +#define ERROR_CALL_NOT_IMPLEMENTED 120 +#define ERROR_SEM_TIMEOUT 121 +#define ERROR_INSUFFICIENT_BUFFER 122 +#define ERROR_INVALID_NAME 123 +#define ERROR_INVALID_LEVEL 124 +#define ERROR_NO_VOLUME_LABEL 125 +#define ERROR_MOD_NOT_FOUND 126 +#define ERROR_PROC_NOT_FOUND 127 +#define ERROR_WAIT_NO_CHILDREN 128 +#define ERROR_CHILD_NOT_COMPLETE 129 +#define ERROR_DIRECT_ACCESS_HANDLE 130 +#define ERROR_NEGATIVE_SEEK 131 +#define ERROR_SEEK_ON_DEVICE 132 +#define ERROR_IS_JOIN_TARGET 133 +#define ERROR_IS_JOINED 134 +#define ERROR_IS_SUBSTED 135 +#define ERROR_NOT_JOINED 136 +#define ERROR_NOT_SUBSTED 137 +#define ERROR_JOIN_TO_JOIN 138 +#define ERROR_SUBST_TO_SUBST 139 +#define ERROR_JOIN_TO_SUBST 140 +#define ERROR_SUBST_TO_JOIN 141 +#define ERROR_BUSY_DRIVE 142 +#define ERROR_SAME_DRIVE 143 +#define ERROR_DIR_NOT_ROOT 144 +#define ERROR_DIR_NOT_EMPTY 145 +#define ERROR_IS_SUBST_PATH 146 +#define ERROR_IS_JOIN_PATH 147 +#define ERROR_PATH_BUSY 148 +#define ERROR_IS_SUBST_TARGET 149 +#define ERROR_SYSTEM_TRACE 150 +#define ERROR_INVALID_EVENT_COUNT 151 +#define ERROR_TOO_MANY_MUXWAITERS 152 +#define ERROR_INVALID_LIST_FORMAT 153 +#define ERROR_LABEL_TOO_LONG 154 +#define ERROR_TOO_MANY_TCBS 155 +#define ERROR_SIGNAL_REFUSED 156 +#define ERROR_DISCARDED 157 +#define ERROR_NOT_LOCKED 158 +#define ERROR_BAD_THREADID_ADDR 159 +#define ERROR_BAD_ARGUMENTS 160 +#define ERROR_BAD_PATHNAME 161 +#define ERROR_SIGNAL_PENDING 162 +#define ERROR_MAX_THRDS_REACHED 164 +#define ERROR_LOCK_FAILED 167 +#define ERROR_BUSY 170 +#define ERROR_CANCEL_VIOLATION 173 +#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174 +#define ERROR_INVALID_SEGMENT_NUMBER 180 +#define ERROR_INVALID_ORDINAL 182 +#define ERROR_ALREADY_EXISTS 183 +#define ERROR_INVALID_FLAG_NUMBER 186 +#define ERROR_SEM_NOT_FOUND 187 +#define ERROR_INVALID_STARTING_CODESEG 188 +#define ERROR_INVALID_STACKSEG 189 +#define ERROR_INVALID_MODULETYPE 190 +#define ERROR_INVALID_EXE_SIGNATURE 191 +#define ERROR_EXE_MARKED_INVALID 192 +#define ERROR_BAD_EXE_FORMAT 193 +#define ERROR_ITERATED_DATA_EXCEEDS_64k 194 +#define ERROR_INVALID_MINALLOCSIZE 195 +#define ERROR_DYNLINK_FROM_INVALID_RING 196 +#define ERROR_IOPL_NOT_ENABLED 197 +#define ERROR_INVALID_SEGDPL 198 +#define ERROR_AUTODATASEG_EXCEEDS_64k 199 +#define ERROR_RING2SEG_MUST_BE_MOVABLE 200 +#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201 +#define ERROR_INFLOOP_IN_RELOC_CHAIN 202 +#define ERROR_ENVVAR_NOT_FOUND 203 +#define ERROR_NO_SIGNAL_SENT 205 +#define ERROR_FILENAME_EXCED_RANGE 206 +#define ERROR_RING2_STACK_IN_USE 207 +#define ERROR_META_EXPANSION_TOO_LONG 208 +#define ERROR_INVALID_SIGNAL_NUMBER 209 +#define ERROR_THREAD_1_INACTIVE 210 +#define ERROR_LOCKED 212 +#define ERROR_TOO_MANY_MODULES 214 +#define ERROR_NESTING_NOT_ALLOWED 215 +#define ERROR_EXE_MACHINE_TYPE_MISMATCH 216 +#define ERROR_BAD_PIPE 230 +#define ERROR_PIPE_BUSY 231 +#define ERROR_NO_DATA 232 +#define ERROR_PIPE_NOT_CONNECTED 233 +#define ERROR_MORE_DATA 234 +#define ERROR_VC_DISCONNECTED 240 +#define ERROR_INVALID_EA_NAME 254 +#define ERROR_EA_LIST_INCONSISTENT 255 +#define ERROR_NO_MORE_ITEMS 259 +#define ERROR_CANNOT_COPY 266 +#define ERROR_DIRECTORY 267 +#define ERROR_EAS_DIDNT_FIT 275 +#define ERROR_EA_FILE_CORRUPT 276 +#define ERROR_EA_TABLE_FULL 277 +#define ERROR_INVALID_EA_HANDLE 278 +#define ERROR_EAS_NOT_SUPPORTED 282 +#define ERROR_NOT_OWNER 288 +#define ERROR_TOO_MANY_POSTS 298 +#define ERROR_PARTIAL_COPY 299 +#define ERROR_OPLOCK_NOT_GRANTED 300 +#define ERROR_INVALID_OPLOCK_PROTOCOL 301 +#define ERROR_MR_MID_NOT_FOUND 317 +#define ERROR_INVALID_ADDRESS 487 +#define ERROR_ARITHMETIC_OVERFLOW 534 +#define ERROR_PIPE_CONNECTED 535 +#define ERROR_PIPE_LISTENING 536 +#define ERROR_EA_ACCESS_DENIED 994 +#define ERROR_OPERATION_ABORTED 995 +#define ERROR_IO_INCOMPLETE 996 +#define ERROR_IO_PENDING 997 +#define ERROR_NOACCESS 998 +#define ERROR_SWAPERROR 999 +#define ERROR_STACK_OVERFLOW 1001 +#define ERROR_INVALID_MESSAGE 1002 +#define ERROR_CAN_NOT_COMPLETE 1003 +#define ERROR_INVALID_FLAGS 1004 +#define ERROR_UNRECOGNIZED_VOLUME 1005 +#define ERROR_FILE_INVALID 1006 +#define ERROR_FULLSCREEN_MODE 1007 +#define ERROR_NO_TOKEN 1008 +#define ERROR_BADDB 1009 +#define ERROR_BADKEY 1010 +#define ERROR_CANTOPEN 1011 +#define ERROR_CANTREAD 1012 +#define ERROR_CANTWRITE 1013 +#define ERROR_REGISTRY_RECOVERED 1014 +#define ERROR_REGISTRY_CORRUPT 1015 +#define ERROR_REGISTRY_IO_FAILED 1016 +#define ERROR_NOT_REGISTRY_FILE 1017 +#define ERROR_KEY_DELETED 1018 +#define ERROR_NO_LOG_SPACE 1019 +#define ERROR_KEY_HAS_CHILDREN 1020 +#define ERROR_CHILD_MUST_BE_VOLATILE 1021 +#define ERROR_NOTIFY_ENUM_DIR 1022 +#define ERROR_DEPENDENT_SERVICES_RUNNING 1051 +#define ERROR_INVALID_SERVICE_CONTROL 1052 +#define ERROR_SERVICE_REQUEST_TIMEOUT 1053 +#define ERROR_SERVICE_NO_THREAD 1054 +#define ERROR_SERVICE_DATABASE_LOCKED 1055 +#define ERROR_SERVICE_ALREADY_RUNNING 1056 +#define ERROR_INVALID_SERVICE_ACCOUNT 1057 +#define ERROR_SERVICE_DISABLED 1058 +#define ERROR_CIRCULAR_DEPENDENCY 1059 +#define ERROR_SERVICE_DOES_NOT_EXIST 1060 +#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061 +#define ERROR_SERVICE_NOT_ACTIVE 1062 +#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063 +#define ERROR_EXCEPTION_IN_SERVICE 1064 +#define ERROR_DATABASE_DOES_NOT_EXIST 1065 +#define ERROR_SERVICE_SPECIFIC_ERROR 1066 +#define ERROR_PROCESS_ABORTED 1067 +#define ERROR_SERVICE_DEPENDENCY_FAIL 1068 +#define ERROR_SERVICE_LOGON_FAILED 1069 +#define ERROR_SERVICE_START_HANG 1070 +#define ERROR_INVALID_SERVICE_LOCK 1071 +#define ERROR_SERVICE_MARKED_FOR_DELETE 1072 +#define ERROR_SERVICE_EXISTS 1073 +#define ERROR_ALREADY_RUNNING_LKG 1074 +#define ERROR_SERVICE_DEPENDENCY_DELETED 1075 +#define ERROR_BOOT_ALREADY_ACCEPTED 1076 +#define ERROR_SERVICE_NEVER_STARTED 1077 +#define ERROR_DUPLICATE_SERVICE_NAME 1078 +#define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079 +#define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080 +#define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081 +#define ERROR_NO_RECOVERY_PROGRAM 1082 +#define ERROR_SERVICE_NOT_IN_EXE 1083 +#define ERROR_END_OF_MEDIA 1100 +#define ERROR_FILEMARK_DETECTED 1101 +#define ERROR_BEGINNING_OF_MEDIA 1102 +#define ERROR_SETMARK_DETECTED 1103 +#define ERROR_NO_DATA_DETECTED 1104 +#define ERROR_PARTITION_FAILURE 1105 +#define ERROR_INVALID_BLOCK_LENGTH 1106 +#define ERROR_DEVICE_NOT_PARTITIONED 1107 +#define ERROR_UNABLE_TO_LOCK_MEDIA 1108 +#define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109 +#define ERROR_MEDIA_CHANGED 1110 +#define ERROR_BUS_RESET 1111 +#define ERROR_NO_MEDIA_IN_DRIVE 1112 +#define ERROR_NO_UNICODE_TRANSLATION 1113 +#define ERROR_DLL_INIT_FAILED 1114 +#define ERROR_SHUTDOWN_IN_PROGRESS 1115 +#define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116 +#define ERROR_IO_DEVICE 1117 +#define ERROR_SERIAL_NO_DEVICE 1118 +#define ERROR_IRQ_BUSY 1119 +#define ERROR_MORE_WRITES 1120 +#define ERROR_COUNTER_TIMEOUT 1121 +#define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122 +#define ERROR_FLOPPY_WRONG_CYLINDER 1123 +#define ERROR_FLOPPY_UNKNOWN_ERROR 1124 +#define ERROR_FLOPPY_BAD_REGISTERS 1125 +#define ERROR_DISK_RECALIBRATE_FAILED 1126 +#define ERROR_DISK_OPERATION_FAILED 1127 +#define ERROR_DISK_RESET_FAILED 1128 +#define ERROR_EOM_OVERFLOW 1129 +#define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130 +#define ERROR_POSSIBLE_DEADLOCK 1131 +#define ERROR_MAPPED_ALIGNMENT 1132 +#define ERROR_SET_POWER_STATE_VETOED 1140 +#define ERROR_SET_POWER_STATE_FAILED 1141 +#define ERROR_TOO_MANY_LINKS 1142 +#define ERROR_OLD_WIN_VERSION 1150 +#define ERROR_APP_WRONG_OS 1151 +#define ERROR_SINGLE_INSTANCE_APP 1152 +#define ERROR_RMODE_APP 1153 +#define ERROR_INVALID_DLL 1154 +#define ERROR_NO_ASSOCIATION 1155 +#define ERROR_DDE_FAIL 1156 +#define ERROR_DLL_NOT_FOUND 1157 +#define ERROR_NO_MORE_USER_HANDLES 1158 +#define ERROR_MESSAGE_SYNC_ONLY 1159 +#define ERROR_SOURCE_ELEMENT_EMPTY 1160 +#define ERROR_DESTINATION_ELEMENT_FULL 1161 +#define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162 +#define ERROR_MAGAZINE_NOT_PRESENT 1163 +#define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164 +#define ERROR_DEVICE_REQUIRES_CLEANING 1165 +#define ERROR_DEVICE_DOOR_OPEN 1166 +#define ERROR_DEVICE_NOT_CONNECTED 1167 +#define ERROR_NOT_FOUND 1168 +#define ERROR_NO_MATCH 1169 +#define ERROR_SET_NOT_FOUND 1170 +#define ERROR_POINT_NOT_FOUND 1171 +#define ERROR_NO_TRACKING_SERVICE 1172 +#define ERROR_NO_VOLUME_ID 1173 +#define ERROR_UNABLE_TO_REMOVE_REPLACED 1175 +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176 +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177 +#define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178 +#define ERROR_JOURNAL_NOT_ACTIVE 1179 +#define ERROR_POTENTIAL_FILE_FOUND 1180 +#define ERROR_JOURNAL_ENTRY_DELETED 1181 +#define ERROR_BAD_DEVICE 1200 +#define ERROR_CONNECTION_UNAVAIL 1201 +#define ERROR_DEVICE_ALREADY_REMEMBERED 1202 +#define ERROR_NO_NET_OR_BAD_PATH 1203 +#define ERROR_BAD_PROVIDER 1204 +#define ERROR_CANNOT_OPEN_PROFILE 1205 +#define ERROR_BAD_PROFILE 1206 +#define ERROR_NOT_CONTAINER 1207 +#define ERROR_EXTENDED_ERROR 1208 +#define ERROR_INVALID_GROUPNAME 1209 +#define ERROR_INVALID_COMPUTERNAME 1210 +#define ERROR_INVALID_EVENTNAME 1211 +#define ERROR_INVALID_DOMAINNAME 1212 +#define ERROR_INVALID_SERVICENAME 1213 +#define ERROR_INVALID_NETNAME 1214 +#define ERROR_INVALID_SHARENAME 1215 +#define ERROR_INVALID_PASSWORDNAME 1216 +#define ERROR_INVALID_MESSAGENAME 1217 +#define ERROR_INVALID_MESSAGEDEST 1218 +#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219 +#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220 +#define ERROR_DUP_DOMAINNAME 1221 +#define ERROR_NO_NETWORK 1222 +#define ERROR_CANCELLED 1223 +#define ERROR_USER_MAPPED_FILE 1224 +#define ERROR_CONNECTION_REFUSED 1225 +#define ERROR_GRACEFUL_DISCONNECT 1226 +#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227 +#define ERROR_ADDRESS_NOT_ASSOCIATED 1228 +#define ERROR_CONNECTION_INVALID 1229 +#define ERROR_CONNECTION_ACTIVE 1230 +#define ERROR_NETWORK_UNREACHABLE 1231 +#define ERROR_HOST_UNREACHABLE 1232 +#define ERROR_PROTOCOL_UNREACHABLE 1233 +#define ERROR_PORT_UNREACHABLE 1234 +#define ERROR_REQUEST_ABORTED 1235 +#define ERROR_CONNECTION_ABORTED 1236 +#define ERROR_RETRY 1237 +#define ERROR_CONNECTION_COUNT_LIMIT 1238 +#define ERROR_LOGIN_TIME_RESTRICTION 1239 +#define ERROR_LOGIN_WKSTA_RESTRICTION 1240 +#define ERROR_INCORRECT_ADDRESS 1241 +#define ERROR_ALREADY_REGISTERED 1242 +#define ERROR_SERVICE_NOT_FOUND 1243 +#define ERROR_NOT_AUTHENTICATED 1244 +#define ERROR_NOT_LOGGED_ON 1245 +#define ERROR_CONTINUE 1246 +#define ERROR_ALREADY_INITIALIZED 1247 +#define ERROR_NO_MORE_DEVICES 1248 +#define ERROR_NO_SUCH_SITE 1249 +#define ERROR_DOMAIN_CONTROLLER_EXISTS 1250 +#define ERROR_ONLY_IF_CONNECTED 1251 +#define ERROR_OVERRIDE_NOCHANGES 1252 +#define ERROR_BAD_USER_PROFILE 1253 +#define ERROR_NOT_SUPPORTED_ON_SBS 1254 +#define ERROR_NOT_ALL_ASSIGNED 1300 +#define ERROR_SOME_NOT_MAPPED 1301 +#define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302 +#define ERROR_LOCAL_USER_SESSION_KEY 1303 +#define ERROR_NULL_LM_PASSWORD 1304 +#define ERROR_UNKNOWN_REVISION 1305 +#define ERROR_REVISION_MISMATCH 1306 +#define ERROR_INVALID_OWNER 1307 +#define ERROR_INVALID_PRIMARY_GROUP 1308 +#define ERROR_NO_IMPERSONATION_TOKEN 1309 +#define ERROR_CANT_DISABLE_MANDATORY 1310 +#define ERROR_NO_LOGON_SERVERS 1311 +#define ERROR_NO_SUCH_LOGON_SESSION 1312 +#define ERROR_NO_SUCH_PRIVILEGE 1313 +#define ERROR_PRIVILEGE_NOT_HELD 1314 +#define ERROR_INVALID_ACCOUNT_NAME 1315 +#define ERROR_USER_EXISTS 1316 +#define ERROR_NO_SUCH_USER 1317 +#define ERROR_GROUP_EXISTS 1318 +#define ERROR_NO_SUCH_GROUP 1319 +#define ERROR_MEMBER_IN_GROUP 1320 +#define ERROR_MEMBER_NOT_IN_GROUP 1321 +#define ERROR_LAST_ADMIN 1322 +#define ERROR_WRONG_PASSWORD 1323 +#define ERROR_ILL_FORMED_PASSWORD 1324 +#define ERROR_PASSWORD_RESTRICTION 1325 +#define ERROR_LOGON_FAILURE 1326 +#define ERROR_ACCOUNT_RESTRICTION 1327 +#define ERROR_INVALID_LOGON_HOURS 1328 +#define ERROR_INVALID_WORKSTATION 1329 +#define ERROR_PASSWORD_EXPIRED 1330 +#define ERROR_ACCOUNT_DISABLED 1331 +#define ERROR_NONE_MAPPED 1332 +#define ERROR_TOO_MANY_LUIDS_REQUESTED 1333 +#define ERROR_LUIDS_EXHAUSTED 1334 +#define ERROR_INVALID_SUB_AUTHORITY 1335 +#define ERROR_INVALID_ACL 1336 +#define ERROR_INVALID_SID 1337 +#define ERROR_INVALID_SECURITY_DESCR 1338 +#define ERROR_BAD_INHERITANCE_ACL 1340 +#define ERROR_SERVER_DISABLED 1341 +#define ERROR_SERVER_NOT_DISABLED 1342 +#define ERROR_INVALID_ID_AUTHORITY 1343 +#define ERROR_ALLOTTED_SPACE_EXCEEDED 1344 +#define ERROR_INVALID_GROUP_ATTRIBUTES 1345 +#define ERROR_BAD_IMPERSONATION_LEVEL 1346 +#define ERROR_CANT_OPEN_ANONYMOUS 1347 +#define ERROR_BAD_VALIDATION_CLASS 1348 +#define ERROR_BAD_TOKEN_TYPE 1349 +#define ERROR_NO_SECURITY_ON_OBJECT 1350 +#define ERROR_CANT_ACCESS_DOMAIN_INFO 1351 +#define ERROR_INVALID_SERVER_STATE 1352 +#define ERROR_INVALID_DOMAIN_STATE 1353 +#define ERROR_INVALID_DOMAIN_ROLE 1354 +#define ERROR_NO_SUCH_DOMAIN 1355 +#define ERROR_DOMAIN_EXISTS 1356 +#define ERROR_DOMAIN_LIMIT_EXCEEDED 1357 +#define ERROR_INTERNAL_DB_CORRUPTION 1358 +#define ERROR_INTERNAL_ERROR 1359 +#define ERROR_GENERIC_NOT_MAPPED 1360 +#define ERROR_BAD_DESCRIPTOR_FORMAT 1361 +#define ERROR_NOT_LOGON_PROCESS 1362 +#define ERROR_LOGON_SESSION_EXISTS 1363 +#define ERROR_NO_SUCH_PACKAGE 1364 +#define ERROR_BAD_LOGON_SESSION_STATE 1365 +#define ERROR_LOGON_SESSION_COLLISION 1366 +#define ERROR_INVALID_LOGON_TYPE 1367 +#define ERROR_CANNOT_IMPERSONATE 1368 +#define ERROR_RXACT_INVALID_STATE 1369 +#define ERROR_RXACT_COMMIT_FAILURE 1370 +#define ERROR_SPECIAL_ACCOUNT 1371 +#define ERROR_SPECIAL_GROUP 1372 +#define ERROR_SPECIAL_USER 1373 +#define ERROR_MEMBERS_PRIMARY_GROUP 1374 +#define ERROR_TOKEN_ALREADY_IN_USE 1375 +#define ERROR_NO_SUCH_ALIAS 1376 +#define ERROR_MEMBER_NOT_IN_ALIAS 1377 +#define ERROR_MEMBER_IN_ALIAS 1378 +#define ERROR_ALIAS_EXISTS 1379 +#define ERROR_LOGON_NOT_GRANTED 1380 +#define ERROR_TOO_MANY_SECRETS 1381 +#define ERROR_SECRET_TOO_LONG 1382 +#define ERROR_INTERNAL_DB_ERROR 1383 +#define ERROR_TOO_MANY_CONTEXT_IDS 1384 +#define ERROR_LOGON_TYPE_NOT_GRANTED 1385 +#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386 +#define ERROR_NO_SUCH_MEMBER 1387 +#define ERROR_INVALID_MEMBER 1388 +#define ERROR_TOO_MANY_SIDS 1389 +#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390 +#define ERROR_NO_INHERITANCE 1391 +#define ERROR_FILE_CORRUPT 1392 +#define ERROR_DISK_CORRUPT 1393 +#define ERROR_NO_USER_SESSION_KEY 1394 +#define ERROR_LICENSE_QUOTA_EXCEEDED 1395 +#define ERROR_WRONG_TARGET_NAME 1396 +#define ERROR_MUTUAL_AUTH_FAILED 1397 +#define ERROR_TIME_SKEW 1398 +#define ERROR_INVALID_WINDOW_HANDLE 1400 +#define ERROR_INVALID_MENU_HANDLE 1401 +#define ERROR_INVALID_CURSOR_HANDLE 1402 +#define ERROR_INVALID_ACCEL_HANDLE 1403 +#define ERROR_INVALID_HOOK_HANDLE 1404 +#define ERROR_INVALID_DWP_HANDLE 1405 +#define ERROR_TLW_WITH_WSCHILD 1406 +#define ERROR_CANNOT_FIND_WND_CLASS 1407 +#define ERROR_WINDOW_OF_OTHER_THREAD 1408 +#define ERROR_HOTKEY_ALREADY_REGISTERED 1409 +#define ERROR_CLASS_ALREADY_EXISTS 1410 +#define ERROR_CLASS_DOES_NOT_EXIST 1411 +#define ERROR_CLASS_HAS_WINDOWS 1412 +#define ERROR_INVALID_INDEX 1413 +#define ERROR_INVALID_ICON_HANDLE 1414 +#define ERROR_PRIVATE_DIALOG_INDEX 1415 +#define ERROR_LISTBOX_ID_NOT_FOUND 1416 +#define ERROR_NO_WILDCARD_CHARACTERS 1417 +#define ERROR_CLIPBOARD_NOT_OPEN 1418 +#define ERROR_HOTKEY_NOT_REGISTERED 1419 +#define ERROR_WINDOW_NOT_DIALOG 1420 +#define ERROR_CONTROL_ID_NOT_FOUND 1421 +#define ERROR_INVALID_COMBOBOX_MESSAGE 1422 +#define ERROR_WINDOW_NOT_COMBOBOX 1423 +#define ERROR_INVALID_EDIT_HEIGHT 1424 +#define ERROR_DC_NOT_FOUND 1425 +#define ERROR_INVALID_HOOK_FILTER 1426 +#define ERROR_INVALID_FILTER_PROC 1427 +#define ERROR_HOOK_NEEDS_HMOD 1428 +#define ERROR_GLOBAL_ONLY_HOOK 1429 +#define ERROR_JOURNAL_HOOK_SET 1430 +#define ERROR_HOOK_NOT_INSTALLED 1431 +#define ERROR_INVALID_LB_MESSAGE 1432 +#define ERROR_SETCOUNT_ON_BAD_LB 1433 +#define ERROR_LB_WITHOUT_TABSTOPS 1434 +#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435 +#define ERROR_CHILD_WINDOW_MENU 1436 +#define ERROR_NO_SYSTEM_MENU 1437 +#define ERROR_INVALID_MSGBOX_STYLE 1438 +#define ERROR_INVALID_SPI_VALUE 1439 +#define ERROR_SCREEN_ALREADY_LOCKED 1440 +#define ERROR_HWNDS_HAVE_DIFF_PARENT 1441 +#define ERROR_NOT_CHILD_WINDOW 1442 +#define ERROR_INVALID_GW_COMMAND 1443 +#define ERROR_INVALID_THREAD_ID 1444 +#define ERROR_NON_MDICHILD_WINDOW 1445 +#define ERROR_POPUP_ALREADY_ACTIVE 1446 +#define ERROR_NO_SCROLLBARS 1447 +#define ERROR_INVALID_SCROLLBAR_RANGE 1448 +#define ERROR_INVALID_SHOWWIN_COMMAND 1449 +#define ERROR_NO_SYSTEM_RESOURCES 1450 +#define ERROR_NONPAGED_SYSTEM_RESOURCES 1451 +#define ERROR_PAGED_SYSTEM_RESOURCES 1452 +#define ERROR_WORKING_SET_QUOTA 1453 +#define ERROR_PAGEFILE_QUOTA 1454 +#define ERROR_COMMITMENT_LIMIT 1455 +#define ERROR_MENU_ITEM_NOT_FOUND 1456 +#define ERROR_INVALID_KEYBOARD_HANDLE 1457 +#define ERROR_HOOK_TYPE_NOT_ALLOWED 1458 +#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459 +#define ERROR_TIMEOUT 1460 +#define ERROR_INVALID_MONITOR_HANDLE 1461 +#define ERROR_EVENTLOG_FILE_CORRUPT 1500 +#define ERROR_EVENTLOG_CANT_START 1501 +#define ERROR_LOG_FILE_FULL 1502 +#define ERROR_EVENTLOG_FILE_CHANGED 1503 +#define ERROR_INSTALL_SERVICE_FAILURE 1601 +#define ERROR_INSTALL_USEREXIT 1602 +#define ERROR_INSTALL_FAILURE 1603 +#define ERROR_INSTALL_SUSPEND 1604 +#define ERROR_UNKNOWN_PRODUCT 1605 +#define ERROR_UNKNOWN_FEATURE 1606 +#define ERROR_UNKNOWN_COMPONENT 1607 +#define ERROR_UNKNOWN_PROPERTY 1608 +#define ERROR_INVALID_HANDLE_STATE 1609 +#define ERROR_BAD_CONFIGURATION 1610 +#define ERROR_INDEX_ABSENT 1611 +#define ERROR_INSTALL_SOURCE_ABSENT 1612 +#define ERROR_INSTALL_PACKAGE_VERSION 1613 +#define ERROR_PRODUCT_UNINSTALLED 1614 +#define ERROR_BAD_QUERY_SYNTAX 1615 +#define ERROR_INVALID_FIELD 1616 +#define ERROR_DEVICE_REMOVED 1617 +#define ERROR_INSTALL_ALREADY_RUNNING 1618 +#define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619 +#define ERROR_INSTALL_PACKAGE_INVALID 1620 +#define ERROR_INSTALL_UI_FAILURE 1621 +#define ERROR_INSTALL_LOG_FAILURE 1622 +#define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623 +#define ERROR_INSTALL_TRANSFORM_FAILURE 1624 +#define ERROR_INSTALL_PACKAGE_REJECTED 1625 +#define ERROR_FUNCTION_NOT_CALLED 1626 +#define ERROR_FUNCTION_FAILED 1627 +#define ERROR_INVALID_TABLE 1628 +#define ERROR_DATATYPE_MISMATCH 1629 +#define ERROR_UNSUPPORTED_TYPE 1630 +#define ERROR_CREATE_FAILED 1631 +#define ERROR_INSTALL_TEMP_UNWRITABLE 1632 +#define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633 +#define ERROR_INSTALL_NOTUSED 1634 +#define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635 +#define ERROR_PATCH_PACKAGE_INVALID 1636 +#define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637 +#define ERROR_PRODUCT_VERSION 1638 +#define ERROR_INVALID_COMMAND_LINE 1639 +#define ERROR_INSTALL_REMOTE_DISALLOWED 1640 +#define ERROR_SUCCESS_REBOOT_INITIATED 1641 +#define RPC_S_INVALID_STRING_BINDING 1700 +#define RPC_S_WRONG_KIND_OF_BINDING 1701 +#define RPC_S_INVALID_BINDING 1702 +#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703 +#define RPC_S_INVALID_RPC_PROTSEQ 1704 +#define RPC_S_INVALID_STRING_UUID 1705 +#define RPC_S_INVALID_ENDPOINT_FORMAT 1706 +#define RPC_S_INVALID_NET_ADDR 1707 +#define RPC_S_NO_ENDPOINT_FOUND 1708 +#define RPC_S_INVALID_TIMEOUT 1709 +#define RPC_S_OBJECT_NOT_FOUND 1710 +#define RPC_S_ALREADY_REGISTERED 1711 +#define RPC_S_TYPE_ALREADY_REGISTERED 1712 +#define RPC_S_ALREADY_LISTENING 1713 +#define RPC_S_NO_PROTSEQS_REGISTERED 1714 +#define RPC_S_NOT_LISTENING 1715 +#define RPC_S_UNKNOWN_MGR_TYPE 1716 +#define RPC_S_UNKNOWN_IF 1717 +#define RPC_S_NO_BINDINGS 1718 +#define RPC_S_NO_PROTSEQS 1719 +#define RPC_S_CANT_CREATE_ENDPOINT 1720 +#define RPC_S_OUT_OF_RESOURCES 1721 +#define RPC_S_SERVER_UNAVAILABLE 1722 +#define RPC_S_SERVER_TOO_BUSY 1723 +#define RPC_S_INVALID_NETWORK_OPTIONS 1724 +#define RPC_S_NO_CALL_ACTIVE 1725 +#define RPC_S_CALL_FAILED 1726 +#define RPC_S_CALL_FAILED_DNE 1727 +#define RPC_S_PROTOCOL_ERROR 1728 +#define RPC_S_UNSUPPORTED_TRANS_SYN 1730 +#define RPC_S_UNSUPPORTED_TYPE 1732 +#define RPC_S_INVALID_TAG 1733 +#define RPC_S_INVALID_BOUND 1734 +#define RPC_S_NO_ENTRY_NAME 1735 +#define RPC_S_INVALID_NAME_SYNTAX 1736 +#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737 +#define RPC_S_UUID_NO_ADDRESS 1739 +#define RPC_S_DUPLICATE_ENDPOINT 1740 +#define RPC_S_UNKNOWN_AUTHN_TYPE 1741 +#define RPC_S_MAX_CALLS_TOO_SMALL 1742 +#define RPC_S_STRING_TOO_LONG 1743 +#define RPC_S_PROTSEQ_NOT_FOUND 1744 +#define RPC_S_PROCNUM_OUT_OF_RANGE 1745 +#define RPC_S_BINDING_HAS_NO_AUTH 1746 +#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747 +#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748 +#define RPC_S_INVALID_AUTH_IDENTITY 1749 +#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750 +#define EPT_S_INVALID_ENTRY 1751 +#define EPT_S_CANT_PERFORM_OP 1752 +#define EPT_S_NOT_REGISTERED 1753 +#define RPC_S_NOTHING_TO_EXPORT 1754 +#define RPC_S_INCOMPLETE_NAME 1755 +#define RPC_S_INVALID_VERS_OPTION 1756 +#define RPC_S_NO_MORE_MEMBERS 1757 +#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758 +#define RPC_S_INTERFACE_NOT_FOUND 1759 +#define RPC_S_ENTRY_ALREADY_EXISTS 1760 +#define RPC_S_ENTRY_NOT_FOUND 1761 +#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762 +#define RPC_S_INVALID_NAF_ID 1763 +#define RPC_S_CANNOT_SUPPORT 1764 +#define RPC_S_NO_CONTEXT_AVAILABLE 1765 +#define RPC_S_INTERNAL_ERROR 1766 +#define RPC_S_ZERO_DIVIDE 1767 +#define RPC_S_ADDRESS_ERROR 1768 +#define RPC_S_FP_DIV_ZERO 1769 +#define RPC_S_FP_UNDERFLOW 1770 +#define RPC_S_FP_OVERFLOW 1771 +#define RPC_X_NO_MORE_ENTRIES 1772 +#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773 +#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774 +#define RPC_X_SS_IN_NULL_CONTEXT 1775 +#define RPC_X_SS_CONTEXT_DAMAGED 1777 +#define RPC_X_SS_HANDLES_MISMATCH 1778 +#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779 +#define RPC_X_NULL_REF_POINTER 1780 +#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781 +#define RPC_X_BYTE_COUNT_TOO_SMALL 1782 +#define RPC_X_BAD_STUB_DATA 1783 +#define ERROR_INVALID_USER_BUFFER 1784 +#define ERROR_UNRECOGNIZED_MEDIA 1785 +#define ERROR_NO_TRUST_LSA_SECRET 1786 +#define ERROR_NO_TRUST_SAM_ACCOUNT 1787 +#define ERROR_TRUSTED_DOMAIN_FAILURE 1788 +#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789 +#define ERROR_TRUST_FAILURE 1790 +#define RPC_S_CALL_IN_PROGRESS 1791 +#define ERROR_NETLOGON_NOT_STARTED 1792 +#define ERROR_ACCOUNT_EXPIRED 1793 +#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794 +#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795 +#define ERROR_UNKNOWN_PORT 1796 +#define ERROR_UNKNOWN_PRINTER_DRIVER 1797 +#define ERROR_UNKNOWN_PRINTPROCESSOR 1798 +#define ERROR_INVALID_SEPARATOR_FILE 1799 +#define ERROR_INVALID_PRIORITY 1800 +#define ERROR_INVALID_PRINTER_NAME 1801 +#define ERROR_PRINTER_ALREADY_EXISTS 1802 +#define ERROR_INVALID_PRINTER_COMMAND 1803 +#define ERROR_INVALID_DATATYPE 1804 +#define ERROR_INVALID_ENVIRONMENT 1805 +#define RPC_S_NO_MORE_BINDINGS 1806 +#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807 +#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808 +#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809 +#define ERROR_DOMAIN_TRUST_INCONSISTENT 1810 +#define ERROR_SERVER_HAS_OPEN_HANDLES 1811 +#define ERROR_RESOURCE_DATA_NOT_FOUND 1812 +#define ERROR_RESOURCE_TYPE_NOT_FOUND 1813 +#define ERROR_RESOURCE_NAME_NOT_FOUND 1814 +#define ERROR_RESOURCE_LANG_NOT_FOUND 1815 +#define ERROR_NOT_ENOUGH_QUOTA 1816 +#define RPC_S_NO_INTERFACES 1817 +#define RPC_S_CALL_CANCELLED 1818 +#define RPC_S_BINDING_INCOMPLETE 1819 +#define RPC_S_COMM_FAILURE 1820 +#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821 +#define RPC_S_NO_PRINC_NAME 1822 +#define RPC_S_NOT_RPC_ERROR 1823 +#define RPC_S_UUID_LOCAL_ONLY 1824 +#define RPC_S_SEC_PKG_ERROR 1825 +#define RPC_S_NOT_CANCELLED 1826 +#define RPC_X_INVALID_ES_ACTION 1827 +#define RPC_X_WRONG_ES_VERSION 1828 +#define RPC_X_WRONG_STUB_VERSION 1829 +#define RPC_X_INVALID_PIPE_OBJECT 1830 +#define RPC_X_WRONG_PIPE_ORDER 1831 +#define RPC_X_WRONG_PIPE_VERSION 1832 +#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898 +#define EPT_S_CANT_CREATE 1899 +#define RPC_S_INVALID_OBJECT 1900 +#define ERROR_INVALID_TIME 1901 +#define ERROR_INVALID_FORM_NAME 1902 +#define ERROR_INVALID_FORM_SIZE 1903 +#define ERROR_ALREADY_WAITING 1904 +#define ERROR_PRINTER_DELETED 1905 +#define ERROR_INVALID_PRINTER_STATE 1906 +#define ERROR_PASSWORD_MUST_CHANGE 1907 +#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908 +#define ERROR_ACCOUNT_LOCKED_OUT 1909 +#define OR_INVALID_OXID 1910 +#define OR_INVALID_OID 1911 +#define OR_INVALID_SET 1912 +#define RPC_S_SEND_INCOMPLETE 1913 +#define RPC_S_INVALID_ASYNC_HANDLE 1914 +#define RPC_S_INVALID_ASYNC_CALL 1915 +#define RPC_X_PIPE_CLOSED 1916 +#define RPC_X_PIPE_DISCIPLINE_ERROR 1917 +#define RPC_X_PIPE_EMPTY 1918 +#define ERROR_NO_SITENAME 1919 +#define ERROR_CANT_ACCESS_FILE 1920 +#define ERROR_CANT_RESOLVE_FILENAME 1921 +#define RPC_S_ENTRY_TYPE_MISMATCH 1922 +#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923 +#define RPC_S_INTERFACE_NOT_EXPORTED 1924 +#define RPC_S_PROFILE_NOT_ADDED 1925 +#define RPC_S_PRF_ELT_NOT_ADDED 1926 +#define RPC_S_PRF_ELT_NOT_REMOVED 1927 +#define RPC_S_GRP_ELT_NOT_ADDED 1928 +#define RPC_S_GRP_ELT_NOT_REMOVED 1929 +#define ERROR_INVALID_PIXEL_FORMAT 2000 +#define ERROR_BAD_DRIVER 2001 +#define ERROR_INVALID_WINDOW_STYLE 2002 +#define ERROR_METAFILE_NOT_SUPPORTED 2003 +#define ERROR_TRANSFORM_NOT_SUPPORTED 2004 +#define ERROR_CLIPPING_NOT_SUPPORTED 2005 +#define ERROR_INVALID_CMM 2010 +#define ERROR_INVALID_PROFILE 2011 +#define ERROR_TAG_NOT_FOUND 2012 +#define ERROR_TAG_NOT_PRESENT 2013 +#define ERROR_DUPLICATE_TAG 2014 +#define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015 +#define ERROR_PROFILE_NOT_FOUND 2016 +#define ERROR_INVALID_COLORSPACE 2017 +#define ERROR_ICM_NOT_ENABLED 2018 +#define ERROR_DELETING_ICM_XFORM 2019 +#define ERROR_INVALID_TRANSFORM 2020 +#define ERROR_COLORSPACE_MISMATCH 2021 +#define ERROR_INVALID_COLORINDEX 2022 +#define ERROR_CONNECTED_OTHER_PASSWORD 2108 +#define ERROR_BAD_USERNAME 2202 +#define ERROR_NOT_CONNECTED 2250 +#define ERROR_OPEN_FILES 2401 +#define ERROR_ACTIVE_CONNECTIONS 2402 +#define ERROR_DEVICE_IN_USE 2404 +#define ERROR_UNKNOWN_PRINT_MONITOR 3000 +#define ERROR_PRINTER_DRIVER_IN_USE 3001 +#define ERROR_SPOOL_FILE_NOT_FOUND 3002 +#define ERROR_SPL_NO_STARTDOC 3003 +#define ERROR_SPL_NO_ADDJOB 3004 +#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005 +#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006 +#define ERROR_INVALID_PRINT_MONITOR 3007 +#define ERROR_PRINT_MONITOR_IN_USE 3008 +#define ERROR_PRINTER_HAS_JOBS_QUEUED 3009 +#define ERROR_SUCCESS_REBOOT_REQUIRED 3010 +#define ERROR_SUCCESS_RESTART_REQUIRED 3011 +#define ERROR_PRINTER_NOT_FOUND 3012 +#define ERROR_WINS_INTERNAL 4000 +#define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001 +#define ERROR_STATIC_INIT 4002 +#define ERROR_INC_BACKUP 4003 +#define ERROR_FULL_BACKUP 4004 +#define ERROR_REC_NON_EXISTENT 4005 +#define ERROR_RPL_NOT_ALLOWED 4006 +#define ERROR_DHCP_ADDRESS_CONFLICT 4100 +#define ERROR_WMI_GUID_NOT_FOUND 4200 +#define ERROR_WMI_INSTANCE_NOT_FOUND 4201 +#define ERROR_WMI_ITEMID_NOT_FOUND 4202 +#define ERROR_WMI_TRY_AGAIN 4203 +#define ERROR_WMI_DP_NOT_FOUND 4204 +#define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205 +#define ERROR_WMI_ALREADY_ENABLED 4206 +#define ERROR_WMI_GUID_DISCONNECTED 4207 +#define ERROR_WMI_SERVER_UNAVAILABLE 4208 +#define ERROR_WMI_DP_FAILED 4209 +#define ERROR_WMI_INVALID_MOF 4210 +#define ERROR_WMI_INVALID_REGINFO 4211 +#define ERROR_WMI_ALREADY_DISABLED 4212 +#define ERROR_WMI_READ_ONLY 4213 +#define ERROR_WMI_SET_FAILURE 4214 +#define ERROR_INVALID_MEDIA 4300 +#define ERROR_INVALID_LIBRARY 4301 +#define ERROR_INVALID_MEDIA_POOL 4302 +#define ERROR_DRIVE_MEDIA_MISMATCH 4303 +#define ERROR_MEDIA_OFFLINE 4304 +#define ERROR_LIBRARY_OFFLINE 4305 +#define ERROR_EMPTY 4306 +#define ERROR_NOT_EMPTY 4307 +#define ERROR_MEDIA_UNAVAILABLE 4308 +#define ERROR_RESOURCE_DISABLED 4309 +#define ERROR_INVALID_CLEANER 4310 +#define ERROR_UNABLE_TO_CLEAN 4311 +#define ERROR_OBJECT_NOT_FOUND 4312 +#define ERROR_DATABASE_FAILURE 4313 +#define ERROR_DATABASE_FULL 4314 +#define ERROR_MEDIA_INCOMPATIBLE 4315 +#define ERROR_RESOURCE_NOT_PRESENT 4316 +#define ERROR_INVALID_OPERATION 4317 +#define ERROR_MEDIA_NOT_AVAILABLE 4318 +#define ERROR_DEVICE_NOT_AVAILABLE 4319 +#define ERROR_REQUEST_REFUSED 4320 +#define ERROR_INVALID_DRIVE_OBJECT 4321 +#define ERROR_LIBRARY_FULL 4322 +#define ERROR_MEDIUM_NOT_ACCESSIBLE 4323 +#define ERROR_UNABLE_TO_LOAD_MEDIUM 4324 +#define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325 +#define ERROR_UNABLE_TO_INVENTORY_SLOT 4326 +#define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327 +#define ERROR_TRANSPORT_FULL 4328 +#define ERROR_CONTROLLING_IEPORT 4329 +#define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330 +#define ERROR_CLEANER_SLOT_SET 4331 +#define ERROR_CLEANER_SLOT_NOT_SET 4332 +#define ERROR_CLEANER_CARTRIDGE_SPENT 4333 +#define ERROR_UNEXPECTED_OMID 4334 +#define ERROR_CANT_DELETE_LAST_ITEM 4335 +#define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336 +#define ERROR_VOLUME_CONTAINS_SYS_FILES 4337 +#define ERROR_INDIGENOUS_TYPE 4338 +#define ERROR_NO_SUPPORTING_DRIVES 4339 +#define ERROR_FILE_OFFLINE 4350 +#define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351 +#define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352 +#define ERROR_NOT_A_REPARSE_POINT 4390 +#define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391 +#define ERROR_INVALID_REPARSE_DATA 4392 +#define ERROR_REPARSE_TAG_INVALID 4393 +#define ERROR_REPARSE_TAG_MISMATCH 4394 +#define ERROR_VOLUME_NOT_SIS_ENABLED 4500 +#define ERROR_DEPENDENT_RESOURCE_EXISTS 5001 +#define ERROR_DEPENDENCY_NOT_FOUND 5002 +#define ERROR_DEPENDENCY_ALREADY_EXISTS 5003 +#define ERROR_RESOURCE_NOT_ONLINE 5004 +#define ERROR_HOST_NODE_NOT_AVAILABLE 5005 +#define ERROR_RESOURCE_NOT_AVAILABLE 5006 +#define ERROR_RESOURCE_NOT_FOUND 5007 +#define ERROR_SHUTDOWN_CLUSTER 5008 +#define ERROR_CANT_EVICT_ACTIVE_NODE 5009 +#define ERROR_OBJECT_ALREADY_EXISTS 5010 +#define ERROR_OBJECT_IN_LIST 5011 +#define ERROR_GROUP_NOT_AVAILABLE 5012 +#define ERROR_GROUP_NOT_FOUND 5013 +#define ERROR_GROUP_NOT_ONLINE 5014 +#define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015 +#define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016 +#define ERROR_RESMON_CREATE_FAILED 5017 +#define ERROR_RESMON_ONLINE_FAILED 5018 +#define ERROR_RESOURCE_ONLINE 5019 +#define ERROR_QUORUM_RESOURCE 5020 +#define ERROR_NOT_QUORUM_CAPABLE 5021 +#define ERROR_CLUSTER_SHUTTING_DOWN 5022 +#define ERROR_INVALID_STATE 5023 +#define ERROR_RESOURCE_PROPERTIES_STORED 5024 +#define ERROR_NOT_QUORUM_CLASS 5025 +#define ERROR_CORE_RESOURCE 5026 +#define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027 +#define ERROR_QUORUMLOG_OPEN_FAILED 5028 +#define ERROR_CLUSTERLOG_CORRUPT 5029 +#define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030 +#define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031 +#define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032 +#define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033 +#define ERROR_QUORUM_OWNER_ALIVE 5034 +#define ERROR_NETWORK_NOT_AVAILABLE 5035 +#define ERROR_NODE_NOT_AVAILABLE 5036 +#define ERROR_ALL_NODES_NOT_AVAILABLE 5037 +#define ERROR_RESOURCE_FAILED 5038 +#define ERROR_CLUSTER_INVALID_NODE 5039 +#define ERROR_CLUSTER_NODE_EXISTS 5040 +#define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041 +#define ERROR_CLUSTER_NODE_NOT_FOUND 5042 +#define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043 +#define ERROR_CLUSTER_NETWORK_EXISTS 5044 +#define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045 +#define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046 +#define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047 +#define ERROR_CLUSTER_INVALID_REQUEST 5048 +#define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049 +#define ERROR_CLUSTER_NODE_DOWN 5050 +#define ERROR_CLUSTER_NODE_UNREACHABLE 5051 +#define ERROR_CLUSTER_NODE_NOT_MEMBER 5052 +#define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053 +#define ERROR_CLUSTER_INVALID_NETWORK 5054 +#define ERROR_CLUSTER_NODE_UP 5056 +#define ERROR_CLUSTER_IPADDR_IN_USE 5057 +#define ERROR_CLUSTER_NODE_NOT_PAUSED 5058 +#define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059 +#define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060 +#define ERROR_CLUSTER_NODE_ALREADY_UP 5061 +#define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062 +#define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063 +#define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064 +#define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065 +#define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066 +#define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067 +#define ERROR_INVALID_OPERATION_ON_QUORUM 5068 +#define ERROR_DEPENDENCY_NOT_ALLOWED 5069 +#define ERROR_CLUSTER_NODE_PAUSED 5070 +#define ERROR_NODE_CANT_HOST_RESOURCE 5071 +#define ERROR_CLUSTER_NODE_NOT_READY 5072 +#define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073 +#define ERROR_CLUSTER_JOIN_ABORTED 5074 +#define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075 +#define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076 +#define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077 +#define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078 +#define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079 +#define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080 +#define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081 +#define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082 +#define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083 +#define ERROR_RESMON_INVALID_STATE 5084 +#define ERROR_CLUSTER_GUM_NOT_LOCKER 5085 +#define ERROR_QUORUM_DISK_NOT_FOUND 5086 +#define ERROR_DATABASE_BACKUP_CORRUPT 5087 +#define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088 +#define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089 +#define ERROR_ENCRYPTION_FAILED 6000 +#define ERROR_DECRYPTION_FAILED 6001 +#define ERROR_FILE_ENCRYPTED 6002 +#define ERROR_NO_RECOVERY_POLICY 6003 +#define ERROR_NO_EFS 6004 +#define ERROR_WRONG_EFS 6005 +#define ERROR_NO_USER_KEYS 6006 +#define ERROR_FILE_NOT_ENCRYPTED 6007 +#define ERROR_NOT_EXPORT_FORMAT 6008 +#define ERROR_FILE_READ_ONLY 6009 +#define ERROR_DIR_EFS_DISALLOWED 6010 +#define ERROR_EFS_SERVER_NOT_TRUSTED 6011 +#define ERROR_NO_BROWSER_SERVERS_FOUND 6118 +#define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200 +#define ERROR_CTX_WINSTATION_NAME_INVALID 7001 +#define ERROR_CTX_INVALID_PD 7002 +#define ERROR_CTX_PD_NOT_FOUND 7003 +#define ERROR_CTX_WD_NOT_FOUND 7004 +#define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005 +#define ERROR_CTX_SERVICE_NAME_COLLISION 7006 +#define ERROR_CTX_CLOSE_PENDING 7007 +#define ERROR_CTX_NO_OUTBUF 7008 +#define ERROR_CTX_MODEM_INF_NOT_FOUND 7009 +#define ERROR_CTX_INVALID_MODEMNAME 7010 +#define ERROR_CTX_MODEM_RESPONSE_ERROR 7011 +#define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012 +#define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013 +#define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014 +#define ERROR_CTX_MODEM_RESPONSE_BUSY 7015 +#define ERROR_CTX_MODEM_RESPONSE_VOICE 7016 +#define ERROR_CTX_TD_ERROR 7017 +#define ERROR_CTX_WINSTATION_NOT_FOUND 7022 +#define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023 +#define ERROR_CTX_WINSTATION_BUSY 7024 +#define ERROR_CTX_BAD_VIDEO_MODE 7025 +#define ERROR_CTX_GRAPHICS_INVALID 7035 +#define ERROR_CTX_LOGON_DISABLED 7037 +#define ERROR_CTX_NOT_CONSOLE 7038 +#define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040 +#define ERROR_CTX_CONSOLE_DISCONNECT 7041 +#define ERROR_CTX_CONSOLE_CONNECT 7042 +#define ERROR_CTX_SHADOW_DENIED 7044 +#define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045 +#define ERROR_CTX_INVALID_WD 7049 +#define ERROR_CTX_SHADOW_INVALID 7050 +#define ERROR_CTX_SHADOW_DISABLED 7051 +#define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052 +#define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053 +#define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054 +#define ERROR_CTX_LICENSE_CLIENT_INVALID 7055 +#define ERROR_CTX_LICENSE_EXPIRED 7056 +#define FRS_ERR_INVALID_API_SEQUENCE 8001 +#define FRS_ERR_STARTING_SERVICE 8002 +#define FRS_ERR_STOPPING_SERVICE 8003 +#define FRS_ERR_INTERNAL_API 8004 +#define FRS_ERR_INTERNAL 8005 +#define FRS_ERR_SERVICE_COMM 8006 +#define FRS_ERR_INSUFFICIENT_PRIV 8007 +#define FRS_ERR_AUTHENTICATION 8008 +#define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009 +#define FRS_ERR_PARENT_AUTHENTICATION 8010 +#define FRS_ERR_CHILD_TO_PARENT_COMM 8011 +#define FRS_ERR_PARENT_TO_CHILD_COMM 8012 +#define FRS_ERR_SYSVOL_POPULATE 8013 +#define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014 +#define FRS_ERR_SYSVOL_IS_BUSY 8015 +#define FRS_ERR_SYSVOL_DEMOTE 8016 +#define FRS_ERR_INVALID_SERVICE_PARAMETER 8017 +#define ERROR_DS_NOT_INSTALLED 8200 +#define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201 +#define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202 +#define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203 +#define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204 +#define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205 +#define ERROR_DS_BUSY 8206 +#define ERROR_DS_UNAVAILABLE 8207 +#define ERROR_DS_NO_RIDS_ALLOCATED 8208 +#define ERROR_DS_NO_MORE_RIDS 8209 +#define ERROR_DS_INCORRECT_ROLE_OWNER 8210 +#define ERROR_DS_RIDMGR_INIT_ERROR 8211 +#define ERROR_DS_OBJ_CLASS_VIOLATION 8212 +#define ERROR_DS_CANT_ON_NON_LEAF 8213 +#define ERROR_DS_CANT_ON_RDN 8214 +#define ERROR_DS_CANT_MOD_OBJ_CLASS 8215 +#define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216 +#define ERROR_DS_GC_NOT_AVAILABLE 8217 +#define ERROR_SHARED_POLICY 8218 +#define ERROR_POLICY_OBJECT_NOT_FOUND 8219 +#define ERROR_POLICY_ONLY_IN_DS 8220 +#define ERROR_PROMOTION_ACTIVE 8221 +#define ERROR_NO_PROMOTION_ACTIVE 8222 +#define ERROR_DS_OPERATIONS_ERROR 8224 +#define ERROR_DS_PROTOCOL_ERROR 8225 +#define ERROR_DS_TIMELIMIT_EXCEEDED 8226 +#define ERROR_DS_SIZELIMIT_EXCEEDED 8227 +#define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228 +#define ERROR_DS_COMPARE_FALSE 8229 +#define ERROR_DS_COMPARE_TRUE 8230 +#define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231 +#define ERROR_DS_STRONG_AUTH_REQUIRED 8232 +#define ERROR_DS_INAPPROPRIATE_AUTH 8233 +#define ERROR_DS_AUTH_UNKNOWN 8234 +#define ERROR_DS_REFERRAL 8235 +#define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236 +#define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237 +#define ERROR_DS_INAPPROPRIATE_MATCHING 8238 +#define ERROR_DS_CONSTRAINT_VIOLATION 8239 +#define ERROR_DS_NO_SUCH_OBJECT 8240 +#define ERROR_DS_ALIAS_PROBLEM 8241 +#define ERROR_DS_INVALID_DN_SYNTAX 8242 +#define ERROR_DS_IS_LEAF 8243 +#define ERROR_DS_ALIAS_DEREF_PROBLEM 8244 +#define ERROR_DS_UNWILLING_TO_PERFORM 8245 +#define ERROR_DS_LOOP_DETECT 8246 +#define ERROR_DS_NAMING_VIOLATION 8247 +#define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248 +#define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249 +#define ERROR_DS_SERVER_DOWN 8250 +#define ERROR_DS_LOCAL_ERROR 8251 +#define ERROR_DS_ENCODING_ERROR 8252 +#define ERROR_DS_DECODING_ERROR 8253 +#define ERROR_DS_FILTER_UNKNOWN 8254 +#define ERROR_DS_PARAM_ERROR 8255 +#define ERROR_DS_NOT_SUPPORTED 8256 +#define ERROR_DS_NO_RESULTS_RETURNED 8257 +#define ERROR_DS_CONTROL_NOT_FOUND 8258 +#define ERROR_DS_CLIENT_LOOP 8259 +#define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260 +#define ERROR_DS_ROOT_MUST_BE_NC 8301 +#define ERROR_DS_ADD_REPLICA_INHIBITED 8302 +#define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303 +#define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304 +#define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305 +#define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306 +#define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307 +#define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308 +#define ERROR_DS_USER_BUFFER_TO_SMALL 8309 +#define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310 +#define ERROR_DS_ILLEGAL_MOD_OPERATION 8311 +#define ERROR_DS_OBJ_TOO_LARGE 8312 +#define ERROR_DS_BAD_INSTANCE_TYPE 8313 +#define ERROR_DS_MASTERDSA_REQUIRED 8314 +#define ERROR_DS_OBJECT_CLASS_REQUIRED 8315 +#define ERROR_DS_MISSING_REQUIRED_ATT 8316 +#define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317 +#define ERROR_DS_ATT_ALREADY_EXISTS 8318 +#define ERROR_DS_CANT_ADD_ATT_VALUES 8320 +#define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321 +#define ERROR_DS_RANGE_CONSTRAINT 8322 +#define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323 +#define ERROR_DS_CANT_REM_MISSING_ATT 8324 +#define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325 +#define ERROR_DS_ROOT_CANT_BE_SUBREF 8326 +#define ERROR_DS_NO_CHAINING 8327 +#define ERROR_DS_NO_CHAINED_EVAL 8328 +#define ERROR_DS_NO_PARENT_OBJECT 8329 +#define ERROR_DS_PARENT_IS_AN_ALIAS 8330 +#define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331 +#define ERROR_DS_CHILDREN_EXIST 8332 +#define ERROR_DS_OBJ_NOT_FOUND 8333 +#define ERROR_DS_ALIASED_OBJ_MISSING 8334 +#define ERROR_DS_BAD_NAME_SYNTAX 8335 +#define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336 +#define ERROR_DS_CANT_DEREF_ALIAS 8337 +#define ERROR_DS_OUT_OF_SCOPE 8338 +#define ERROR_DS_CANT_DELETE_DSA_OBJ 8340 +#define ERROR_DS_GENERIC_ERROR 8341 +#define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342 +#define ERROR_DS_CLASS_NOT_DSA 8343 +#define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344 +#define ERROR_DS_ILLEGAL_SUPERIOR 8345 +#define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346 +#define ERROR_DS_NAME_TOO_MANY_PARTS 8347 +#define ERROR_DS_NAME_TOO_LONG 8348 +#define ERROR_DS_NAME_VALUE_TOO_LONG 8349 +#define ERROR_DS_NAME_UNPARSEABLE 8350 +#define ERROR_DS_NAME_TYPE_UNKNOWN 8351 +#define ERROR_DS_NOT_AN_OBJECT 8352 +#define ERROR_DS_SEC_DESC_TOO_SHORT 8353 +#define ERROR_DS_SEC_DESC_INVALID 8354 +#define ERROR_DS_NO_DELETED_NAME 8355 +#define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356 +#define ERROR_DS_NCNAME_MUST_BE_NC 8357 +#define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358 +#define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359 +#define ERROR_DS_INVALID_DMD 8360 +#define ERROR_DS_OBJ_GUID_EXISTS 8361 +#define ERROR_DS_NOT_ON_BACKLINK 8362 +#define ERROR_DS_NO_CROSSREF_FOR_NC 8363 +#define ERROR_DS_SHUTTING_DOWN 8364 +#define ERROR_DS_UNKNOWN_OPERATION 8365 +#define ERROR_DS_INVALID_ROLE_OWNER 8366 +#define ERROR_DS_COULDNT_CONTACT_FSMO 8367 +#define ERROR_DS_CROSS_NC_DN_RENAME 8368 +#define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369 +#define ERROR_DS_REPLICATOR_ONLY 8370 +#define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371 +#define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372 +#define ERROR_DS_NAME_REFERENCE_INVALID 8373 +#define ERROR_DS_CROSS_REF_EXISTS 8374 +#define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375 +#define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376 +#define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377 +#define ERROR_DS_DUP_RDN 8378 +#define ERROR_DS_DUP_OID 8379 +#define ERROR_DS_DUP_MAPI_ID 8380 +#define ERROR_DS_DUP_SCHEMA_ID_GUID 8381 +#define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382 +#define ERROR_DS_SEMANTIC_ATT_TEST 8383 +#define ERROR_DS_SYNTAX_MISMATCH 8384 +#define ERROR_DS_EXISTS_IN_MUST_HAVE 8385 +#define ERROR_DS_EXISTS_IN_MAY_HAVE 8386 +#define ERROR_DS_NONEXISTENT_MAY_HAVE 8387 +#define ERROR_DS_NONEXISTENT_MUST_HAVE 8388 +#define ERROR_DS_AUX_CLS_TEST_FAIL 8389 +#define ERROR_DS_NONEXISTENT_POSS_SUP 8390 +#define ERROR_DS_SUB_CLS_TEST_FAIL 8391 +#define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392 +#define ERROR_DS_EXISTS_IN_AUX_CLS 8393 +#define ERROR_DS_EXISTS_IN_SUB_CLS 8394 +#define ERROR_DS_EXISTS_IN_POSS_SUP 8395 +#define ERROR_DS_RECALCSCHEMA_FAILED 8396 +#define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397 +#define ERROR_DS_CANT_DELETE 8398 +#define ERROR_DS_ATT_SCHEMA_REQ_ID 8399 +#define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400 +#define ERROR_DS_CANT_CACHE_ATT 8401 +#define ERROR_DS_CANT_CACHE_CLASS 8402 +#define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403 +#define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404 +#define ERROR_DS_CANT_RETRIEVE_DN 8405 +#define ERROR_DS_MISSING_SUPREF 8406 +#define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407 +#define ERROR_DS_CODE_INCONSISTENCY 8408 +#define ERROR_DS_DATABASE_ERROR 8409 +#define ERROR_DS_GOVERNSID_MISSING 8410 +#define ERROR_DS_MISSING_EXPECTED_ATT 8411 +#define ERROR_DS_NCNAME_MISSING_CR_REF 8412 +#define ERROR_DS_SECURITY_CHECKING_ERROR 8413 +#define ERROR_DS_SCHEMA_NOT_LOADED 8414 +#define ERROR_DS_SCHEMA_ALLOC_FAILED 8415 +#define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416 +#define ERROR_DS_GCVERIFY_ERROR 8417 +#define ERROR_DS_DRA_SCHEMA_MISMATCH 8418 +#define ERROR_DS_CANT_FIND_DSA_OBJ 8419 +#define ERROR_DS_CANT_FIND_EXPECTED_NC 8420 +#define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421 +#define ERROR_DS_CANT_RETRIEVE_CHILD 8422 +#define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423 +#define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424 +#define ERROR_DS_BAD_HIERARCHY_FILE 8425 +#define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426 +#define ERROR_DS_CONFIG_PARAM_MISSING 8427 +#define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428 +#define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429 +#define ERROR_DS_INTERNAL_FAILURE 8430 +#define ERROR_DS_UNKNOWN_ERROR 8431 +#define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432 +#define ERROR_DS_REFUSING_FSMO_ROLES 8433 +#define ERROR_DS_MISSING_FSMO_SETTINGS 8434 +#define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435 +#define ERROR_DS_DRA_GENERIC 8436 +#define ERROR_DS_DRA_INVALID_PARAMETER 8437 +#define ERROR_DS_DRA_BUSY 8438 +#define ERROR_DS_DRA_BAD_DN 8439 +#define ERROR_DS_DRA_BAD_NC 8440 +#define ERROR_DS_DRA_DN_EXISTS 8441 +#define ERROR_DS_DRA_INTERNAL_ERROR 8442 +#define ERROR_DS_DRA_INCONSISTENT_DIT 8443 +#define ERROR_DS_DRA_CONNECTION_FAILED 8444 +#define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445 +#define ERROR_DS_DRA_OUT_OF_MEM 8446 +#define ERROR_DS_DRA_MAIL_PROBLEM 8447 +#define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448 +#define ERROR_DS_DRA_REF_NOT_FOUND 8449 +#define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450 +#define ERROR_DS_DRA_DB_ERROR 8451 +#define ERROR_DS_DRA_NO_REPLICA 8452 +#define ERROR_DS_DRA_ACCESS_DENIED 8453 +#define ERROR_DS_DRA_NOT_SUPPORTED 8454 +#define ERROR_DS_DRA_RPC_CANCELLED 8455 +#define ERROR_DS_DRA_SOURCE_DISABLED 8456 +#define ERROR_DS_DRA_SINK_DISABLED 8457 +#define ERROR_DS_DRA_NAME_COLLISION 8458 +#define ERROR_DS_DRA_SOURCE_REINSTALLED 8459 +#define ERROR_DS_DRA_MISSING_PARENT 8460 +#define ERROR_DS_DRA_PREEMPTED 8461 +#define ERROR_DS_DRA_ABANDON_SYNC 8462 +#define ERROR_DS_DRA_SHUTDOWN 8463 +#define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464 +#define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465 +#define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466 +#define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467 +#define ERROR_DS_DUP_LINK_ID 8468 +#define ERROR_DS_NAME_ERROR_RESOLVING 8469 +#define ERROR_DS_NAME_ERROR_NOT_FOUND 8470 +#define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471 +#define ERROR_DS_NAME_ERROR_NO_MAPPING 8472 +#define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473 +#define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474 +#define ERROR_DS_CONSTRUCTED_ATT_MOD 8475 +#define ERROR_DS_WRONG_OM_OBJ_CLASS 8476 +#define ERROR_DS_DRA_REPL_PENDING 8477 +#define ERROR_DS_DS_REQUIRED 8478 +#define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479 +#define ERROR_DS_NON_BASE_SEARCH 8480 +#define ERROR_DS_CANT_RETRIEVE_ATTS 8481 +#define ERROR_DS_BACKLINK_WITHOUT_LINK 8482 +#define ERROR_DS_EPOCH_MISMATCH 8483 +#define ERROR_DS_SRC_NAME_MISMATCH 8484 +#define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485 +#define ERROR_DS_DST_NC_MISMATCH 8486 +#define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487 +#define ERROR_DS_SRC_GUID_MISMATCH 8488 +#define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489 +#define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490 +#define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491 +#define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492 +#define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493 +#define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494 +#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495 +#define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496 +#define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497 +#define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498 +#define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499 +#define ERROR_DS_INVALID_SEARCH_FLAG 8500 +#define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501 +#define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502 +#define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503 +#define ERROR_DS_SAM_INIT_FAILURE 8504 +#define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505 +#define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506 +#define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507 +#define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508 +#define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509 +#define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510 +#define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511 +#define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512 +#define ERROR_DS_INVALID_GROUP_TYPE 8513 +#define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514 +#define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515 +#define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516 +#define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517 +#define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518 +#define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519 +#define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520 +#define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521 +#define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522 +#define ERROR_DS_NAMING_MASTER_GC 8523 +#define ERROR_DS_LOOKUP_FAILURE 8524 +#define ERROR_DS_COULDNT_UPDATE_SPNS 8525 +#define ERROR_DS_CANT_RETRIEVE_SD 8526 +#define ERROR_DS_KEY_NOT_UNIQUE 8527 +#define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528 +#define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529 +#define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530 +#define ERROR_DS_CANT_START 8531 +#define ERROR_DS_INIT_FAILURE 8532 +#define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533 +#define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534 +#define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535 +#define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536 +#define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537 +#define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538 +#define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539 +#define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540 +#define ERROR_SAM_INIT_FAILURE 8541 +#define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542 +#define ERROR_DS_DRA_SCHEMA_CONFLICT 8543 +#define ERROR_DS_DRA_EARLIER_SCHEMA_CONLICT 8544 +#define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545 +#define ERROR_DS_NC_STILL_HAS_DSAS 8546 +#define ERROR_DS_GC_REQUIRED 8547 +#define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548 +#define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549 +#define ERROR_DS_CANT_ADD_TO_GC 8550 +#define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551 +#define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552 +#define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553 +#define ERROR_DS_INVALID_NAME_FOR_SPN 8554 +#define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555 +#define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556 +#define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557 +#define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558 +#define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559 +#define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560 +#define DNS_ERROR_RCODE_FORMAT_ERROR 9001 +#define DNS_ERROR_RCODE_SERVER_FAILURE 9002 +#define DNS_ERROR_RCODE_NAME_ERROR 9003 +#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004 +#define DNS_ERROR_RCODE_REFUSED 9005 +#define DNS_ERROR_RCODE_YXDOMAIN 9006 +#define DNS_ERROR_RCODE_YXRRSET 9007 +#define DNS_ERROR_RCODE_NXRRSET 9008 +#define DNS_ERROR_RCODE_NOTAUTH 9009 +#define DNS_ERROR_RCODE_NOTZONE 9010 +#define DNS_ERROR_RCODE_BADSIG 9016 +#define DNS_ERROR_RCODE_BADKEY 9017 +#define DNS_ERROR_RCODE_BADTIME 9018 +#define DNS_INFO_NO_RECORDS 9501 +#define DNS_ERROR_BAD_PACKET 9502 +#define DNS_ERROR_NO_PACKET 9503 +#define DNS_ERROR_RCODE 9504 +#define DNS_ERROR_UNSECURE_PACKET 9505 +#define DNS_ERROR_INVALID_TYPE 9551 +#define DNS_ERROR_INVALID_IP_ADDRESS 9552 +#define DNS_ERROR_INVALID_PROPERTY 9553 +#define DNS_ERROR_TRY_AGAIN_LATER 9554 +#define DNS_ERROR_NOT_UNIQUE 9555 +#define DNS_ERROR_NON_RFC_NAME 9556 +#define DNS_STATUS_FQDN 9557 +#define DNS_STATUS_DOTTED_NAME 9558 +#define DNS_STATUS_SINGLE_PART_NAME 9559 +#define DNS_ERROR_INVALID_NAME_CHAR 9560 +#define DNS_ERROR_NUMERIC_NAME 9561 +#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601 +#define DNS_ERROR_NO_ZONE_INFO 9602 +#define DNS_ERROR_INVALID_ZONE_OPERATION 9603 +#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604 +#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605 +#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606 +#define DNS_ERROR_ZONE_LOCKED 9607 +#define DNS_ERROR_ZONE_CREATION_FAILED 9608 +#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609 +#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610 +#define DNS_ERROR_INVALID_ZONE_TYPE 9611 +#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612 +#define DNS_ERROR_ZONE_NOT_SECONDARY 9613 +#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614 +#define DNS_ERROR_WINS_INIT_FAILED 9615 +#define DNS_ERROR_NEED_WINS_SERVERS 9616 +#define DNS_ERROR_NBSTAT_INIT_FAILED 9617 +#define DNS_ERROR_SOA_DELETE_INVALID 9618 +#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651 +#define DNS_ERROR_INVALID_DATAFILE_NAME 9652 +#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653 +#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654 +#define DNS_ERROR_DATAFILE_PARSING 9655 +#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701 +#define DNS_ERROR_RECORD_FORMAT 9702 +#define DNS_ERROR_NODE_CREATION_FAILED 9703 +#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704 +#define DNS_ERROR_RECORD_TIMED_OUT 9705 +#define DNS_ERROR_NAME_NOT_IN_ZONE 9706 +#define DNS_ERROR_CNAME_LOOP 9707 +#define DNS_ERROR_NODE_IS_CNAME 9708 +#define DNS_ERROR_CNAME_COLLISION 9709 +#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710 +#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711 +#define DNS_ERROR_SECONDARY_DATA 9712 +#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713 +#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714 +#define DNS_WARNING_PTR_CREATE_FAILED 9715 +#define DNS_WARNING_DOMAIN_UNDELETED 9716 +#define DNS_ERROR_DS_UNAVAILABLE 9717 +#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718 +#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719 +#define DNS_INFO_AXFR_COMPLETE 9751 +#define DNS_ERROR_AXFR 9752 +#define DNS_INFO_ADDED_LOCAL_WINS 9753 +#define DNS_STATUS_CONTINUE_NEEDED 9801 +#define DNS_ERROR_NO_TCPIP 9851 +#define DNS_ERROR_NO_DNS_SERVERS 9852 + +/* HRESULT values for OLE, SHELL and other Interface stuff */ +/* the codes 4000-40ff are reserved for OLE */ +#define NOERROR 0L +#define S_OK ((HRESULT)0L) +#define S_FALSE ((HRESULT)1L) + +#define DISP_E_UNKNOWNINTERFACE 0x80020001L +#define DISP_E_MEMBERNOTFOUND 0x80020003L +#define DISP_E_PARAMNOTFOUND 0x80020004L +#define DISP_E_TYPEMISMATCH 0x80020005L +#define DISP_E_UNKNOWNNAME 0x80020006L +#define DISP_E_NONAMEDARGS 0x80020007L +#define DISP_E_BADVARTYPE 0x80020008L +#define DISP_E_EXCEPTION 0x80020009L +#define DISP_E_OVERFLOW 0x8002000AL +#define DISP_E_BADINDEX 0x8002000BL +#define DISP_E_UNKNOWNLCID 0x8002000CL +#define DISP_E_ARRAYISLOCKED 0x8002000DL +#define DISP_E_BADPARAMCOUNT 0x8002000EL +#define DISP_E_PARAMNOTOPTIONAL 0x8002000FL + +#define TYPE_E_ELEMENTNOTFOUND 0x8002802BL +#define TYPE_E_CANTLOADLIBRARY 0x80029C4AL + +/* OLE Clipboard */ +#define CLIPBRD_E_FIRST 0x800401D0L +#define CLIPBRD_E_LAST 0x800401DFL +#define CLIPBRD_S_FIRST 0x000401D0L +#define CLIPBRD_S_LAST 0x000401DFL +#define CLIPBRD_E_CANT_OPEN 0x800401D0L +#define CLIPBRD_E_CANT_EMPTY 0x800401D1L +#define CLIPBRD_E_CANT_SET 0x800401D2L +#define CLIPBRD_E_BAD_DATA 0x800401D3L +#define CLIPBRD_E_CANT_CLOSE 0x800401D4L + +/* Drag and Drop */ +#define DRAGDROP_S_DROP 0x00040100L +#define DRAGDROP_S_CANCEL 0x00040101L +#define DRAGDROP_E_NOTREGISTERED 0x80040100L +#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L +#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L + +#define E_UNEXPECTED 0x8000FFFF + +#define E_NOTIMPL 0x80004001 +#define E_NOINTERFACE 0x80004002 +#define E_POINTER 0x80004003 +#define E_ABORT 0x80004004 +#define E_FAIL 0x80004005 +#define E_UNSPEC E_FAIL /* must to be defined (used by FileMoniker, IOleLink and DoDragDrop as a return value) */ + +/*#define CO_E_INIT_TLS 0x80004006 +#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007 +#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008 +#define CO_E_INIT_CLASS_CACHE 0x80004009 +#define CO_E_INIT_RPC_CHANNEL 0x8000400A +#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400B +#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400C +#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400D +#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400E +#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400F +#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010 +#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011 +#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012 */ + +#define CO_S_NOTALLINTERFACES 0x00080012 +#define CO_E_NOTINITIALIZED 0x800401F0 +#define CO_E_ERRORINDLL 0x800401F9 +#define CO_E_OBJISREG 0x800401FB + +#define OLE_E_FIRST 0x80040000L +#define OLE_E_LAST 0x800400FFL +#define OLE_S_FIRST 0x00040000L +#define OLE_S_LAST 0x000400FFL + +#define OLE_E_ENUM_NOMORE 0x80040002 +#define OLE_E_ADVISENOTSUPPORTED 0x80040003 +#define OLE_E_NOCONNECTION 0x80040004 +#define OLE_E_NOTRUNNING 0x80040005 +#define OLE_E_NOCACHE 0x80040006 +#define OLE_E_BLANK 0x80040007 +#define OLE_E_NOT_INPLACEACTIVE 0x80040010 +#define OLE_E_STATIC 0x8004000B +#define OLE_E_PROMPTSAVECANCELLED 0x8004000C +#define OLE_S_USEREG 0x00040000 +#define OLE_S_STATIC 0x00040001 + +#define DV_E_FORMATETC 0x80040064 +#define DV_E_DVASPECT 0x8004006B +#define DV_E_LINDEX 0x80040068 +#define DV_E_TYMED 0x80040069 + +#define CLASS_E_NOAGGREGATION 0x80040110 +#define CLASS_E_CLASSNOTAVAILABLE 0x80040111 + +#define DATA_S_SAMEFORMATETC 0x80040130 + +#define E_ACCESSDENIED 0x80070005 +#define E_HANDLE 0x80070006 +#define E_OUTOFMEMORY 0x8007000E +#define E_INVALIDARG 0x80070057 + +/*#define OLE_E_FIRST 0x80040000L */ +/*#define OLE_E_LAST 0x800400FFL */ +/*#define OLE_S_FIRST 0x00040000L */ +/*#define OLE_S_LAST 0x000400FFL */ + +#define MK_S_REDUCED_TO_SELF 0x000401E2 +#define MK_S_ME 0x000401E4 +#define MK_S_HIM 0x000401E5 +#define MK_S_US 0x000401E6 +#define MK_S_MONIKERALREADYREGISTERED 0x000401E7 + +#define MK_E_EXCEEDEDDEADLINE 0x800401E1 +#define MK_E_NEEDGENERIC 0x800401E2 +#define MK_E_UNAVAILABLE 0x800401E3 +#define MK_E_SYNTAX 0x800401E4 +#define MK_E_NOOBJECT 0x800401E5 +#define MK_E_INVALIDEXTENSION 0x800401E6 +#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7 +#define MK_E_NOTBINDABLE 0x800401E8 +#define MK_E_NOTBOUND 0x800401E9 +#define MK_E_CANTOPENFILE 0x800401EA +#define MK_E_MIUSTBOTHERUSER 0x800401EB +#define MK_E_NOINVERSE 0x800401EC +#define MK_E_NOSTORAGE 0x800401ED +#define MK_E_NOPREFIX 0x800401EE + +#define STG_E_INVALIDFUNCTION 0x80030001 +#define STG_E_FILENOTFOUND 0x80030002 +#define STG_E_PATHNOTFOUND 0x80030003 +#define STG_E_TOOMANYOPENFILES 0x80030004 +#define STG_E_ACCESSDENIED 0x80030005 +#define STG_E_INVALIDHANDLE 0x80030006 +#define STG_E_INSUFFICIENTMEMORY 0x80030008 +#define STG_E_INVALIDPOINTER 0x80030009 +#define STG_E_NOMOREFILES 0x80030012 +#define STG_E_DISKISWRITEPROTECTED 0x80030013 +#define STG_E_SEEKERROR 0x80030019 +#define STG_E_WRITEFAULT 0x8003001D +#define STG_E_READFAULT 0x8003001E +#define STG_E_SHAREVIOLATION 0x80030020 +#define STG_E_LOCKVIOLATION 0x80030021 +#define STG_E_FILEALREADYEXISTS 0x80030050 +#define STG_E_INVALIDPARAMETER 0x80030057 +#define STG_E_MEDIUMFULL 0x80030070 +#define STG_E_ABNORMALAPIEXIT 0x800300FA +#define STG_E_INVALIDHEADER 0x800300FB +#define STG_E_INVALIDNAME 0x800300FC +#define STG_E_UNKNOWN 0x800300FD +#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FE +#define STG_E_INVALIDFLAG 0x800300FF +#define STG_E_INUSE 0x80030100 +#define STG_E_NOTCURRENT 0x80030101 +#define STG_E_REVERTED 0x80030102 +#define STG_E_CANTSAVE 0x80030103 +#define STG_E_OLDFORMAT 0x80030104 +#define STG_E_OLDDLL 0x80030105 +#define STG_E_SHAREREQUIRED 0x80030106 +#define STG_E_NOTFILEBASEDSTORAGE 0x80030107 +#define STG_E_EXTANTMARSHALLINGS 0x80030108 + +#define CONVERT10_E_OLESTREAM_GET 0x800401C0 +#define CONVERT10_E_OLESTREAM_PUT 0x800401C1 +#define CONVERT10_E_OLESTREAM_FMT 0x800401C2 +#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3 +#define CONVERT10_E_STG_FMT 0x800401C4 +#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5 +#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6 + +/* alten versionen +#define E_NOTIMPL 0x80000001 +#define E_OUTOFMEMORY 0x80000002 +#define E_INVALIDARG 0x80000003 +#define E_NOINTERFACE 0x80000004 +#define E_POINTER 0x80000005 +#define E_HANDLE 0x80000006 +#define E_ABORT 0x80000007 +#define E_FAIL 0x80000008 +#define E_ACCESSDENIED 0x80000009 */ + +/* Obtained from lcc-win32 include files */ +#define GDI_ERROR 0xffffffff + + +/* registry errors */ +#define REGDB_E_READREGDB 0x80040150 +#define REGDB_E_CLASSNOTREG 0x80040154 + +#define INPLACE_E_NOTUNDOABLE 0x800401A0 +#define INPLACE_E_NOTOOLSPACE 0x800401A1 + +#define DATA_E_FORMATETC DV_E_FORMATETC + +#define CLASSFACTORY_E_FIRST 0x80040110L +#define CLASSFACTORY_E_LAST 0x8004011FL +#define CLASSFACTORY_S_FIRST 0x80040110L +#define CLASSFACTORY_S_LAST 0x8004011FL + +#define CLASS_E_NOTLICENSED (CLASSFACTORY_E_FIRST+2) +#define CLASS_E_NOAGGREGATION 0x80040110 +#define CLASS_E_CLASSNOTAVAILABLE 0x80040111 + + +#define OLEOBJ_E_NOVERBS 0x00040180L +#define OLEOBJ_E_INVALIDVERB 0x00040181L +#define OLEOBJ_S_INVALIDVERB 0x00040180L + +#endif /* __WINE_WINERROR_H */ diff --git a/linphone/win32acm/wine/winestring.h b/linphone/win32acm/wine/winestring.h new file mode 100644 index 000000000..5b66dc803 --- /dev/null +++ b/linphone/win32acm/wine/winestring.h @@ -0,0 +1,13 @@ +#ifndef __WINE_WINE_WINESTRING_H +#define __WINE_WINE_WINESTRING_H + +#include "windef.h" + +LPWSTR WINAPI lstrcpyAtoW(LPWSTR,LPCSTR); +LPSTR WINAPI lstrcpyWtoA(LPSTR,LPCWSTR); +LPWSTR WINAPI lstrcpynAtoW(LPWSTR,LPCSTR,INT); +LPSTR WINAPI lstrcpynWtoA(LPSTR,LPCWSTR,INT); + +#define lstrncmpiA strncasecmp + +#endif /* __WINE_WINE_WINESTRING_H */ diff --git a/linphone/win32acm/wine/winnt.h b/linphone/win32acm/wine/winnt.h new file mode 100644 index 000000000..401c39889 --- /dev/null +++ b/linphone/win32acm/wine/winnt.h @@ -0,0 +1,2668 @@ +/* + * Win32 definitions for Windows NT + * + * Copyright 1996 Alexandre Julliard + */ + +#ifndef __WINE_WINNT_H +#define __WINE_WINNT_H + +#include "windef.h" + +#ifndef RC_INVOKED +#include +#endif + +#include "pshpack1.h" +/* Defines */ + +/* Argument 1 passed to the DllEntryProc. */ +#define DLL_PROCESS_DETACH 0 /* detach process (unload library) */ +#define DLL_PROCESS_ATTACH 1 /* attach process (load library) */ +#define DLL_THREAD_ATTACH 2 /* attach new thread */ +#define DLL_THREAD_DETACH 3 /* detach thread */ + + +/* u.x.wProcessorArchitecture (NT) */ +#define PROCESSOR_ARCHITECTURE_INTEL 0 +#define PROCESSOR_ARCHITECTURE_MIPS 1 +#define PROCESSOR_ARCHITECTURE_ALPHA 2 +#define PROCESSOR_ARCHITECTURE_PPC 3 +#define PROCESSOR_ARCHITECTURE_SHX 4 +#define PROCESSOR_ARCHITECTURE_ARM 5 +#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF + +/* dwProcessorType */ +#define PROCESSOR_INTEL_386 386 +#define PROCESSOR_INTEL_486 486 +#define PROCESSOR_INTEL_PENTIUM 586 +#define PROCESSOR_INTEL_860 860 +#define PROCESSOR_MIPS_R2000 2000 +#define PROCESSOR_MIPS_R3000 3000 +#define PROCESSOR_MIPS_R4000 4000 +#define PROCESSOR_ALPHA_21064 21064 +#define PROCESSOR_PPC_601 601 +#define PROCESSOR_PPC_603 603 +#define PROCESSOR_PPC_604 604 +#define PROCESSOR_PPC_620 620 +#define PROCESSOR_HITACHI_SH3 10003 +#define PROCESSOR_HITACHI_SH3E 10004 +#define PROCESSOR_HITACHI_SH4 10005 +#define PROCESSOR_MOTOROLA_821 821 +#define PROCESSOR_SHx_SH3 103 +#define PROCESSOR_SHx_SH4 104 +#define PROCESSOR_STRONGARM 2577 +#define PROCESSOR_ARM720 1824 /* 0x720 */ +#define PROCESSOR_ARM820 2080 /* 0x820 */ +#define PROCESSOR_ARM920 2336 /* 0x920 */ +#define PROCESSOR_ARM_7TDMI 70001 + +#define ANYSIZE_ARRAY 1 + +#define MINCHAR 0x80 +#define MAXCHAR 0x7f +#define MINSHORT 0x8000 +#define MAXSHORT 0x7fff +#define MINLONG 0x80000000 +#define MAXLONG 0x7fffffff +#define MAXBYTE 0xff +#define MAXWORD 0xffff +#define MAXDWORD 0xffffffff + +#define FIELD_OFFSET(type, field) \ + ((LONG)(INT)&(((type *)0)->field)) + +#define CONTAINING_RECORD(address, type, field) \ + ((type *)((PCHAR)(address) - (PCHAR)(&((type *)0)->field))) + +/* Types */ + +/* TCHAR data types definitions for Winelib. */ +/* These types are _not_ defined for the emulator, because they */ +/* depend on the UNICODE macro that only exists in user's code. */ + +//#ifndef __WINE__ +# ifdef UNICODE +typedef WCHAR TCHAR, *PTCHAR; +typedef LPWSTR PTSTR, LPTSTR; +typedef LPCWSTR PCTSTR, LPCTSTR; +#define __TEXT(string) L##string /*probably wrong */ +# else /* UNICODE */ +typedef char TCHAR, *PTCHAR; +typedef LPSTR PTSTR, LPTSTR; +typedef LPCSTR PCTSTR, LPCTSTR; +#define __TEXT(string) string +# endif /* UNICODE */ +//#endif /* __WINE__ */ +#define TEXT(quote) __TEXT(quote) + +typedef BYTE BOOLEAN; +typedef BOOLEAN *PBOOLEAN; + +typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; +} LIST_ENTRY, *PLIST_ENTRY; + +typedef struct _SINGLE_LIST_ENTRY { + struct _SINGLE_LIST_ENTRY *Next; +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; + +/* Heap flags */ + +#define HEAP_NO_SERIALIZE 0x00000001 +#define HEAP_GROWABLE 0x00000002 +#define HEAP_GENERATE_EXCEPTIONS 0x00000004 +#define HEAP_ZERO_MEMORY 0x00000008 +#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 +#define HEAP_TAIL_CHECKING_ENABLED 0x00000020 +#define HEAP_FREE_CHECKING_ENABLED 0x00000040 +#define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 +#define HEAP_CREATE_ALIGN_16 0x00010000 +#define HEAP_CREATE_ENABLE_TRACING 0x00020000 +#define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */ +#define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */ +#define HEAP_WINE_CODE16SEG 0x04000000 /* Not a Win32 flag */ +#define HEAP_WINE_SHARED 0x08000000 /* Not a Win32 flag */ + +/* Processor feature flags. */ +#define PF_FLOATING_POINT_PRECISION_ERRATA 0 +#define PF_FLOATING_POINT_EMULATED 1 +#define PF_COMPARE_EXCHANGE_DOUBLE 2 +#define PF_MMX_INSTRUCTIONS_AVAILABLE 3 +#define PF_PPC_MOVEMEM_64BIT_OK 4 +#define PF_ALPHA_BYTE_INSTRUCTIONS 5 +/* based on wine-20010510 -- alex */ +#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6 +#define PF_AMD3D_INSTRUCTIONS_AVAILABLE 7 +#define PF_RDTSC_INSTRUCTION_AVAILABLE 8 + +/* The Win32 register context */ + +/* CONTEXT is the CPU-dependent context; it should be used */ +/* wherever a platform-specific context is needed (e.g. exception */ +/* handling, Win32 register functions). */ + +/* CONTEXT86 is the i386-specific context; it should be used */ +/* wherever only a 386 context makes sense (e.g. DOS interrupts, */ +/* Win16 register functions), so that this code can be compiled */ +/* on all platforms. */ + +#define SIZE_OF_80387_REGISTERS 80 + +typedef struct _FLOATING_SAVE_AREA +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; + DWORD Cr0NpxState; +} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; + +typedef struct _CONTEXT86 +{ + DWORD ContextFlags; + + /* These are selected by CONTEXT_DEBUG_REGISTERS */ + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + + /* These are selected by CONTEXT_FLOATING_POINT */ + FLOATING_SAVE_AREA FloatSave; + + /* These are selected by CONTEXT_SEGMENTS */ + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + + /* These are selected by CONTEXT_INTEGER */ + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + + /* These are selected by CONTEXT_CONTROL */ + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; +} CONTEXT86; + +#define CONTEXT_X86 0x00010000 +#define CONTEXT_i386 CONTEXT_X86 +#define CONTEXT_i486 CONTEXT_X86 + +#define CONTEXT86_CONTROL (CONTEXT_i386 | 0x0001) /* SS:SP, CS:IP, FLAGS, BP */ +#define CONTEXT86_INTEGER (CONTEXT_i386 | 0x0002) /* AX, BX, CX, DX, SI, DI */ +#define CONTEXT86_SEGMENTS (CONTEXT_i386 | 0x0004) /* DS, ES, FS, GS */ +#define CONTEXT86_FLOATING_POINT (CONTEXT_i386 | 0x0008L) /* 387 state */ +#define CONTEXT86_DEBUG_REGISTERS (CONTEXT_i386 | 0x0010L) /* DB 0-3,6,7 */ +#define CONTEXT86_FULL (CONTEXT86_CONTROL | CONTEXT86_INTEGER | CONTEXT86_SEGMENTS) + +/* i386 context definitions */ +#ifdef __i386__ + +#define CONTEXT_CONTROL CONTEXT86_CONTROL +#define CONTEXT_INTEGER CONTEXT86_INTEGER +#define CONTEXT_SEGMENTS CONTEXT86_SEGMENTS +#define CONTEXT_FLOATING_POINT CONTEXT86_FLOATING_POINT +#define CONTEXT_DEBUG_REGISTERS CONTEXT86_DEBUG_REGISTERS +#define CONTEXT_FULL CONTEXT86_FULL + +typedef CONTEXT86 CONTEXT; + +#endif /* __i386__ */ + +/* Alpha context definitions */ +#if defined(_ALPHA_) || defined(__alpha__) + +#define CONTEXT_ALPHA 0x00020000 + +#define CONTEXT_CONTROL (CONTEXT_ALPHA | 0x00000001L) +#define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA | 0x00000002L) +#define CONTEXT_INTEGER (CONTEXT_ALPHA | 0x00000004L) +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) + +typedef struct _CONTEXT +{ + /* selected by CONTEXT_FLOATING_POINT */ + ULONGLONG FltF0; + ULONGLONG FltF1; + ULONGLONG FltF2; + ULONGLONG FltF3; + ULONGLONG FltF4; + ULONGLONG FltF5; + ULONGLONG FltF6; + ULONGLONG FltF7; + ULONGLONG FltF8; + ULONGLONG FltF9; + ULONGLONG FltF10; + ULONGLONG FltF11; + ULONGLONG FltF12; + ULONGLONG FltF13; + ULONGLONG FltF14; + ULONGLONG FltF15; + ULONGLONG FltF16; + ULONGLONG FltF17; + ULONGLONG FltF18; + ULONGLONG FltF19; + ULONGLONG FltF20; + ULONGLONG FltF21; + ULONGLONG FltF22; + ULONGLONG FltF23; + ULONGLONG FltF24; + ULONGLONG FltF25; + ULONGLONG FltF26; + ULONGLONG FltF27; + ULONGLONG FltF28; + ULONGLONG FltF29; + ULONGLONG FltF30; + ULONGLONG FltF31; + + /* selected by CONTEXT_INTEGER */ + ULONGLONG IntV0; + ULONGLONG IntT0; + ULONGLONG IntT1; + ULONGLONG IntT2; + ULONGLONG IntT3; + ULONGLONG IntT4; + ULONGLONG IntT5; + ULONGLONG IntT6; + ULONGLONG IntT7; + ULONGLONG IntS0; + ULONGLONG IntS1; + ULONGLONG IntS2; + ULONGLONG IntS3; + ULONGLONG IntS4; + ULONGLONG IntS5; + ULONGLONG IntFp; + ULONGLONG IntA0; + ULONGLONG IntA1; + ULONGLONG IntA2; + ULONGLONG IntA3; + ULONGLONG IntA4; + ULONGLONG IntA5; + ULONGLONG IntT8; + ULONGLONG IntT9; + ULONGLONG IntT10; + ULONGLONG IntT11; + ULONGLONG IntRa; + ULONGLONG IntT12; + ULONGLONG IntAt; + ULONGLONG IntGp; + ULONGLONG IntSp; + ULONGLONG IntZero; + + /* selected by CONTEXT_FLOATING_POINT */ + ULONGLONG Fpcr; + ULONGLONG SoftFpcr; + + /* selected by CONTEXT_CONTROL */ + ULONGLONG Fir; + DWORD Psr; + DWORD ContextFlags; + DWORD Fill[4]; +} CONTEXT; + +#define _QUAD_PSR_OFFSET HighSoftFpcr +#define _QUAD_FLAGS_OFFSET HighFir + +#endif /* _ALPHA_ */ + +/* Mips context definitions */ +#ifdef _MIPS_ + +#define CONTEXT_R4000 0x00010000 + +#define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001) +#define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002) +#define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) + +typedef struct _CONTEXT +{ + DWORD Argument[4]; + /* These are selected by CONTEXT_FLOATING_POINT */ + DWORD FltF0; + DWORD FltF1; + DWORD FltF2; + DWORD FltF3; + DWORD FltF4; + DWORD FltF5; + DWORD FltF6; + DWORD FltF7; + DWORD FltF8; + DWORD FltF9; + DWORD FltF10; + DWORD FltF11; + DWORD FltF12; + DWORD FltF13; + DWORD FltF14; + DWORD FltF15; + DWORD FltF16; + DWORD FltF17; + DWORD FltF18; + DWORD FltF19; + DWORD FltF20; + DWORD FltF21; + DWORD FltF22; + DWORD FltF23; + DWORD FltF24; + DWORD FltF25; + DWORD FltF26; + DWORD FltF27; + DWORD FltF28; + DWORD FltF29; + DWORD FltF30; + DWORD FltF31; + + /* These are selected by CONTEXT_INTEGER */ + DWORD IntZero; + DWORD IntAt; + DWORD IntV0; + DWORD IntV1; + DWORD IntA0; + DWORD IntA1; + DWORD IntA2; + DWORD IntA3; + DWORD IntT0; + DWORD IntT1; + DWORD IntT2; + DWORD IntT3; + DWORD IntT4; + DWORD IntT5; + DWORD IntT6; + DWORD IntT7; + DWORD IntS0; + DWORD IntS1; + DWORD IntS2; + DWORD IntS3; + DWORD IntS4; + DWORD IntS5; + DWORD IntS6; + DWORD IntS7; + DWORD IntT8; + DWORD IntT9; + DWORD IntK0; + DWORD IntK1; + DWORD IntGp; + DWORD IntSp; + DWORD IntS8; + DWORD IntRa; + DWORD IntLo; + DWORD IntHi; + + /* These are selected by CONTEXT_FLOATING_POINT */ + DWORD Fsr; + + /* These are selected by CONTEXT_CONTROL */ + DWORD Fir; + DWORD Psr; + + DWORD ContextFlags; + DWORD Fill[2]; +} CONTEXT; + +#endif /* _MIPS_ */ + +/* PowerPC context definitions */ +#ifdef __PPC__ + +#define CONTEXT_CONTROL 0x0001 +#define CONTEXT_FLOATING_POINT 0x0002 +#define CONTEXT_INTEGER 0x0004 +#define CONTEXT_DEBUG_REGISTERS 0x0008 +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) + +typedef struct +{ + /* These are selected by CONTEXT_FLOATING_POINT */ + double Fpr0; + double Fpr1; + double Fpr2; + double Fpr3; + double Fpr4; + double Fpr5; + double Fpr6; + double Fpr7; + double Fpr8; + double Fpr9; + double Fpr10; + double Fpr11; + double Fpr12; + double Fpr13; + double Fpr14; + double Fpr15; + double Fpr16; + double Fpr17; + double Fpr18; + double Fpr19; + double Fpr20; + double Fpr21; + double Fpr22; + double Fpr23; + double Fpr24; + double Fpr25; + double Fpr26; + double Fpr27; + double Fpr28; + double Fpr29; + double Fpr30; + double Fpr31; + double Fpscr; + + /* These are selected by CONTEXT_INTEGER */ + DWORD Gpr0; + DWORD Gpr1; + DWORD Gpr2; + DWORD Gpr3; + DWORD Gpr4; + DWORD Gpr5; + DWORD Gpr6; + DWORD Gpr7; + DWORD Gpr8; + DWORD Gpr9; + DWORD Gpr10; + DWORD Gpr11; + DWORD Gpr12; + DWORD Gpr13; + DWORD Gpr14; + DWORD Gpr15; + DWORD Gpr16; + DWORD Gpr17; + DWORD Gpr18; + DWORD Gpr19; + DWORD Gpr20; + DWORD Gpr21; + DWORD Gpr22; + DWORD Gpr23; + DWORD Gpr24; + DWORD Gpr25; + DWORD Gpr26; + DWORD Gpr27; + DWORD Gpr28; + DWORD Gpr29; + DWORD Gpr30; + DWORD Gpr31; + + DWORD Cr; + DWORD Xer; + + /* These are selected by CONTEXT_CONTROL */ + DWORD Msr; + DWORD Iar; + DWORD Lr; + DWORD Ctr; + + DWORD ContextFlags; + DWORD Fill[3]; + + /* These are selected by CONTEXT_DEBUG_REGISTERS */ + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr4; + DWORD Dr5; + DWORD Dr6; + DWORD Dr7; +} CONTEXT; + +typedef struct _STACK_FRAME_HEADER +{ + DWORD BackChain; + DWORD GlueSaved1; + DWORD GlueSaved2; + DWORD Reserved1; + DWORD Spare1; + DWORD Spare2; + + DWORD Parameter0; + DWORD Parameter1; + DWORD Parameter2; + DWORD Parameter3; + DWORD Parameter4; + DWORD Parameter5; + DWORD Parameter6; + DWORD Parameter7; +} STACK_FRAME_HEADER,*PSTACK_FRAME_HEADER; + +#endif /* __PPC__ */ + +#ifdef __sparc__ + +/* + * FIXME: + * + * There is no official CONTEXT structure defined for the SPARC + * architecture, so I just made one up. + * + * This structure is valid only for 32-bit SPARC architectures, + * not for 64-bit SPARC. + * + * Note that this structure contains only the 'top-level' registers; + * the rest of the register window chain is not visible. + * + * The layout follows the Solaris 'prgregset_t' structure. + * + */ + +#define CONTEXT_SPARC 0x10000000 + +#define CONTEXT_CONTROL (CONTEXT_SPARC | 0x00000001) +#define CONTEXT_FLOATING_POINT (CONTEXT_SPARC | 0x00000002) +#define CONTEXT_INTEGER (CONTEXT_SPARC | 0x00000004) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) + +typedef struct _CONTEXT +{ + DWORD ContextFlags; + + /* These are selected by CONTEXT_INTEGER */ + DWORD g0; + DWORD g1; + DWORD g2; + DWORD g3; + DWORD g4; + DWORD g5; + DWORD g6; + DWORD g7; + DWORD o0; + DWORD o1; + DWORD o2; + DWORD o3; + DWORD o4; + DWORD o5; + DWORD o6; + DWORD o7; + DWORD l0; + DWORD l1; + DWORD l2; + DWORD l3; + DWORD l4; + DWORD l5; + DWORD l6; + DWORD l7; + DWORD i0; + DWORD i1; + DWORD i2; + DWORD i3; + DWORD i4; + DWORD i5; + DWORD i6; + DWORD i7; + + /* These are selected by CONTEXT_CONTROL */ + DWORD psr; + DWORD pc; + DWORD npc; + DWORD y; + DWORD wim; + DWORD tbr; + + /* FIXME: floating point registers missing */ + +} CONTEXT; + +#endif /* __sparc__ */ + +#if !defined(CONTEXT_FULL) && !defined(RC_INVOKED) +#error You need to define a CONTEXT for your CPU +#endif + +typedef CONTEXT *PCONTEXT; +typedef HANDLE *PHANDLE; + +#ifdef __WINE__ + +/* Macros for easier access to i386 context registers */ + +#define EAX_reg(context) ((context)->Eax) +#define EBX_reg(context) ((context)->Ebx) +#define ECX_reg(context) ((context)->Ecx) +#define EDX_reg(context) ((context)->Edx) +#define ESI_reg(context) ((context)->Esi) +#define EDI_reg(context) ((context)->Edi) +#define EBP_reg(context) ((context)->Ebp) + +#define CS_reg(context) ((context)->SegCs) +#define DS_reg(context) ((context)->SegDs) +#define ES_reg(context) ((context)->SegEs) +#define FS_reg(context) ((context)->SegFs) +#define GS_reg(context) ((context)->SegGs) +#define SS_reg(context) ((context)->SegSs) + +#define EFL_reg(context) ((context)->EFlags) +#define EIP_reg(context) ((context)->Eip) +#define ESP_reg(context) ((context)->Esp) + +#define AX_reg(context) (*(WORD*)&EAX_reg(context)) +#define BX_reg(context) (*(WORD*)&EBX_reg(context)) +#define CX_reg(context) (*(WORD*)&ECX_reg(context)) +#define DX_reg(context) (*(WORD*)&EDX_reg(context)) +#define SI_reg(context) (*(WORD*)&ESI_reg(context)) +#define DI_reg(context) (*(WORD*)&EDI_reg(context)) +#define BP_reg(context) (*(WORD*)&EBP_reg(context)) + +#define AL_reg(context) (*(BYTE*)&EAX_reg(context)) +#define AH_reg(context) (*((BYTE*)&EAX_reg(context)+1)) +#define BL_reg(context) (*(BYTE*)&EBX_reg(context)) +#define BH_reg(context) (*((BYTE*)&EBX_reg(context)+1)) +#define CL_reg(context) (*(BYTE*)&ECX_reg(context)) +#define CH_reg(context) (*((BYTE*)&ECX_reg(context)+1)) +#define DL_reg(context) (*(BYTE*)&EDX_reg(context)) +#define DH_reg(context) (*((BYTE*)&EDX_reg(context)+1)) + +#define SET_CFLAG(context) (EFL_reg(context) |= 0x0001) +#define RESET_CFLAG(context) (EFL_reg(context) &= ~0x0001) +#define SET_ZFLAG(context) (EFL_reg(context) |= 0x0040) +#define RESET_ZFLAG(context) (EFL_reg(context) &= ~0x0040) + +#define ISV86(context) (EFL_reg(context) & 0x00020000) +#define V86BASE(context) ((context)->Dr7) /* ugly */ + + +/* Macros to retrieve the current context */ + +#ifdef __i386__ + +#ifdef NEED_UNDERSCORE_PREFIX +# define __ASM_NAME(name) "_" name +#else +# define __ASM_NAME(name) name +#endif + +#ifdef __GNUC__ +# define __ASM_GLOBAL_FUNC(name,code) \ + __asm__( ".align 4\n\t" \ + ".globl " __ASM_NAME(#name) "\n\t" \ + ".type " __ASM_NAME(#name) ",@function\n" \ + __ASM_NAME(#name) ":\n\t" \ + code ); +#else /* __GNUC__ */ +# define __ASM_GLOBAL_FUNC(name,code) \ + void __asm_dummy_##name(void) { \ + asm( ".align 4\n\t" \ + ".globl " __ASM_NAME(#name) "\n\t" \ + ".type " __ASM_NAME(#name) ",@function\n" \ + __ASM_NAME(#name) ":\n\t" \ + code ); \ + } +#endif /* __GNUC__ */ + +#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \ + __ASM_GLOBAL_FUNC( name, \ + "call " __ASM_NAME("CALL32_Regs") "\n\t" \ + ".long " __ASM_NAME(#fn) "\n\t" \ + ".byte " #args ", " #args ) +#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \ + _DEFINE_REGS_ENTRYPOINT( name, fn, 0 ) +#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \ + _DEFINE_REGS_ENTRYPOINT( name, fn, 4 ) +#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \ + _DEFINE_REGS_ENTRYPOINT( name, fn, 8 ) +#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \ + _DEFINE_REGS_ENTRYPOINT( name, fn, 12 ) +#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \ + _DEFINE_REGS_ENTRYPOINT( name, fn, 16 ) + +#endif /* __i386__ */ + +#ifdef __sparc__ +/* FIXME: use getcontext() to retrieve full context */ +#define _GET_CONTEXT \ + CONTEXT context; \ + do { memset(&context, 0, sizeof(CONTEXT)); \ + context.ContextFlags = CONTEXT_CONTROL; \ + context.pc = (DWORD)__builtin_return_address(0); \ + } while (0) + +#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \ + void WINAPI name ( void ) \ + { _GET_CONTEXT; fn( &context ); } +#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \ + void WINAPI name ( t1 a1 ) \ + { _GET_CONTEXT; fn( a1, &context ); } +#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \ + void WINAPI name ( t1 a1, t2 a2 ) \ + { _GET_CONTEXT; fn( a1, a2, &context ); } +#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \ + void WINAPI name ( t1 a1, t2 a2, t3 a3 ) \ + { _GET_CONTEXT; fn( a1, a2, a3, &context ); } +#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \ + void WINAPI name ( t1 a1, t2 a2, t3 a3, t4 a4 ) \ + { _GET_CONTEXT; fn( a1, a2, a3, a4, &context ); } + +#endif /* __sparc__ */ + +#ifndef DEFINE_REGS_ENTRYPOINT_0 +#error You need to define DEFINE_REGS_ENTRYPOINT macros for your CPU +#endif + +#ifdef __i386__ +# define GET_IP(context) ((LPVOID)(context)->Eip) +#endif +#ifdef __sparc__ +# define GET_IP(context) ((LPVOID)(context)->pc) +#endif + +#if !defined(GET_IP) && !defined(RC_INVOKED) +# error You must define GET_IP for this CPU +#endif + +#endif /* __WINE__ */ + +/* + * Exception codes + */ + +#define STATUS_SUCCESS 0x00000000 +#define STATUS_WAIT_0 0x00000000 +#define STATUS_ABANDONED_WAIT_0 0x00000080 +#define STATUS_USER_APC 0x000000C0 +#define STATUS_TIMEOUT 0x00000102 +#define STATUS_PENDING 0x00000103 + +#define STATUS_GUARD_PAGE_VIOLATION 0x80000001 +#define STATUS_DATATYPE_MISALIGNMENT 0x80000002 +#define STATUS_BREAKPOINT 0x80000003 +#define STATUS_SINGLE_STEP 0x80000004 +#define STATUS_BUFFER_OVERFLOW 0x80000005 +#define STATUS_NO_MORE_FILES 0x80000006 +#define STATUS_WAKE_SYSTEM_DEBUGGER 0x80000007 + +#define STATUS_HANDLES_CLOSED 0x8000000A +#define STATUS_NO_INHERITANCE 0x8000000B +#define STATUS_GUID_SUBSTITUTION_MADE 0x8000000C +#define STATUS_PARTIAL_COPY 0x8000000D +#define STATUS_DEVICE_PAPER_EMPTY 0x8000000E +#define STATUS_DEVICE_POWERED_OFF 0x8000000F +#define STATUS_DEVICE_OFF_LINE 0x80000010 +#define STATUS_DEVICE_BUSY 0x80000011 +#define STATUS_NO_MORE_EAS 0x80000012 +#define STATUS_INVALID_EA_NAME 0x80000013 +#define STATUS_EA_LIST_INCONSISTENT 0x80000014 +#define STATUS_INVALID_EA_FLAG 0x80000015 +#define STATUS_VERIFY_REQUIRED 0x80000016 +#define STATUS_EXTRANEOUS_INFORMATION 0x80000017 +#define STATUS_RXACT_COMMIT_NECESSARY 0x80000018 +#define STATUS_NO_MORE_ENTRIES 0x8000001A +#define STATUS_FILEMARK_DETECTED 0x8000001B +#define STATUS_MEDIA_CHANGED 0x8000001C +#define STATUS_BUS_RESET 0x8000001D +#define STATUS_END_OF_MEDIA 0x8000001E +#define STATUS_BEGINNING_OF_MEDIA 0x8000001F +#define STATUS_MEDIA_CHECK 0x80000020 +#define STATUS_SETMARK_DETECTED 0x80000021 +#define STATUS_NO_DATA_DETECTED 0x80000022 +#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES 0x80000023 +#define STATUS_SERVER_HAS_OPEN_HANDLES 0x80000024 +#define STATUS_ALREADY_DISCONNECTED 0x80000025 +#define STATUS_LONGJUMP 0x80000026 + +#define STATUS_UNSUCCESSFUL 0xC0000001 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_INVALID_INFO_CLASS 0xC0000003 +#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 +#define STATUS_ACCESS_VIOLATION 0xC0000005 +#define STATUS_IN_PAGE_ERROR 0xC0000006 +#define STATUS_PAGEFILE_QUOTA 0xC0000007 +#define STATUS_INVALID_HANDLE 0xC0000008 +#define STATUS_BAD_INITIAL_STACK 0xC0000009 +#define STATUS_BAD_INITIAL_PC 0xC000000A +#define STATUS_INVALID_CID 0xC000000B +#define STATUS_TIMER_NOT_CANCELED 0xC000000C +#define STATUS_INVALID_PARAMETER 0xC000000D +#define STATUS_NO_SUCH_DEVICE 0xC000000E +#define STATUS_NO_SUCH_FILE 0xC000000F +#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 +#define STATUS_END_OF_FILE 0xC0000011 +#define STATUS_WRONG_VOLUME 0xC0000012 +#define STATUS_NO_MEDIA_IN_DEVICE 0xC0000013 +#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014 +#define STATUS_NONEXISTENT_SECTOR 0xC0000015 +#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 +#define STATUS_NO_MEMORY 0xC0000017 +#define STATUS_CONFLICTING_ADDRESSES 0xC0000018 +#define STATUS_NOT_MAPPED_VIEW 0xC0000019 +#define STATUS_UNABLE_TO_FREE_VM 0xC000001A +#define STATUS_UNABLE_TO_DELETE_SECTION 0xC000001B +#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C +#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D +#define STATUS_INVALID_LOCK_SEQUENCE 0xC000001E +#define STATUS_INVALID_VIEW_SIZE 0xC000001F +#define STATUS_INVALID_FILE_FOR_SECTION 0xC0000020 +#define STATUS_ALREADY_COMMITTED 0xC0000021 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_BUFFER_TOO_SMALL 0xC0000023 +#define STATUS_OBJECT_TYPE_MISMATCH 0xC0000024 +#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025 +#define STATUS_INVALID_DISPOSITION 0xC0000026 +#define STATUS_UNWIND 0xC0000027 +#define STATUS_BAD_STACK 0xC0000028 +#define STATUS_INVALID_UNWIND_TARGET 0xC0000029 +#define STATUS_NOT_LOCKED 0xC000002A +#define STATUS_PARITY_ERROR 0xC000002B +#define STATUS_UNABLE_TO_DECOMMIT_VM 0xC000002C +#define STATUS_NOT_COMMITTED 0xC000002D +#define STATUS_INVALID_PORT_ATTRIBUTES 0xC000002E +#define STATUS_PORT_MESSAGE_TOO_LONG 0xC000002F +#define STATUS_INVALID_PARAMETER_MIX 0xC0000030 +#define STATUS_INVALID_QUOTA_LOWER 0xC0000031 +#define STATUS_DISK_CORRUPT_ERROR 0xC0000032 +#define STATUS_OBJECT_NAME_INVALID 0xC0000033 +#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034 +#define STATUS_OBJECT_NAME_COLLISION 0xC0000035 +#define STATUS_PORT_DISCONNECTED 0xC0000037 +#define STATUS_DEVICE_ALREADY_ATTACHED 0xC0000038 +#define STATUS_OBJECT_PATH_INVALID 0xC0000039 +#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A +#define STATUS_PATH_SYNTAX_BAD 0xC000003B +#define STATUS_DATA_OVERRUN 0xC000003C +#define STATUS_DATA_LATE_ERROR 0xC000003D +#define STATUS_DATA_ERROR 0xC000003E +#define STATUS_CRC_ERROR 0xC000003F +#define STATUS_SECTION_TOO_BIG 0xC0000040 +#define STATUS_PORT_CONNECTION_REFUSED 0xC0000041 +#define STATUS_INVALID_PORT_HANDLE 0xC0000042 +#define STATUS_SHARING_VIOLATION 0xC0000043 +#define STATUS_QUOTA_EXCEEDED 0xC0000044 +#define STATUS_INVALID_PAGE_PROTECTION 0xC0000045 +#define STATUS_MUTANT_NOT_OWNED 0xC0000046 +#define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047 +#define STATUS_PORT_ALREADY_SET 0xC0000048 +#define STATUS_SUSPEND_COUNT_EXCEEDED 0xC000004A +#define STATUS_LOCK_NOT_GRANTED 0xC0000054 /* FIXME: not sure */ +#define STATUS_FILE_LOCK_CONFLICT 0xC0000055 /* FIXME: not sure */ +#define STATUS_UNKNOWN_REVISION 0xC0000058 +#define STATUS_INVALID_SECURITY_DESCR 0xC0000079 +#define STATUS_DISK_FULL 0xC000007F +#define STATUS_SECTION_NOT_EXTENDED 0xC0000087 +#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C +#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D +#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E +#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F +#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090 +#define STATUS_FLOAT_OVERFLOW 0xC0000091 +#define STATUS_FLOAT_STACK_CHECK 0xC0000092 +#define STATUS_FLOAT_UNDERFLOW 0xC0000093 +#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 +#define STATUS_INTEGER_OVERFLOW 0xC0000095 +#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 +#define STATUS_MEDIA_WRITE_PROTECTED 0XC00000A2 +#define STATUS_INVALID_PARAMETER_2 0xC00000F0 +#define STATUS_STACK_OVERFLOW 0xC00000FD +#define STATUS_DIRECTORY_NOT_EMPTY 0xC0000101 +#define STATUS_TOO_MANY_OPENED_FILES 0xC000011F +#define STATUS_CONTROL_C_EXIT 0xC000013A +#define STATUS_PIPE_BROKEN 0xC000014B +#define STATUS_NOT_REGISTRY_FILE 0xC000015C +#define STATUS_PARTITION_FAILURE 0xC0000172 +#define STATUS_INVALID_BLOCK_LENGTH 0xC0000173 +#define STATUS_DEVICE_NOT_PARTITIONED 0xC0000174 +#define STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000175 +#define STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000176 +#define STATUS_EOM_OVERFLOW 0xC0000177 +#define STATUS_NO_MEDIA 0xC0000178 +#define STATUS_NO_SUCH_MEMBER 0xC000017A +#define STATUS_INVALID_MEMBER 0xC000017B +#define STATUS_KEY_DELETED 0xC000017C +#define STATUS_NO_LOG_SPACE 0xC000017D +#define STATUS_TOO_MANY_SIDS 0xC000017E +#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017F +#define STATUS_KEY_HAS_CHILDREN 0xC0000180 +#define STATUS_CHILD_MUST_BE_VOLATILE 0xC0000181 +#define STATUS_DEVICE_CONFIGURATION_ERROR0xC0000182 +#define STATUS_DRIVER_INTERNAL_ERROR 0xC0000183 +#define STATUS_INVALID_DEVICE_STATE 0xC0000184 +#define STATUS_IO_DEVICE_ERROR 0xC0000185 +#define STATUS_DEVICE_PROTOCOL_ERROR 0xC0000186 +#define STATUS_BACKUP_CONTROLLER 0xC0000187 +#define STATUS_LOG_FILE_FULL 0xC0000188 +#define STATUS_TOO_LATE 0xC0000189 +#define STATUS_NO_TRUST_LSA_SECRET 0xC000018A +#define STATUS_NO_TRUST_SAM_ACCOUNT 0xC000018B +#define STATUS_TRUSTED_DOMAIN_FAILURE 0xC000018C +#define STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018D +#define STATUS_EVENTLOG_FILE_CORRUPT 0xC000018E +#define STATUS_EVENTLOG_CANT_START 0xC000018F +#define STATUS_TRUST_FAILURE 0xC0000190 +#define STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000191 +#define STATUS_NETLOGON_NOT_STARTED 0xC0000192 +#define STATUS_ACCOUNT_EXPIRED 0xC0000193 +#define STATUS_POSSIBLE_DEADLOCK 0xC0000194 +#define STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195 +#define STATUS_REMOTE_SESSION_LIMIT 0xC0000196 +#define STATUS_EVENTLOG_FILE_CHANGED 0xC0000197 +#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198 +#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199 +#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019A +#define STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019B +#define STATUS_FS_DRIVER_REQUIRED 0xC000019C + +#define STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204 + +#define MAXIMUM_WAIT_OBJECTS 64 +#define MAXIMUM_SUSPEND_COUNT 127 + + +/* + * Return values from the actual exception handlers + */ + +#define ExceptionContinueExecution 0 +#define ExceptionContinueSearch 1 +#define ExceptionNestedException 2 +#define ExceptionCollidedUnwind 3 + +/* + * Return values from filters in except() and from UnhandledExceptionFilter + */ + +#define EXCEPTION_EXECUTE_HANDLER 1 +#define EXCEPTION_CONTINUE_SEARCH 0 +#define EXCEPTION_CONTINUE_EXECUTION -1 + +/* + * From OS/2 2.0 exception handling + * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD + */ + +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + +#define EXCEPTION_CONTINUABLE 0 +#define EXCEPTION_NONCONTINUABLE EH_NONCONTINUABLE + +/* + * The exception record used by Win32 to give additional information + * about exception to exception handlers. + */ + +#define EXCEPTION_MAXIMUM_PARAMETERS 15 + +typedef struct __EXCEPTION_RECORD +{ + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct __EXCEPTION_RECORD *ExceptionRecord; + + LPVOID ExceptionAddress; + DWORD NumberParameters; + DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; +} EXCEPTION_RECORD, *PEXCEPTION_RECORD; + +/* + * The exception pointers structure passed to exception filters + * in except() and the UnhandledExceptionFilter(). + */ + +typedef struct _EXCEPTION_POINTERS +{ + PEXCEPTION_RECORD ExceptionRecord; + PCONTEXT ContextRecord; +} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; + + +/* + * The exception frame, used for registering exception handlers + * Win32 cares only about this, but compilers generally emit + * larger exception frames for their own use. + */ + +struct __EXCEPTION_FRAME; + +typedef DWORD (*PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,struct __EXCEPTION_FRAME*, + PCONTEXT,struct __EXCEPTION_FRAME **); + +typedef struct __EXCEPTION_FRAME +{ + struct __EXCEPTION_FRAME *Prev; + PEXCEPTION_HANDLER Handler; +} EXCEPTION_FRAME, *PEXCEPTION_FRAME; + +#include "poppack.h" + +/* + * function pointer to a exception filter + */ + +typedef LONG CALLBACK (*PTOP_LEVEL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS ExceptionInfo); +typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; + +DWORD WINAPI UnhandledExceptionFilter( PEXCEPTION_POINTERS epointers ); +LPTOP_LEVEL_EXCEPTION_FILTER +WINAPI SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter ); + +/* status values for ContinueDebugEvent */ +#define DBG_CONTINUE 0x00010002 +#define DBG_TERMINATE_THREAD 0x40010003 +#define DBG_TERMINATE_PROCESS 0x40010004 +#define DBG_CONTROL_C 0x40010005 +#define DBG_CONTROL_BREAK 0x40010008 +#define DBG_EXCEPTION_NOT_HANDLED 0x80010001 + +typedef struct _NT_TIB +{ + struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; + PVOID StackBase; + PVOID StackLimit; + PVOID SubSystemTib; + union { + PVOID FiberData; + DWORD Version; + } DUMMYUNIONNAME; + PVOID ArbitraryUserPointer; + struct _NT_TIB *Self; +} NT_TIB, *PNT_TIB; + +struct _TEB; +/* +#if defined(__i386__) && defined(__GNUC__) +extern inline struct _TEB * WINAPI NtCurrentTeb(void); +extern inline struct _TEB * WINAPI NtCurrentTeb(void) +{ + struct _TEB *teb; + __asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb)); + return teb; +} +#else +extern struct _TEB * WINAPI NtCurrentTeb(void); +#endif +*/ + +/* + * File formats definitions + */ + +typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; /* 00: MZ Header signature */ + WORD e_cblp; /* 02: Bytes on last page of file */ + WORD e_cp; /* 04: Pages in file */ + WORD e_crlc; /* 06: Relocations */ + WORD e_cparhdr; /* 08: Size of header in paragraphs */ + WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */ + WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */ + WORD e_ss; /* 0e: Initial (relative) SS value */ + WORD e_sp; /* 10: Initial SP value */ + WORD e_csum; /* 12: Checksum */ + WORD e_ip; /* 14: Initial IP value */ + WORD e_cs; /* 16: Initial (relative) CS value */ + WORD e_lfarlc; /* 18: File address of relocation table */ + WORD e_ovno; /* 1a: Overlay number */ + WORD e_res[4]; /* 1c: Reserved words */ + WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */ + WORD e_oeminfo; /* 26: OEM information; e_oemid specific */ + WORD e_res2[10]; /* 28: Reserved words */ + DWORD e_lfanew; /* 3c: Offset to extended header */ +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ +#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ +#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ +#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */ +#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ + +/* + * This is the Windows executable (NE) header. + * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way. + */ +typedef struct +{ + WORD ne_magic; /* 00 NE signature 'NE' */ + BYTE ne_ver; /* 02 Linker version number */ + BYTE ne_rev; /* 03 Linker revision number */ + WORD ne_enttab; /* 04 Offset to entry table relative to NE */ + WORD ne_cbenttab; /* 06 Length of entry table in bytes */ + LONG ne_crc; /* 08 Checksum */ + WORD ne_flags; /* 0c Flags about segments in this file */ + WORD ne_autodata; /* 0e Automatic data segment number */ + WORD ne_heap; /* 10 Initial size of local heap */ + WORD ne_stack; /* 12 Initial size of stack */ + DWORD ne_csip; /* 14 Initial CS:IP */ + DWORD ne_sssp; /* 18 Initial SS:SP */ + WORD ne_cseg; /* 1c # of entries in segment table */ + WORD ne_cmod; /* 1e # of entries in module reference tab. */ + WORD ne_cbnrestab; /* 20 Length of nonresident-name table */ + WORD ne_segtab; /* 22 Offset to segment table */ + WORD ne_rsrctab; /* 24 Offset to resource table */ + WORD ne_restab; /* 26 Offset to resident-name table */ + WORD ne_modtab; /* 28 Offset to module reference table */ + WORD ne_imptab; /* 2a Offset to imported name table */ + DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ + WORD ne_cmovent; /* 30 # of movable entry points */ + WORD ne_align; /* 32 Logical sector alignment shift count */ + WORD ne_cres; /* 34 # of resource segments */ + BYTE ne_exetyp; /* 36 Flags indicating target OS */ + BYTE ne_flagsothers; /* 37 Additional information flags */ + WORD fastload_offset; /* 38 Offset to fast load area (should be ne_pretthunks)*/ + WORD fastload_length; /* 3a Length of fast load area (should be ne_psegrefbytes) */ + WORD ne_swaparea; /* 3c Reserved by Microsoft */ + WORD ne_expver; /* 3e Expected Windows version number */ +} IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER; + +typedef struct _IMAGE_VXD_HEADER { + WORD e32_magic; + BYTE e32_border; + BYTE e32_worder; + DWORD e32_level; + WORD e32_cpu; + WORD e32_os; + DWORD e32_ver; + DWORD e32_mflags; + DWORD e32_mpages; + DWORD e32_startobj; + DWORD e32_eip; + DWORD e32_stackobj; + DWORD e32_esp; + DWORD e32_pagesize; + DWORD e32_lastpagesize; + DWORD e32_fixupsize; + DWORD e32_fixupsum; + DWORD e32_ldrsize; + DWORD e32_ldrsum; + DWORD e32_objtab; + DWORD e32_objcnt; + DWORD e32_objmap; + DWORD e32_itermap; + DWORD e32_rsrctab; + DWORD e32_rsrccnt; + DWORD e32_restab; + DWORD e32_enttab; + DWORD e32_dirtab; + DWORD e32_dircnt; + DWORD e32_fpagetab; + DWORD e32_frectab; + DWORD e32_impmod; + DWORD e32_impmodcnt; + DWORD e32_impproc; + DWORD e32_pagesum; + DWORD e32_datapage; + DWORD e32_preload; + DWORD e32_nrestab; + DWORD e32_cbnrestab; + DWORD e32_nressum; + DWORD e32_autodata; + DWORD e32_debuginfo; + DWORD e32_debuglen; + DWORD e32_instpreload; + DWORD e32_instdemand; + DWORD e32_heapsize; + BYTE e32_res3[12]; + DWORD e32_winresoff; + DWORD e32_winreslen; + WORD e32_devid; + WORD e32_ddkver; +} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; + + +/* These defines describe the meanings of the bits in the Characteristics + field */ + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */ +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_16BIT_MACHINE 0x0040 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +/* These are the settings of the Machine field. */ +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I860 0x14d +#define IMAGE_FILE_MACHINE_I386 0x14c +#define IMAGE_FILE_MACHINE_R3000 0x162 +#define IMAGE_FILE_MACHINE_R4000 0x166 +#define IMAGE_FILE_MACHINE_R10000 0x168 +#define IMAGE_FILE_MACHINE_ALPHA 0x184 +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +/* Possible Magic values */ +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +/* These are indexes into the DataDirectory array */ +#define IMAGE_FILE_EXPORT_DIRECTORY 0 +#define IMAGE_FILE_IMPORT_DIRECTORY 1 +#define IMAGE_FILE_RESOURCE_DIRECTORY 2 +#define IMAGE_FILE_EXCEPTION_DIRECTORY 3 +#define IMAGE_FILE_SECURITY_DIRECTORY 4 +#define IMAGE_FILE_BASE_RELOCATION_TABLE 5 +#define IMAGE_FILE_DEBUG_DIRECTORY 6 +#define IMAGE_FILE_DESCRIPTION_STRING 7 +#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */ +#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9 +#define IMAGE_FILE_CALLBACK_DIRECTORY 10 + +/* Directory Entries, indices into the DataDirectory array */ + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ +#define IMAGE_DIRECTORY_ENTRY_TLS 9 +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 +#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 + +/* Subsystem Values */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */ +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem*/ +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER { + + /* Standard fields */ + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + + /* NT additional fields */ + + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef struct _IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_FIRST_SECTION(ntheader) \ + ((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) + +/* These defines are for the Characteristics bitfield. */ +/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */ +/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */ +/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */ +/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */ +/* #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 - Reserved */ +/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */ + +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */ +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 + +/* 0x00002000 - Reserved */ +/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */ +#define IMAGE_SCN_MEM_FARDATA 0x00008000 + +/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */ +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */ +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +/* 0x00800000 - Unused */ + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 + + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +#include "pshpack2.h" + +typedef struct _IMAGE_SYMBOL { + union { + BYTE ShortName[8]; + struct { + DWORD Short; + DWORD Long; + } Name; + DWORD LongName[2]; + } N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} IMAGE_SYMBOL; +typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +typedef struct _IMAGE_LINENUMBER { + union { + DWORD SymbolTableIndex; + DWORD VirtualAddress; + } Type; + WORD Linenumber; +} IMAGE_LINENUMBER; +typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +typedef union _IMAGE_AUX_SYMBOL { + struct { + DWORD TagIndex; + union { + struct { + WORD Linenumber; + WORD Size; + } LnSz; + DWORD TotalSize; + } Misc; + union { + struct { + DWORD PointerToLinenumber; + DWORD PointerToNextFunction; + } Function; + struct { + WORD Dimension[4]; + } Array; + } FcnAry; + WORD TvIndex; + } Sym; + struct { + BYTE Name[IMAGE_SIZEOF_SYMBOL]; + } File; + struct { + DWORD Length; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD CheckSum; + SHORT Number; + BYTE Selection; + } Section; +} IMAGE_AUX_SYMBOL; +typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; + +#define IMAGE_SIZEOF_AUX_SYMBOL 18 + +#include "poppack.h" + +#define IMAGE_SYM_UNDEFINED (SHORT)0 +#define IMAGE_SYM_ABSOLUTE (SHORT)-1 +#define IMAGE_SYM_DEBUG (SHORT)-2 + +#define IMAGE_SYM_TYPE_NULL 0x0000 +#define IMAGE_SYM_TYPE_VOID 0x0001 +#define IMAGE_SYM_TYPE_CHAR 0x0002 +#define IMAGE_SYM_TYPE_SHORT 0x0003 +#define IMAGE_SYM_TYPE_INT 0x0004 +#define IMAGE_SYM_TYPE_LONG 0x0005 +#define IMAGE_SYM_TYPE_FLOAT 0x0006 +#define IMAGE_SYM_TYPE_DOUBLE 0x0007 +#define IMAGE_SYM_TYPE_STRUCT 0x0008 +#define IMAGE_SYM_TYPE_UNION 0x0009 +#define IMAGE_SYM_TYPE_ENUM 0x000A +#define IMAGE_SYM_TYPE_MOE 0x000B +#define IMAGE_SYM_TYPE_BYTE 0x000C +#define IMAGE_SYM_TYPE_WORD 0x000D +#define IMAGE_SYM_TYPE_UINT 0x000E +#define IMAGE_SYM_TYPE_DWORD 0x000F +#define IMAGE_SYM_TYPE_PCODE 0x8000 + +#define IMAGE_SYM_DTYPE_NULL 0 +#define IMAGE_SYM_DTYPE_POINTER 1 +#define IMAGE_SYM_DTYPE_FUNCTION 2 +#define IMAGE_SYM_DTYPE_ARRAY 3 + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0x0000 +#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 +#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 +#define IMAGE_SYM_CLASS_STATIC 0x0003 +#define IMAGE_SYM_CLASS_REGISTER 0x0004 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 +#define IMAGE_SYM_CLASS_LABEL 0x0006 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 +#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 +#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B +#define IMAGE_SYM_CLASS_UNION_TAG 0x000C +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E +#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 +#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 + +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 +#define IMAGE_SYM_CLASS_BLOCK 0x0064 +#define IMAGE_SYM_CLASS_FUNCTION 0x0065 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 +#define IMAGE_SYM_CLASS_FILE 0x0067 +#define IMAGE_SYM_CLASS_SECTION 0x0068 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 + +#define N_BTMASK 0x000F +#define N_TMASK 0x0030 +#define N_TMASK1 0x00C0 +#define N_TMASK2 0x00F0 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +#define BTYPE(x) ((x) & N_BTMASK) + +#ifndef ISPTR +#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) +#endif + +#ifndef ISFCN +#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) +#endif + +#ifndef ISARY +#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) +#endif + +#ifndef ISTAG +#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) +#endif + +#ifndef INCREF +#define INCREF(x) ((((x)&~N_BTMASK)<>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) +#endif + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 +#define IMAGE_COMDAT_SELECT_LARGEST 6 +#define IMAGE_COMDAT_SELECT_NEWEST 7 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/* Export module directory */ + +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + LPDWORD *AddressOfFunctions; + LPDWORD *AddressOfNames; + LPWORD *AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + +/* Import name entry */ +typedef struct _IMAGE_IMPORT_BY_NAME { + WORD Hint; + BYTE Name[1]; +} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; + +/* Import thunk */ +typedef struct _IMAGE_THUNK_DATA { + union { + LPBYTE ForwarderString; + FARPROC Function; + DWORD Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA; + +/* Import module directory */ + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; /* 0 for terminating null import descriptor */ + PIMAGE_THUNK_DATA OriginalFirstThunk; /* RVA to original unbound IAT */ + } u; + DWORD TimeDateStamp; /* 0 if not bound, + * -1 if bound, and real date\time stamp + * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT + * (new BIND) + * otherwise date/time stamp of DLL bound to + * (Old BIND) + */ + DWORD ForwarderChain; /* -1 if no forwarders */ + DWORD Name; + /* RVA to IAT (if bound this IAT has actual addresses) */ + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD NumberOfModuleForwarderRefs; +/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */ +} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_BOUND_FORWARDER_REF +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD Reserved; +} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; + +typedef struct _IMAGE_BASE_RELOCATION +{ + DWORD VirtualAddress; + DWORD SizeOfBlock; + WORD TypeOffset[1]; +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; + +typedef struct _IMAGE_RELOCATION +{ + union { + DWORD VirtualAddress; + DWORD RelocCount; + } u; + DWORD SymbolTableIndex; + WORD Type; +} IMAGE_RELOCATION; +typedef IMAGE_RELOCATION *PIMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +/* generic relocation types */ +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_SECTION 6 +#define IMAGE_REL_BASED_REL 7 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ +#define IMAGE_REL_BASED_DIR64 10 +#define IMAGE_REL_BASED_HIGH3ADJ 11 + +/* I386 relocation types */ +#define IMAGE_REL_I386_ABSOLUTE 0 +#define IMAGE_REL_I386_DIR16 1 +#define IMAGE_REL_I386_REL16 2 +#define IMAGE_REL_I386_DIR32 6 +#define IMAGE_REL_I386_DIR32NB 7 +#define IMAGE_REL_I386_SEG12 9 +#define IMAGE_REL_I386_SECTION 10 +#define IMAGE_REL_I386_SECREL 11 +#define IMAGE_REL_I386_REL32 20 + +/* MIPS relocation types */ +#define IMAGE_REL_MIPS_ABSOLUTE 0x0000 +#define IMAGE_REL_MIPS_REFHALF 0x0001 +#define IMAGE_REL_MIPS_REFWORD 0x0002 +#define IMAGE_REL_MIPS_JMPADDR 0x0003 +#define IMAGE_REL_MIPS_REFHI 0x0004 +#define IMAGE_REL_MIPS_REFLO 0x0005 +#define IMAGE_REL_MIPS_GPREL 0x0006 +#define IMAGE_REL_MIPS_LITERAL 0x0007 +#define IMAGE_REL_MIPS_SECTION 0x000A +#define IMAGE_REL_MIPS_SECREL 0x000B +#define IMAGE_REL_MIPS_SECRELLO 0x000C +#define IMAGE_REL_MIPS_SECRELHI 0x000D +#define IMAGE_REL_MIPS_JMPADDR16 0x0010 +#define IMAGE_REL_MIPS_REFWORDNB 0x0022 +#define IMAGE_REL_MIPS_PAIR 0x0025 + +/* ALPHA relocation types */ +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 +#define IMAGE_REL_ALPHA_REFLONG 0x0001 +#define IMAGE_REL_ALPHA_REFQUAD 0x0002 +#define IMAGE_REL_ALPHA_GPREL 0x0003 +#define IMAGE_REL_ALPHA_LITERAL 0x0004 +#define IMAGE_REL_ALPHA_LITUSE 0x0005 +#define IMAGE_REL_ALPHA_GPDISP 0x0006 +#define IMAGE_REL_ALPHA_BRADDR 0x0007 +#define IMAGE_REL_ALPHA_HINT 0x0008 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 +#define IMAGE_REL_ALPHA_REFHI 0x000A +#define IMAGE_REL_ALPHA_REFLO 0x000B +#define IMAGE_REL_ALPHA_PAIR 0x000C +#define IMAGE_REL_ALPHA_MATCH 0x000D +#define IMAGE_REL_ALPHA_SECTION 0x000E +#define IMAGE_REL_ALPHA_SECREL 0x000F +#define IMAGE_REL_ALPHA_REFLONGNB 0x0010 +#define IMAGE_REL_ALPHA_SECRELLO 0x0011 +#define IMAGE_REL_ALPHA_SECRELHI 0x0012 +#define IMAGE_REL_ALPHA_REFQ3 0x0013 +#define IMAGE_REL_ALPHA_REFQ2 0x0014 +#define IMAGE_REL_ALPHA_REFQ1 0x0015 +#define IMAGE_REL_ALPHA_GPRELLO 0x0016 +#define IMAGE_REL_ALPHA_GPRELHI 0x0017 + +/* PowerPC relocation types */ +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 +#define IMAGE_REL_PPC_ADDR64 0x0001 +#define IMAGE_REL_PPC_ADDR 0x0002 +#define IMAGE_REL_PPC_ADDR24 0x0003 +#define IMAGE_REL_PPC_ADDR16 0x0004 +#define IMAGE_REL_PPC_ADDR14 0x0005 +#define IMAGE_REL_PPC_REL24 0x0006 +#define IMAGE_REL_PPC_REL14 0x0007 +#define IMAGE_REL_PPC_TOCREL16 0x0008 +#define IMAGE_REL_PPC_TOCREL14 0x0009 +#define IMAGE_REL_PPC_ADDR32NB 0x000A +#define IMAGE_REL_PPC_SECREL 0x000B +#define IMAGE_REL_PPC_SECTION 0x000C +#define IMAGE_REL_PPC_IFGLUE 0x000D +#define IMAGE_REL_PPC_IMGLUE 0x000E +#define IMAGE_REL_PPC_SECREL16 0x000F +#define IMAGE_REL_PPC_REFHI 0x0010 +#define IMAGE_REL_PPC_REFLO 0x0011 +#define IMAGE_REL_PPC_PAIR 0x0012 +#define IMAGE_REL_PPC_SECRELLO 0x0013 +#define IMAGE_REL_PPC_SECRELHI 0x0014 +#define IMAGE_REL_PPC_GPREL 0x0015 +#define IMAGE_REL_PPC_TYPEMASK 0x00FF +/* modifier bits */ +#define IMAGE_REL_PPC_NEG 0x0100 +#define IMAGE_REL_PPC_BRTAKEN 0x0200 +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 +#define IMAGE_REL_PPC_TOCDEFN 0x0800 + +/* SH3 ? relocation type */ +#define IMAGE_REL_SH3_ABSOLUTE 0x0000 +#define IMAGE_REL_SH3_DIRECT16 0x0001 +#define IMAGE_REL_SH3_DIRECT 0x0002 +#define IMAGE_REL_SH3_DIRECT8 0x0003 +#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 +#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 +#define IMAGE_REL_SH3_DIRECT4 0x0006 +#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 +#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 +#define IMAGE_REL_SH3_PCREL8_WORD 0x0009 +#define IMAGE_REL_SH3_PCREL8_LONG 0x000A +#define IMAGE_REL_SH3_PCREL12_WORD 0x000B +#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C +#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D +#define IMAGE_REL_SH3_SECTION 0x000E +#define IMAGE_REL_SH3_SECREL 0x000F +#define IMAGE_REL_SH3_DIRECT32_NB 0x0010 + +/* ARM (Archimedes?) relocation types */ +#define IMAGE_REL_ARM_ABSOLUTE 0x0000 +#define IMAGE_REL_ARM_ADDR 0x0001 +#define IMAGE_REL_ARM_ADDR32NB 0x0002 +#define IMAGE_REL_ARM_BRANCH24 0x0003 +#define IMAGE_REL_ARM_BRANCH11 0x0004 +#define IMAGE_REL_ARM_SECTION 0x000E +#define IMAGE_REL_ARM_SECREL 0x000F + +/* IA64 relocation types */ +#define IMAGE_REL_IA64_ABSOLUTE 0x0000 +#define IMAGE_REL_IA64_IMM14 0x0001 +#define IMAGE_REL_IA64_IMM22 0x0002 +#define IMAGE_REL_IA64_IMM64 0x0003 +#define IMAGE_REL_IA64_DIR 0x0004 +#define IMAGE_REL_IA64_DIR64 0x0005 +#define IMAGE_REL_IA64_PCREL21B 0x0006 +#define IMAGE_REL_IA64_PCREL21M 0x0007 +#define IMAGE_REL_IA64_PCREL21F 0x0008 +#define IMAGE_REL_IA64_GPREL22 0x0009 +#define IMAGE_REL_IA64_LTOFF22 0x000A +#define IMAGE_REL_IA64_SECTION 0x000B +#define IMAGE_REL_IA64_SECREL22 0x000C +#define IMAGE_REL_IA64_SECREL64I 0x000D +#define IMAGE_REL_IA64_SECREL 0x000E +#define IMAGE_REL_IA64_LTOFF64 0x000F +#define IMAGE_REL_IA64_DIR32NB 0x0010 +#define IMAGE_REL_IA64_RESERVED_11 0x0011 +#define IMAGE_REL_IA64_RESERVED_12 0x0012 +#define IMAGE_REL_IA64_RESERVED_13 0x0013 +#define IMAGE_REL_IA64_RESERVED_14 0x0014 +#define IMAGE_REL_IA64_RESERVED_15 0x0015 +#define IMAGE_REL_IA64_RESERVED_16 0x0016 +#define IMAGE_REL_IA64_ADDEND 0x001F + +/* archive format */ + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER +{ + BYTE Name[16]; + BYTE Date[12]; + BYTE UserID[6]; + BYTE GroupID[6]; + BYTE Mode[8]; + BYTE Size[10]; + BYTE EndHeader[2]; +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* + * Resource directory stuff + */ +typedef struct _IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; + /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ +} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; + +#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + struct { + unsigned NameOffset:31; + unsigned NameIsString:1; + } s; + DWORD Name; + WORD Id; + } u1; + union { + DWORD OffsetToData; + struct { + unsigned OffsetToDirectory:31; + unsigned DataIsDirectory:1; + } s; + } u2; +} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; + + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + WORD Length; + CHAR NameString[ 1 ]; +} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; + +typedef struct _IMAGE_RESOURCE_DIR_STRING_U { + WORD Length; + WCHAR NameString[ 1 ]; +} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U; + +typedef struct _IMAGE_RESOURCE_DATA_ENTRY { + DWORD OffsetToData; + DWORD Size; + DWORD CodePage; + DWORD ResourceHandle; +} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; + + +typedef VOID CALLBACK (*PIMAGE_TLS_CALLBACK)( + LPVOID DllHandle,DWORD Reason,LPVOID Reserved +); + +typedef struct _IMAGE_TLS_DIRECTORY { + DWORD StartAddressOfRawData; + DWORD EndAddressOfRawData; + LPDWORD AddressOfIndex; + PIMAGE_TLS_CALLBACK *AddressOfCallBacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; +} IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY; + +typedef struct _IMAGE_DEBUG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Type; + DWORD SizeOfData; + DWORD AddressOfRawData; + DWORD PointerToRawData; +} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; + +#define IMAGE_DEBUG_TYPE_UNKNOWN 0 +#define IMAGE_DEBUG_TYPE_COFF 1 +#define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#define IMAGE_DEBUG_TYPE_FPO 3 +#define IMAGE_DEBUG_TYPE_MISC 4 +#define IMAGE_DEBUG_TYPE_EXCEPTION 5 +#define IMAGE_DEBUG_TYPE_FIXUP 6 +#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 +#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 +#define IMAGE_DEBUG_TYPE_BORLAND 9 +#define IMAGE_DEBUG_TYPE_RESERVED10 10 + +typedef struct _IMAGE_COFF_SYMBOLS_HEADER { + DWORD NumberOfSymbols; + DWORD LvaToFirstSymbol; + DWORD NumberOfLinenumbers; + DWORD LvaToFirstLinenumber; + DWORD RvaToFirstByteOfCode; + DWORD RvaToLastByteOfCode; + DWORD RvaToFirstByteOfData; + DWORD RvaToLastByteOfData; +} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER; + +#define FRAME_FPO 0 +#define FRAME_TRAP 1 +#define FRAME_TSS 2 +#define FRAME_NONFPO 3 + +typedef struct _FPO_DATA { + DWORD ulOffStart; + DWORD cbProcSize; + DWORD cdwLocals; + WORD cdwParams; + unsigned cbProlog : 8; + unsigned cbRegs : 3; + unsigned fHasSEH : 1; + unsigned fUseBP : 1; + unsigned reserved : 1; + unsigned cbFrame : 2; +} FPO_DATA, *PFPO_DATA; + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD GlobalFlagsClear; + DWORD GlobalFlagsSet; + DWORD CriticalSectionDefaultTimeout; + DWORD DeCommitFreeBlockThreshold; + DWORD DeCommitTotalFreeThreshold; + PVOID LockPrefixTable; + DWORD MaximumAllocationSize; + DWORD VirtualMemoryThreshold; + DWORD ProcessHeapFlags; + DWORD ProcessAffinityMask; + WORD CSDVersion; + WORD Reserved1; + PVOID EditList; + DWORD Reserved[1]; +} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY; + +typedef struct _IMAGE_FUNCTION_ENTRY { + DWORD StartingAddress; + DWORD EndingAddress; + DWORD EndOfPrologue; +} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY; + +/* This is the structure that appears at the very start of a .DBG file. */ + +typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { + WORD Signature; + WORD Flags; + WORD Machine; + WORD Characteristics; + DWORD TimeDateStamp; + DWORD CheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + DWORD NumberOfSections; + DWORD ExportedNamesSize; + DWORD DebugDirectorySize; + DWORD SectionAlignment; + DWORD Reserved[ 2 ]; +} IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER; + +#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 + + +typedef struct tagMESSAGE_RESOURCE_ENTRY { + WORD Length; + WORD Flags; + BYTE Text[1]; +} MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY; +#define MESSAGE_RESOURCE_UNICODE 0x0001 + +typedef struct tagMESSAGE_RESOURCE_BLOCK { + DWORD LowId; + DWORD HighId; + DWORD OffsetToEntries; +} MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK; + +typedef struct tagMESSAGE_RESOURCE_DATA { + DWORD NumberOfBlocks; + MESSAGE_RESOURCE_BLOCK Blocks[ 1 ]; +} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; + +/* + * Here follows typedefs for security and tokens. + */ + +/* + * First a constant for the following typdefs. + */ + +#define ANYSIZE_ARRAY 1 + +/* FIXME: Orphan. What does it point to? */ +typedef PVOID PACCESS_TOKEN; + +/* + * TOKEN_INFORMATION_CLASS + */ + +typedef enum _TOKEN_INFORMATION_CLASS { + TokenUser = 1, + TokenGroups, + TokenPrivileges, + TokenOwner, + TokenPrimaryGroup, + TokenDefaultDacl, + TokenSource, + TokenType, + TokenImpersonationLevel, + TokenStatistics +} TOKEN_INFORMATION_CLASS; + +#ifndef _SECURITY_DEFINED +#define _SECURITY_DEFINED + +#include "pshpack1.h" + +typedef DWORD ACCESS_MASK, *PACCESS_MASK; + +typedef struct _GENERIC_MAPPING { + ACCESS_MASK GenericRead; + ACCESS_MASK GenericWrite; + ACCESS_MASK GenericExecute; + ACCESS_MASK GenericAll; +} GENERIC_MAPPING, *PGENERIC_MAPPING; + +#ifndef SID_IDENTIFIER_AUTHORITY_DEFINED +#define SID_IDENTIFIER_AUTHORITY_DEFINED +typedef struct { + BYTE Value[6]; +} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY; +#endif /* !defined(SID_IDENTIFIER_AUTHORITY_DEFINED) */ + +#ifndef SID_DEFINED +#define SID_DEFINED +typedef struct _SID { + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[1]; +} SID,*PSID; +#endif /* !defined(SID_DEFINED) */ + +#define SID_REVISION (1) /* Current revision */ +#define SID_MAX_SUB_AUTHORITIES (15) /* current max subauths */ +#define SID_RECOMMENDED_SUB_AUTHORITIES (1) /* recommended subauths */ + + +/* + * ACL + */ + +#define ACL_REVISION1 1 +#define ACL_REVISION2 2 +#define ACL_REVISION3 3 +#define ACL_REVISION4 4 + +#define MIN_ACL_REVISION ACL_REVISION2 +#define MAX_ACL_REVISION ACL_REVISION4 + +typedef struct _ACL { + BYTE AclRevision; + BYTE Sbz1; + WORD AclSize; + WORD AceCount; + WORD Sbz2; +} ACL, *PACL; + +/* SECURITY_DESCRIPTOR */ +#define SECURITY_DESCRIPTOR_REVISION 1 +#define SECURITY_DESCRIPTOR_REVISION1 1 + + +#define SE_OWNER_DEFAULTED 0x0001 +#define SE_GROUP_DEFAULTED 0x0002 +#define SE_DACL_PRESENT 0x0004 +#define SE_DACL_DEFAULTED 0x0008 +#define SE_SACL_PRESENT 0x0010 +#define SE_SACL_DEFAULTED 0x0020 +#define SE_SELF_RELATIVE 0x8000 + +typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION; +typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; + +/* The security descriptor structure */ +typedef struct { + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + DWORD Owner; + DWORD Group; + DWORD Sacl; + DWORD Dacl; +} SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE; + +typedef struct { + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; +} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR; + +#define SECURITY_DESCRIPTOR_MIN_LENGTH (sizeof(SECURITY_DESCRIPTOR)) + +#include "poppack.h" + +#endif /* _SECURITY_DEFINED */ + +#include "pshpack1.h" + +/* + * SID_AND_ATTRIBUTES + */ + +typedef struct _SID_AND_ATTRIBUTES { + PSID Sid; + DWORD Attributes; +} SID_AND_ATTRIBUTES ; + +/* security entities */ +#define SECURITY_NULL_RID (0x00000000L) +#define SECURITY_WORLD_RID (0x00000000L) +#define SECURITY_LOCAL_RID (0X00000000L) + +#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} + +/* S-1-1 */ +#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} + +/* S-1-2 */ +#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2} + +/* S-1-3 */ +#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3} +#define SECURITY_CREATOR_OWNER_RID (0x00000000L) +#define SECURITY_CREATOR_GROUP_RID (0x00000001L) +#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L) +#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L) + +/* S-1-4 */ +#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4} + +/* S-1-5 */ +#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5} +#define SECURITY_DIALUP_RID 0x00000001L +#define SECURITY_NETWORK_RID 0x00000002L +#define SECURITY_BATCH_RID 0x00000003L +#define SECURITY_INTERACTIVE_RID 0x00000004L +#define SECURITY_LOGON_IDS_RID 0x00000005L +#define SECURITY_SERVICE_RID 0x00000006L +#define SECURITY_ANONYMOUS_LOGON_RID 0x00000007L +#define SECURITY_PROXY_RID 0x00000008L +#define SECURITY_ENTERPRISE_CONTROLLERS_RID 0x00000009L +#define SECURITY_PRINCIPAL_SELF_RID 0x0000000AL +#define SECURITY_AUTHENTICATED_USER_RID 0x0000000BL +#define SECURITY_RESTRICTED_CODE_RID 0x0000000CL +#define SECURITY_TERMINAL_SERVER_RID 0x0000000DL +#define SECURITY_LOCAL_SYSTEM_RID 0x00000012L +#define SECURITY_NT_NON_UNIQUE 0x00000015L +#define SECURITY_BUILTIN_DOMAIN_RID 0x00000020L + +#define DOMAIN_GROUP_RID_ADMINS 0x00000200L +#define DOMAIN_GROUP_RID_USERS 0x00000201L +#define DOMAIN_GROUP_RID_GUESTS 0x00000202L + +#define DOMAIN_ALIAS_RID_ADMINS 0x00000220L +#define DOMAIN_ALIAS_RID_USERS 0x00000221L +#define DOMAIN_ALIAS_RID_GUESTS 0x00000222L + +#define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID + +#define SECURITY_LOGON_IDS_RID_COUNT (3L) + +/* + * TOKEN_USER + */ + +typedef struct _TOKEN_USER { + SID_AND_ATTRIBUTES User; +} TOKEN_USER; + +/* + * TOKEN_GROUPS + */ + +typedef struct _TOKEN_GROUPS { + DWORD GroupCount; + SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; +} TOKEN_GROUPS; + +/* + * LUID_AND_ATTRIBUTES + */ + +typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + LONGLONG QuadPart; +} LARGE_INTEGER, *LPLARGE_INTEGER, *PLARGE_INTEGER; + +typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + LONGLONG QuadPart; +} ULARGE_INTEGER, *LPULARGE_INTEGER, *PULARGE_INTEGER; + +/* + * Locally Unique Identifier + */ + +typedef LARGE_INTEGER LUID,*PLUID; + +typedef struct _LUID_AND_ATTRIBUTES { + LUID Luid; + DWORD Attributes; +} LUID_AND_ATTRIBUTES; + +/* + * PRIVILEGE_SET + */ + +typedef struct _PRIVILEGE_SET { + DWORD PrivilegeCount; + DWORD Control; + LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; +} PRIVILEGE_SET, *PPRIVILEGE_SET; + +/* + * TOKEN_PRIVILEGES + */ + +typedef struct _TOKEN_PRIVILEGES { + DWORD PrivilegeCount; + LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; +} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES; + +/* + * TOKEN_OWNER + */ + +typedef struct _TOKEN_OWNER { + PSID Owner; +} TOKEN_OWNER; + +/* + * TOKEN_PRIMARY_GROUP + */ + +typedef struct _TOKEN_PRIMARY_GROUP { + PSID PrimaryGroup; +} TOKEN_PRIMARY_GROUP; + + +/* + * TOKEN_DEFAULT_DACL + */ + +typedef struct _TOKEN_DEFAULT_DACL { + PACL DefaultDacl; +} TOKEN_DEFAULT_DACL; + +/* + * TOKEN_SOURCEL + */ + +typedef struct _TOKEN_SOURCE { + char Sourcename[8]; + LUID SourceIdentifier; +} TOKEN_SOURCE; + +/* + * TOKEN_TYPE + */ + +typedef enum tagTOKEN_TYPE { + TokenPrimary = 1, + TokenImpersonation +} TOKEN_TYPE; + +/* + * SECURITY_IMPERSONATION_LEVEL + */ + +typedef enum _SECURITY_IMPERSONATION_LEVEL { + SecurityAnonymous, + SecurityIdentification, + SecurityImpersonation, + SecurityDelegation +} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; + + +typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, + * PSECURITY_CONTEXT_TRACKING_MODE; +/* + * Quality of Service + */ + +typedef struct _SECURITY_QUALITY_OF_SERVICE { + DWORD Length; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode; + WIN_BOOL EffectiveOnly; +} SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE; + +/* + * TOKEN_STATISTICS + */ + +typedef struct _TOKEN_STATISTICS { + LUID TokenId; + LUID AuthenticationId; + LARGE_INTEGER ExpirationTime; + TOKEN_TYPE TokenType; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + DWORD DynamicCharged; + DWORD DynamicAvailable; + DWORD GroupCount; + DWORD PrivilegeCount; + LUID ModifiedId; +} TOKEN_STATISTICS; + +/* + * ACLs of NT + */ + +#define ACL_REVISION 2 + +#define ACL_REVISION1 1 +#define ACL_REVISION2 2 + +/* ACEs, directly starting after an ACL */ +typedef struct _ACE_HEADER { + BYTE AceType; + BYTE AceFlags; + WORD AceSize; +} ACE_HEADER,*PACE_HEADER; + +/* AceType */ +#define ACCESS_ALLOWED_ACE_TYPE 0 +#define ACCESS_DENIED_ACE_TYPE 1 +#define SYSTEM_AUDIT_ACE_TYPE 2 +#define SYSTEM_ALARM_ACE_TYPE 3 + +/* inherit AceFlags */ +#define OBJECT_INHERIT_ACE 0x01 +#define CONTAINER_INHERIT_ACE 0x02 +#define NO_PROPAGATE_INHERIT_ACE 0x04 +#define INHERIT_ONLY_ACE 0x08 +#define VALID_INHERIT_FLAGS 0x0F + +/* AceFlags mask for what events we (should) audit */ +#define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 +#define FAILED_ACCESS_ACE_FLAG 0x80 + +/* different ACEs depending on AceType + * SidStart marks the begin of a SID + * so the thing finally looks like this: + * 0: ACE_HEADER + * 4: ACCESS_MASK + * 8... : SID + */ +typedef struct _ACCESS_ALLOWED_ACE { + ACE_HEADER Header; + DWORD Mask; + DWORD SidStart; +} ACCESS_ALLOWED_ACE,*PACCESS_ALLOWED_ACE; + +typedef struct _ACCESS_DENIED_ACE { + ACE_HEADER Header; + DWORD Mask; + DWORD SidStart; +} ACCESS_DENIED_ACE,*PACCESS_DENIED_ACE; + +typedef struct _SYSTEM_AUDIT_ACE { + ACE_HEADER Header; + DWORD Mask; + DWORD SidStart; +} SYSTEM_AUDIT_ACE,*PSYSTEM_AUDIT_ACE; + +typedef struct _SYSTEM_ALARM_ACE { + ACE_HEADER Header; + DWORD Mask; + DWORD SidStart; +} SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE; + +typedef enum tagSID_NAME_USE { + SidTypeUser = 1, + SidTypeGroup, + SidTypeDomain, + SidTypeAlias, + SidTypeWellKnownGroup, + SidTypeDeletedAccount, + SidTypeInvalid, + SidTypeUnknown +} SID_NAME_USE,*PSID_NAME_USE; + +/* Access rights */ + +#define DELETE 0x00010000 +#define READ_CONTROL 0x00020000 +#define WRITE_DAC 0x00040000 +#define WRITE_OWNER 0x00080000 +#define SYNCHRONIZE 0x00100000 +#define STANDARD_RIGHTS_REQUIRED 0x000f0000 + +#define STANDARD_RIGHTS_READ READ_CONTROL +#define STANDARD_RIGHTS_WRITE READ_CONTROL +#define STANDARD_RIGHTS_EXECUTE READ_CONTROL + +#define STANDARD_RIGHTS_ALL 0x001f0000 + +#define SPECIFIC_RIGHTS_ALL 0x0000ffff + +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 +#define GENERIC_EXECUTE 0x20000000 +#define GENERIC_ALL 0x10000000 + +#define MAXIMUM_ALLOWED 0x02000000 +#define ACCESS_SYSTEM_SECURITY 0x01000000 + +#define EVENT_MODIFY_STATE 0x0002 +#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +#define SEMAPHORE_MODIFY_STATE 0x0002 +#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +#define MUTEX_MODIFY_STATE 0x0001 +#define MUTEX_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1) + +#define PROCESS_TERMINATE 0x0001 +#define PROCESS_CREATE_THREAD 0x0002 +#define PROCESS_VM_OPERATION 0x0008 +#define PROCESS_VM_READ 0x0010 +#define PROCESS_VM_WRITE 0x0020 +#define PROCESS_DUP_HANDLE 0x0040 +#define PROCESS_CREATE_PROCESS 0x0080 +#define PROCESS_SET_QUOTA 0x0100 +#define PROCESS_SET_INFORMATION 0x0200 +#define PROCESS_QUERY_INFORMATION 0x0400 +#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xfff) + +#define THREAD_TERMINATE 0x0001 +#define THREAD_SUSPEND_RESUME 0x0002 +#define THREAD_GET_CONTEXT 0x0008 +#define THREAD_SET_CONTEXT 0x0010 +#define THREAD_SET_INFORMATION 0x0020 +#define THREAD_QUERY_INFORMATION 0x0040 +#define THREAD_SET_THREAD_TOKEN 0x0080 +#define THREAD_IMPERSONATE 0x0100 +#define THREAD_DIRECT_IMPERSONATION 0x0200 +#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3ff) + +#define THREAD_BASE_PRIORITY_LOWRT 15 +#define THREAD_BASE_PRIORITY_MAX 2 +#define THREAD_BASE_PRIORITY_MIN -2 +#define THREAD_BASE_PRIORITY_IDLE -15 + +#define FILE_READ_DATA 0x0001 /* file & pipe */ +#define FILE_LIST_DIRECTORY 0x0001 /* directory */ +#define FILE_WRITE_DATA 0x0002 /* file & pipe */ +#define FILE_ADD_FILE 0x0002 /* directory */ +#define FILE_APPEND_DATA 0x0004 /* file */ +#define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */ +#define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */ +#define FILE_READ_EA 0x0008 /* file & directory */ +#define FILE_READ_PROPERTIES FILE_READ_EA +#define FILE_WRITE_EA 0x0010 /* file & directory */ +#define FILE_WRITE_PROPERTIES FILE_WRITE_EA +#define FILE_EXECUTE 0x0020 /* file */ +#define FILE_TRAVERSE 0x0020 /* directory */ +#define FILE_DELETE_CHILD 0x0040 /* directory */ +#define FILE_READ_ATTRIBUTES 0x0080 /* all */ +#define FILE_WRITE_ATTRIBUTES 0x0100 /* all */ +#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff) + +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | \ + FILE_READ_ATTRIBUTES | FILE_READ_EA | \ + SYNCHRONIZE) +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | \ + FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | \ + FILE_APPEND_DATA | SYNCHRONIZE) +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_EXECUTE | \ + FILE_READ_ATTRIBUTES | SYNCHRONIZE) + + +/* File attribute flags + */ +#define FILE_SHARE_READ 0x00000001L +#define FILE_SHARE_WRITE 0x00000002L +#define FILE_SHARE_DELETE 0x00000004L +#define FILE_ATTRIBUTE_READONLY 0x00000001L +#define FILE_ATTRIBUTE_HIDDEN 0x00000002L +#define FILE_ATTRIBUTE_SYSTEM 0x00000004L +#define FILE_ATTRIBUTE_LABEL 0x00000008L /* Not in Windows API */ +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010L +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020L +#define FILE_ATTRIBUTE_NORMAL 0x00000080L +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100L +#define FILE_ATTRIBUTE_ATOMIC_WRITE 0x00000200L +#define FILE_ATTRIBUTE_XACTION_WRITE 0x00000400L +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800L +#define FILE_ATTRIBUTE_OFFLINE 0x00001000L + +/* File alignments (NT) */ +#define FILE_BYTE_ALIGNMENT 0x00000000 +#define FILE_WORD_ALIGNMENT 0x00000001 +#define FILE_LONG_ALIGNMENT 0x00000003 +#define FILE_QUAD_ALIGNMENT 0x00000007 +#define FILE_OCTA_ALIGNMENT 0x0000000f +#define FILE_32_BYTE_ALIGNMENT 0x0000001f +#define FILE_64_BYTE_ALIGNMENT 0x0000003f +#define FILE_128_BYTE_ALIGNMENT 0x0000007f +#define FILE_256_BYTE_ALIGNMENT 0x000000ff +#define FILE_512_BYTE_ALIGNMENT 0x000001ff + +#define REG_NONE 0 /* no type */ +#define REG_SZ 1 /* string type (ASCII) */ +#define REG_EXPAND_SZ 2 /* string, includes %ENVVAR% (expanded by caller) (ASCII) */ +#define REG_BINARY 3 /* binary format, callerspecific */ +/* YES, REG_DWORD == REG_DWORD_LITTLE_ENDIAN */ +#define REG_DWORD 4 /* DWORD in little endian format */ +#define REG_DWORD_LITTLE_ENDIAN 4 /* DWORD in little endian format */ +#define REG_DWORD_BIG_ENDIAN 5 /* DWORD in big endian format */ +#define REG_LINK 6 /* symbolic link (UNICODE) */ +#define REG_MULTI_SZ 7 /* multiple strings, delimited by \0, terminated by \0\0 (ASCII) */ +#define REG_RESOURCE_LIST 8 /* resource list? huh? */ +#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */ +#define REG_RESOURCE_REQUIREMENTS_LIST 10 + +/* ----------------------------- begin registry ----------------------------- */ + +/* Registry security values */ +#define OWNER_SECURITY_INFORMATION 0x00000001 +#define GROUP_SECURITY_INFORMATION 0x00000002 +#define DACL_SECURITY_INFORMATION 0x00000004 +#define SACL_SECURITY_INFORMATION 0x00000008 + +#define REG_OPTION_RESERVED 0x00000000 +#define REG_OPTION_NON_VOLATILE 0x00000000 +#define REG_OPTION_VOLATILE 0x00000001 +#define REG_OPTION_CREATE_LINK 0x00000002 +#define REG_OPTION_BACKUP_RESTORE 0x00000004 /* FIXME */ +#define REG_OPTION_OPEN_LINK 0x00000008 +#define REG_LEGAL_OPTION (REG_OPTION_RESERVED| \ + REG_OPTION_NON_VOLATILE| \ + REG_OPTION_VOLATILE| \ + REG_OPTION_CREATE_LINK| \ + REG_OPTION_BACKUP_RESTORE| \ + REG_OPTION_OPEN_LINK) + + +#define REG_CREATED_NEW_KEY 0x00000001 +#define REG_OPENED_EXISTING_KEY 0x00000002 + +/* For RegNotifyChangeKeyValue */ +#define REG_NOTIFY_CHANGE_NAME 0x1 + +#define KEY_QUERY_VALUE 0x00000001 +#define KEY_SET_VALUE 0x00000002 +#define KEY_CREATE_SUB_KEY 0x00000004 +#define KEY_ENUMERATE_SUB_KEYS 0x00000008 +#define KEY_NOTIFY 0x00000010 +#define KEY_CREATE_LINK 0x00000020 + +#define KEY_READ ((STANDARD_RIGHTS_READ| \ + KEY_QUERY_VALUE| \ + KEY_ENUMERATE_SUB_KEYS| \ + KEY_NOTIFY) \ + & (~SYNCHRONIZE) \ + ) +#define KEY_WRITE ((STANDARD_RIGHTS_WRITE| \ + KEY_SET_VALUE| \ + KEY_CREATE_SUB_KEY) \ + & (~SYNCHRONIZE) \ + ) +#define KEY_EXECUTE ((KEY_READ) \ + & (~SYNCHRONIZE)) \ + ) +#define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL| \ + KEY_QUERY_VALUE| \ + KEY_SET_VALUE| \ + KEY_CREATE_SUB_KEY| \ + KEY_ENUMERATE_SUB_KEYS| \ + KEY_NOTIFY| \ + KEY_CREATE_LINK) \ + & (~SYNCHRONIZE) \ + ) +/* ------------------------------ end registry ------------------------------ */ + + +#define RtlEqualMemory(Destination, Source, Length) (!memcmp((Destination),(Source),(Length))) +#define RtlMoveMemory(Destination, Source, Length) memmove((Destination),(Source),(Length)) +#define RtlCopyMemory(Destination, Source, Length) memcpy((Destination),(Source),(Length)) +#define RtlFillMemory(Destination, Length, Fill) memset((Destination),(Fill),(Length)) +#define RtlZeroMemory(Destination, Length) memset((Destination),0,(Length)) + +#include "poppack.h" + +#endif /* __WINE_WINNT_H */ diff --git a/linphone/win32acm/wine/winreg.h b/linphone/win32acm/wine/winreg.h new file mode 100644 index 000000000..8c290b58f --- /dev/null +++ b/linphone/win32acm/wine/winreg.h @@ -0,0 +1,57 @@ +/* + * Win32 registry defines (see also winnt.h) + */ +#ifndef __WINE_WINREG_H +#define __WINE_WINREG_H + +#include "winbase.h" +#include "winnt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/* +#define SHELL_ERROR_SUCCESS 0L +#define SHELL_ERROR_BADDB 1L +#define SHELL_ERROR_BADKEY 2L +#define SHELL_ERROR_CANTOPEN 3L +#define SHELL_ERROR_CANTREAD 4L +#define SHELL_ERROR_CANTWRITE 5L +#define SHELL_ERROR_OUTOFMEMORY 6L +#define SHELL_ERROR_INVALID_PARAMETER 7L +#define SHELL_ERROR_ACCESS_DENIED 8L +*/ + +#define HKEY_CLASSES_ROOT ((HKEY) 0x80000000) +#define HKEY_CURRENT_USER ((HKEY) 0x80000001) +#define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002) +#define HKEY_USERS ((HKEY) 0x80000003) +#define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004) +#define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005) +#define HKEY_DYN_DATA ((HKEY) 0x80000006) + +/* + * registry provider structs + */ +typedef struct value_entA +{ LPSTR ve_valuename; + DWORD ve_valuelen; + DWORD_PTR ve_valueptr; + DWORD ve_type; +} VALENTA, *PVALENTA; + +typedef struct value_entW { + LPWSTR ve_valuename; + DWORD ve_valuelen; + DWORD_PTR ve_valueptr; + DWORD ve_type; +} VALENTW, *PVALENTW; + +typedef ACCESS_MASK REGSAM; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINREG_H */ diff --git a/linphone/win32acm/wine/winuser.h b/linphone/win32acm/wine/winuser.h new file mode 100644 index 000000000..d74864ef7 --- /dev/null +++ b/linphone/win32acm/wine/winuser.h @@ -0,0 +1,2929 @@ +#ifndef _WINUSER_ +#define _WINUSER_ + +#ifndef RC_INVOKED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "pshpack1.h" + +/* flags for HIGHCONTRAST dwFlags field */ +#define HCF_HIGHCONTRASTON 0x00000001 +#define HCF_AVAILABLE 0x00000002 +#define HCF_HOTKEYACTIVE 0x00000004 +#define HCF_CONFIRMHOTKEY 0x00000008 +#define HCF_HOTKEYSOUND 0x00000010 +#define HCF_INDICATOR 0x00000020 +#define HCF_HOTKEYAVAILABLE 0x00000040 + +typedef struct tagHIGHCONTRASTA +{ + UINT cbSize; + DWORD dwFlags; + LPSTR lpszDefaultScheme; +} HIGHCONTRASTA, *LPHIGHCONTRASTA; + +typedef struct tagHIGHCONTRASTW +{ + UINT cbSize; + DWORD dwFlags; + LPWSTR lpszDefaultScheme; +} HIGHCONTRASTW, *LPHIGHCONTRASTW; + +DECL_WINELIB_TYPE_AW(HIGHCONTRAST) +DECL_WINELIB_TYPE_AW(LPHIGHCONTRAST) + +typedef struct +{ + UINT message; + UINT paramL; + UINT paramH; + DWORD time; + HWND hwnd; +} EVENTMSG, *LPEVENTMSG; + + + /* Mouse hook structure */ + +typedef struct +{ + POINT pt; + HWND hwnd; + UINT wHitTestCode; + DWORD dwExtraInfo; +} MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT; + + + /* Hardware hook structure */ + +typedef struct +{ + HWND hWnd; + UINT wMessage; + WPARAM wParam; + LPARAM lParam; +} HARDWAREHOOKSTRUCT, *LPHARDWAREHOOKSTRUCT; + + + /* Debug hook structure */ + +typedef struct +{ + DWORD idThread; + DWORD idThreadInstaller; + LPARAM lParam; + WPARAM wParam; + INT code; +} DEBUGHOOKINFO, *LPDEBUGHOOKINFO; + +#define HKL_PREV 0 +#define HKL_NEXT 1 + +#define KLF_ACTIVATE 0x00000001 +#define KLF_SUBSTITUTE_OK 0x00000002 +#define KLF_UNLOADPREVIOUS 0x00000004 +#define KLF_REORDER 0x00000008 +#define KLF_REPLACELANG 0x00000010 +#define KLF_NOTELLSHELL 0x00000080 + +#define KL_NAMELENGTH 9 + + /***** Dialogs *****/ +#ifdef FSHIFT +/* Gcc on Solaris has a version of this that we don't care about. */ +#undef FSHIFT +#endif + +#define FVIRTKEY TRUE /* Assumed to be == TRUE */ +#define FNOINVERT 0x02 +#define FSHIFT 0x04 +#define FCONTROL 0x08 +#define FALT 0x10 + + +typedef struct tagANIMATIONINFO +{ + UINT cbSize; + INT iMinAnimate; +} ANIMATIONINFO, *LPANIMATIONINFO; + +typedef struct tagNMHDR +{ + HWND hwndFrom; + UINT idFrom; + UINT code; +} NMHDR, *LPNMHDR; + +typedef struct +{ + UINT cbSize; + INT iTabLength; + INT iLeftMargin; + INT iRightMargin; + UINT uiLengthDrawn; +} DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS; + +#define WM_USER 0x0400 + +#define DT_EDITCONTROL 0x00002000 +#define DT_PATH_ELLIPSIS 0x00004000 +#define DT_END_ELLIPSIS 0x00008000 +#define DT_MODIFYSTRING 0x00010000 +#define DT_RTLREADING 0x00020000 +#define DT_WORD_ELLIPSIS 0x00040000 + +typedef struct +{ + LPARAM lParam; + WPARAM16 wParam; + UINT16 message; + HWND16 hwnd; +} CWPSTRUCT16, *LPCWPSTRUCT16; + +typedef struct +{ + LPARAM lParam; + WPARAM wParam; + UINT message; + HWND hwnd; +} CWPSTRUCT, *LPCWPSTRUCT; + + + +typedef struct +{ + LRESULT lResult; + LPARAM lParam; + WPARAM16 wParam; + DWORD message; + HWND16 hwnd; +} CWPRETSTRUCT16, *LPCWPRETSTRUCT16; + +typedef struct +{ + LRESULT lResult; + LPARAM lParam; + WPARAM wParam; + DWORD message; + HWND hwnd; +} CWPRETSTRUCT, *LPCWPRETSTRUCT; + +typedef struct +{ + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition WINE_PACKED; + POINT ptMaxPosition WINE_PACKED; + RECT rcNormalPosition WINE_PACKED; +} WINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + + /* WINDOWPLACEMENT flags */ +#define WPF_SETMINPOSITION 0x0001 +#define WPF_RESTORETOMAXIMIZED 0x0002 + +/***** Dialogs *****/ + + /* cbWndExtra bytes for dialog class */ +#define DLGWINDOWEXTRA 30 + +/* Button control styles */ +#define BS_PUSHBUTTON 0x00000000L +#define BS_DEFPUSHBUTTON 0x00000001L +#define BS_CHECKBOX 0x00000002L +#define BS_AUTOCHECKBOX 0x00000003L +#define BS_RADIOBUTTON 0x00000004L +#define BS_3STATE 0x00000005L +#define BS_AUTO3STATE 0x00000006L +#define BS_GROUPBOX 0x00000007L +#define BS_USERBUTTON 0x00000008L +#define BS_AUTORADIOBUTTON 0x00000009L +#define BS_OWNERDRAW 0x0000000BL +#define BS_LEFTTEXT 0x00000020L + +#define BS_TEXT 0x00000000L +#define BS_ICON 0x00000040L +#define BS_BITMAP 0x00000080L +#define BS_LEFT 0x00000100L +#define BS_RIGHT 0x00000200L +#define BS_CENTER 0x00000300L +#define BS_TOP 0x00000400L +#define BS_BOTTOM 0x00000800L +#define BS_VCENTER 0x00000C00L +#define BS_PUSHLIKE 0x00001000L +#define BS_MULTILINE 0x00002000L +#define BS_NOTIFY 0x00004000L +#define BS_FLAT 0x00008000L + + /* Dialog styles */ +#define DS_ABSALIGN 0x0001 +#define DS_SYSMODAL 0x0002 +#define DS_3DLOOK 0x0004 /* win95 */ +#define DS_FIXEDSYS 0x0008 /* win95 */ +#define DS_NOFAILCREATE 0x0010 /* win95 */ +#define DS_LOCALEDIT 0x0020 +#define DS_SETFONT 0x0040 +#define DS_MODALFRAME 0x0080 +#define DS_NOIDLEMSG 0x0100 +#define DS_SETFOREGROUND 0x0200 /* win95 */ +#define DS_CONTROL 0x0400 /* win95 */ +#define DS_CENTER 0x0800 /* win95 */ +#define DS_CENTERMOUSE 0x1000 /* win95 */ +#define DS_CONTEXTHELP 0x2000 /* win95 */ + + + /* Dialog messages */ +#define DM_GETDEFID (WM_USER+0) +#define DM_SETDEFID (WM_USER+1) + +#define DC_HASDEFID 0x534b + +/* Owner draw control types */ +#define ODT_MENU 1 +#define ODT_LISTBOX 2 +#define ODT_COMBOBOX 3 +#define ODT_BUTTON 4 +#define ODT_STATIC 5 + +/* Owner draw actions */ +#define ODA_DRAWENTIRE 0x0001 +#define ODA_SELECT 0x0002 +#define ODA_FOCUS 0x0004 + +/* Owner draw state */ +#define ODS_SELECTED 0x0001 +#define ODS_GRAYED 0x0002 +#define ODS_DISABLED 0x0004 +#define ODS_CHECKED 0x0008 +#define ODS_FOCUS 0x0010 +#define ODS_COMBOBOXEDIT 0x1000 +#define ODS_HOTLIGHT 0x0040 +#define ODS_INACTIVE 0x0080 + +/* Edit control styles */ +#define ES_LEFT 0x00000000 +#define ES_CENTER 0x00000001 +#define ES_RIGHT 0x00000002 +#define ES_MULTILINE 0x00000004 +#define ES_UPPERCASE 0x00000008 +#define ES_LOWERCASE 0x00000010 +#define ES_PASSWORD 0x00000020 +#define ES_AUTOVSCROLL 0x00000040 +#define ES_AUTOHSCROLL 0x00000080 +#define ES_NOHIDESEL 0x00000100 +#define ES_OEMCONVERT 0x00000400 +#define ES_READONLY 0x00000800 +#define ES_WANTRETURN 0x00001000 +#define ES_NUMBER 0x00002000 + +/* OEM Resource Ordinal Numbers */ +#define OBM_CLOSED 32731 +#define OBM_RADIOCHECK 32732 +#define OBM_TRTYPE 32733 +#define OBM_LFARROWI 32734 +#define OBM_RGARROWI 32735 +#define OBM_DNARROWI 32736 +#define OBM_UPARROWI 32737 +#define OBM_COMBO 32738 +#define OBM_MNARROW 32739 +#define OBM_LFARROWD 32740 +#define OBM_RGARROWD 32741 +#define OBM_DNARROWD 32742 +#define OBM_UPARROWD 32743 +#define OBM_RESTORED 32744 +#define OBM_ZOOMD 32745 +#define OBM_REDUCED 32746 +#define OBM_RESTORE 32747 +#define OBM_ZOOM 32748 +#define OBM_REDUCE 32749 +#define OBM_LFARROW 32750 +#define OBM_RGARROW 32751 +#define OBM_DNARROW 32752 +#define OBM_UPARROW 32753 +#define OBM_CLOSE 32754 +#define OBM_OLD_RESTORE 32755 +#define OBM_OLD_ZOOM 32756 +#define OBM_OLD_REDUCE 32757 +#define OBM_BTNCORNERS 32758 +#define OBM_CHECKBOXES 32759 +#define OBM_CHECK 32760 +#define OBM_BTSIZE 32761 +#define OBM_OLD_LFARROW 32762 +#define OBM_OLD_RGARROW 32763 +#define OBM_OLD_DNARROW 32764 +#define OBM_OLD_UPARROW 32765 +#define OBM_SIZE 32766 +#define OBM_OLD_CLOSE 32767 + +#define OCR_BUMMER 100 +#define OCR_DRAGOBJECT 101 + +#define OCR_NORMAL 32512 +#define OCR_IBEAM 32513 +#define OCR_WAIT 32514 +#define OCR_CROSS 32515 +#define OCR_UP 32516 +#define OCR_SIZE 32640 +#define OCR_ICON 32641 +#define OCR_SIZENWSE 32642 +#define OCR_SIZENESW 32643 +#define OCR_SIZEWE 32644 +#define OCR_SIZENS 32645 +#define OCR_SIZEALL 32646 +#define OCR_ICOCUR 32647 +#define OCR_NO 32648 +#define OCR_APPSTARTING 32650 +#define OCR_HELP 32651 /* only defined in wine */ + +#define OIC_SAMPLE 32512 +#define OIC_HAND 32513 +#define OIC_QUES 32514 +#define OIC_BANG 32515 +#define OIC_NOTE 32516 +#define OIC_PORTRAIT 32517 +#define OIC_LANDSCAPE 32518 +#define OIC_WINEICON 32519 +#define OIC_FOLDER 32520 +#define OIC_FOLDER2 32521 +#define OIC_FLOPPY 32522 +#define OIC_CDROM 32523 +#define OIC_HDISK 32524 +#define OIC_NETWORK 32525 + +#define COLOR_SCROLLBAR 0 +#define COLOR_BACKGROUND 1 +#define COLOR_ACTIVECAPTION 2 +#define COLOR_INACTIVECAPTION 3 +#define COLOR_MENU 4 +#define COLOR_WINDOW 5 +#define COLOR_WINDOWFRAME 6 +#define COLOR_MENUTEXT 7 +#define COLOR_WINDOWTEXT 8 +#define COLOR_CAPTIONTEXT 9 +#define COLOR_ACTIVEBORDER 10 +#define COLOR_INACTIVEBORDER 11 +#define COLOR_APPWORKSPACE 12 +#define COLOR_HIGHLIGHT 13 +#define COLOR_HIGHLIGHTTEXT 14 +#define COLOR_BTNFACE 15 +#define COLOR_BTNSHADOW 16 +#define COLOR_GRAYTEXT 17 +#define COLOR_BTNTEXT 18 +#define COLOR_INACTIVECAPTIONTEXT 19 +#define COLOR_BTNHIGHLIGHT 20 +/* win95 colors */ +#define COLOR_3DDKSHADOW 21 +#define COLOR_3DLIGHT 22 +#define COLOR_INFOTEXT 23 +#define COLOR_INFOBK 24 +#define COLOR_DESKTOP COLOR_BACKGROUND +#define COLOR_3DFACE COLOR_BTNFACE +#define COLOR_3DSHADOW COLOR_BTNSHADOW +#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT +#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT +#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT +/* win98 colors */ +#define COLOR_ALTERNATEBTNFACE 25 /* undocumented, constant's name unknown */ +#define COLOR_HOTLIGHT 26 +#define COLOR_GRADIENTACTIVECAPTION 27 +#define COLOR_GRADIENTINACTIVECAPTION 28 + + /* WM_CTLCOLOR values */ +#define CTLCOLOR_MSGBOX 0 +#define CTLCOLOR_EDIT 1 +#define CTLCOLOR_LISTBOX 2 +#define CTLCOLOR_BTN 3 +#define CTLCOLOR_DLG 4 +#define CTLCOLOR_SCROLLBAR 5 +#define CTLCOLOR_STATIC 6 + +/* Edit control messages */ +#define EM_GETSEL 0x00b0 +#define EM_SETSEL 0x00b1 +#define EM_GETRECT 0x00b2 +#define EM_SETRECT 0x00b3 +#define EM_SETRECTNP 0x00b4 +#define EM_SCROLL 0x00b5 +#define EM_LINESCROLL 0x00b6 +#define EM_SCROLLCARET 0x00b7 +#define EM_GETMODIFY 0x00b8 +#define EM_SETMODIFY 0x00b9 +#define EM_GETLINECOUNT 0x00ba +#define EM_LINEINDEX 0x00bb +#define EM_SETHANDLE 0x00bc +#define EM_GETHANDLE 0x00bd +#define EM_GETTHUMB 0x00be +/* FIXME : missing from specs 0x00bf and 0x00c0 */ +#define EM_LINELENGTH 0x00c1 +#define EM_REPLACESEL 0x00c2 +/* FIXME : missing from specs 0x00c3 */ +#define EM_GETLINE 0x00c4 +#define EM_LIMITTEXT 0x00c5 +#define EM_CANUNDO 0x00c6 +#define EM_UNDO 0x00c7 +#define EM_FMTLINES 0x00c8 +#define EM_LINEFROMCHAR 0x00c9 +/* FIXME : missing from specs 0x00ca */ +#define EM_SETTABSTOPS 0x00cb +#define EM_SETPASSWORDCHAR 0x00cc +#define EM_EMPTYUNDOBUFFER 0x00cd +#define EM_GETFIRSTVISIBLELINE 0x00ce +#define EM_SETREADONLY 0x00cf +#define EM_SETWORDBREAKPROC 0x00d0 +#define EM_GETWORDBREAKPROC 0x00d1 +#define EM_GETPASSWORDCHAR 0x00d2 +#define EM_SETMARGINS 0x00d3 +#define EM_GETMARGINS 0x00d4 +#define EM_GETLIMITTEXT 0x00d5 +#define EM_POSFROMCHAR 0x00d6 +#define EM_CHARFROMPOS 0x00d7 +/* a name change since win95 */ +#define EM_SETLIMITTEXT EM_LIMITTEXT + +/* EDITWORDBREAKPROC code values */ +#define WB_LEFT 0 +#define WB_RIGHT 1 +#define WB_ISDELIMITER 2 + +/* Edit control notification codes */ +#define EN_SETFOCUS 0x0100 +#define EN_KILLFOCUS 0x0200 +#define EN_CHANGE 0x0300 +#define EN_UPDATE 0x0400 +#define EN_ERRSPACE 0x0500 +#define EN_MAXTEXT 0x0501 +#define EN_HSCROLL 0x0601 +#define EN_VSCROLL 0x0602 + +/* New since win95 : EM_SETMARGIN parameters */ +#define EC_LEFTMARGIN 0x0001 +#define EC_RIGHTMARGIN 0x0002 +#define EC_USEFONTINFO 0xffff + + +/* Messages */ + + /* WM_GETDLGCODE values */ + + +#define WM_NULL 0x0000 +#define WM_CREATE 0x0001 +#define WM_DESTROY 0x0002 +#define WM_MOVE 0x0003 +#define WM_SIZEWAIT 0x0004 +#define WM_SIZE 0x0005 +#define WM_ACTIVATE 0x0006 +#define WM_SETFOCUS 0x0007 +#define WM_KILLFOCUS 0x0008 +#define WM_SETVISIBLE 0x0009 +#define WM_ENABLE 0x000a +#define WM_SETREDRAW 0x000b +#define WM_SETTEXT 0x000c +#define WM_GETTEXT 0x000d +#define WM_GETTEXTLENGTH 0x000e +#define WM_PAINT 0x000f +#define WM_CLOSE 0x0010 +#define WM_QUERYENDSESSION 0x0011 +#define WM_QUIT 0x0012 +#define WM_QUERYOPEN 0x0013 +#define WM_ERASEBKGND 0x0014 +#define WM_SYSCOLORCHANGE 0x0015 +#define WM_ENDSESSION 0x0016 +#define WM_SYSTEMERROR 0x0017 +#define WM_SHOWWINDOW 0x0018 +#define WM_CTLCOLOR 0x0019 +#define WM_WININICHANGE 0x001a +#define WM_SETTINGCHANGE WM_WININICHANGE +#define WM_DEVMODECHANGE 0x001b +#define WM_ACTIVATEAPP 0x001c +#define WM_FONTCHANGE 0x001d +#define WM_TIMECHANGE 0x001e +#define WM_CANCELMODE 0x001f +#define WM_SETCURSOR 0x0020 +#define WM_MOUSEACTIVATE 0x0021 +#define WM_CHILDACTIVATE 0x0022 +#define WM_QUEUESYNC 0x0023 +#define WM_GETMINMAXINFO 0x0024 + +#define WM_PAINTICON 0x0026 +#define WM_ICONERASEBKGND 0x0027 +#define WM_NEXTDLGCTL 0x0028 +#define WM_ALTTABACTIVE 0x0029 +#define WM_SPOOLERSTATUS 0x002a +#define WM_DRAWITEM 0x002b +#define WM_MEASUREITEM 0x002c +#define WM_DELETEITEM 0x002d +#define WM_VKEYTOITEM 0x002e +#define WM_CHARTOITEM 0x002f +#define WM_SETFONT 0x0030 +#define WM_GETFONT 0x0031 +#define WM_SETHOTKEY 0x0032 +#define WM_GETHOTKEY 0x0033 +#define WM_FILESYSCHANGE 0x0034 +#define WM_ISACTIVEICON 0x0035 +#define WM_QUERYPARKICON 0x0036 +#define WM_QUERYDRAGICON 0x0037 +#define WM_QUERYSAVESTATE 0x0038 +#define WM_COMPAREITEM 0x0039 +#define WM_TESTING 0x003a + +#define WM_OTHERWINDOWCREATED 0x003c +#define WM_OTHERWINDOWDESTROYED 0x003d +#define WM_ACTIVATESHELLWINDOW 0x003e + +#define WM_COMPACTING 0x0041 + +#define WM_COMMNOTIFY 0x0044 +#define WM_WINDOWPOSCHANGING 0x0046 +#define WM_WINDOWPOSCHANGED 0x0047 +#define WM_POWER 0x0048 + + /* Win32 4.0 messages */ +#define WM_COPYDATA 0x004a +#define WM_CANCELJOURNAL 0x004b +#define WM_NOTIFY 0x004e +#define WM_HELP 0x0053 +#define WM_NOTIFYFORMAT 0x0055 + +#define WM_CONTEXTMENU 0x007b +#define WM_STYLECHANGING 0x007c +#define WM_STYLECHANGED 0x007d +#define WM_DISPLAYCHANGE 0x007e +#define WM_GETICON 0x007f +#define WM_SETICON 0x0080 + + /* Non-client system messages */ +#define WM_NCCREATE 0x0081 +#define WM_NCDESTROY 0x0082 +#define WM_NCCALCSIZE 0x0083 +#define WM_NCHITTEST 0x0084 +#define WM_NCPAINT 0x0085 +#define WM_NCACTIVATE 0x0086 + +#define WM_GETDLGCODE 0x0087 +#define WM_SYNCPAINT 0x0088 +#define WM_SYNCTASK 0x0089 + + /* Non-client mouse messages */ +#define WM_NCMOUSEMOVE 0x00a0 +#define WM_NCLBUTTONDOWN 0x00a1 +#define WM_NCLBUTTONUP 0x00a2 +#define WM_NCLBUTTONDBLCLK 0x00a3 +#define WM_NCRBUTTONDOWN 0x00a4 +#define WM_NCRBUTTONUP 0x00a5 +#define WM_NCRBUTTONDBLCLK 0x00a6 +#define WM_NCMBUTTONDOWN 0x00a7 +#define WM_NCMBUTTONUP 0x00a8 +#define WM_NCMBUTTONDBLCLK 0x00a9 + + /* Keyboard messages */ +#define WM_KEYDOWN 0x0100 +#define WM_KEYUP 0x0101 +#define WM_CHAR 0x0102 +#define WM_DEADCHAR 0x0103 +#define WM_SYSKEYDOWN 0x0104 +#define WM_SYSKEYUP 0x0105 +#define WM_SYSCHAR 0x0106 +#define WM_SYSDEADCHAR 0x0107 +#define WM_KEYFIRST WM_KEYDOWN +#define WM_KEYLAST 0x0108 + +/* Win32 4.0 messages for IME */ +#define WM_IME_STARTCOMPOSITION 0x010d +#define WM_IME_ENDCOMPOSITION 0x010e +#define WM_IME_COMPOSITION 0x010f +#define WM_IME_KEYLAST 0x010f + +#define WM_INITDIALOG 0x0110 +#define WM_COMMAND 0x0111 +#define WM_SYSCOMMAND 0x0112 +#define WM_TIMER 0x0113 +#define WM_SYSTIMER 0x0118 + + /* scroll messages */ +#define WM_HSCROLL 0x0114 +#define WM_VSCROLL 0x0115 + +/* Menu messages */ +#define WM_INITMENU 0x0116 +#define WM_INITMENUPOPUP 0x0117 + +#define WM_MENUSELECT 0x011F +#define WM_MENUCHAR 0x0120 +#define WM_ENTERIDLE 0x0121 + +#define WM_LBTRACKPOINT 0x0131 + + /* Win32 CTLCOLOR messages */ +#define WM_CTLCOLORMSGBOX 0x0132 +#define WM_CTLCOLOREDIT 0x0133 +#define WM_CTLCOLORLISTBOX 0x0134 +#define WM_CTLCOLORBTN 0x0135 +#define WM_CTLCOLORDLG 0x0136 +#define WM_CTLCOLORSCROLLBAR 0x0137 +#define WM_CTLCOLORSTATIC 0x0138 + + /* Mouse messages */ +#define WM_MOUSEMOVE 0x0200 +#define WM_LBUTTONDOWN 0x0201 +#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEWHEEL 0x020A +#define WM_MOUSEFIRST WM_MOUSEMOVE + + +#define WM_MOUSELAST WM_MOUSEWHEEL + +#define WHEEL_DELTA 120 +#define WHEEL_PAGESCROLL (UINT_MAX) +#define WM_PARENTNOTIFY 0x0210 +#define WM_ENTERMENULOOP 0x0211 +#define WM_EXITMENULOOP 0x0212 +#define WM_NEXTMENU 0x0213 + + /* Win32 4.0 messages */ +#define WM_SIZING 0x0214 +#define WM_CAPTURECHANGED 0x0215 +#define WM_MOVING 0x0216 + + /* MDI messages */ +#define WM_MDICREATE 0x0220 +#define WM_MDIDESTROY 0x0221 +#define WM_MDIACTIVATE 0x0222 +#define WM_MDIRESTORE 0x0223 +#define WM_MDINEXT 0x0224 +#define WM_MDIMAXIMIZE 0x0225 +#define WM_MDITILE 0x0226 +#define WM_MDICASCADE 0x0227 +#define WM_MDIICONARRANGE 0x0228 +#define WM_MDIGETACTIVE 0x0229 +#define WM_MDIREFRESHMENU 0x0234 + + /* D&D messages */ +#define WM_DROPOBJECT 0x022A +#define WM_QUERYDROPOBJECT 0x022B +#define WM_BEGINDRAG 0x022C +#define WM_DRAGLOOP 0x022D +#define WM_DRAGSELECT 0x022E +#define WM_DRAGMOVE 0x022F +#define WM_MDISETMENU 0x0230 + +#define WM_ENTERSIZEMOVE 0x0231 +#define WM_EXITSIZEMOVE 0x0232 +#define WM_DROPFILES 0x0233 + + +/* Win32 4.0 messages for IME */ +#define WM_IME_SETCONTEXT 0x0281 +#define WM_IME_NOTIFY 0x0282 +#define WM_IME_CONTROL 0x0283 +#define WM_IME_COMPOSITIONFULL 0x0284 +#define WM_IME_SELECT 0x0285 +#define WM_IME_CHAR 0x0286 +/* Win32 5.0 messages for IME */ +#define WM_IME_REQUEST 0x0288 + +/* Win32 4.0 messages for IME */ +#define WM_IME_KEYDOWN 0x0290 +#define WM_IME_KEYUP 0x0291 + +/* Clipboard command messages */ +#define WM_CUT 0x0300 +#define WM_COPY 0x0301 +#define WM_PASTE 0x0302 +#define WM_CLEAR 0x0303 +#define WM_UNDO 0x0304 + +/* Clipboard owner messages */ +#define WM_RENDERFORMAT 0x0305 +#define WM_RENDERALLFORMATS 0x0306 +#define WM_DESTROYCLIPBOARD 0x0307 + +/* Clipboard viewer messages */ +#define WM_DRAWCLIPBOARD 0x0308 +#define WM_PAINTCLIPBOARD 0x0309 +#define WM_VSCROLLCLIPBOARD 0x030A +#define WM_SIZECLIPBOARD 0x030B +#define WM_ASKCBFORMATNAME 0x030C +#define WM_CHANGECBCHAIN 0x030D +#define WM_HSCROLLCLIPBOARD 0x030E + +#define WM_QUERYNEWPALETTE 0x030F +#define WM_PALETTEISCHANGING 0x0310 +#define WM_PALETTECHANGED 0x0311 +#define WM_HOTKEY 0x0312 + +#define WM_PRINT 0x0317 +#define WM_PRINTCLIENT 0x0318 + + /* FIXME: This does not belong to any libwine interface header */ + /* MFC messages [360-38f] */ + +#define WM_QUERYAFXWNDPROC 0x0360 +#define WM_SIZEPARENT 0x0361 +#define WM_SETMESSAGESTRING 0x0362 +#define WM_IDLEUPDATECMDUI 0x0363 +#define WM_INITIALUPDATE 0x0364 +#define WM_COMMANDHELP 0x0365 +#define WM_HELPHITTEST 0x0366 +#define WM_EXITHELPMODE 0x0367 +#define WM_RECALCPARENT 0x0368 +#define WM_SIZECHILD 0x0369 +#define WM_KICKIDLE 0x036A +#define WM_QUERYCENTERWND 0x036B +#define WM_DISABLEMODAL 0x036C +#define WM_FLOATSTATUS 0x036D +#define WM_ACTIVATETOPLEVEL 0x036E +#define WM_QUERY3DCONTROLS 0x036F +#define WM_SOCKET_NOTIFY 0x0373 +#define WM_SOCKET_DEAD 0x0374 +#define WM_POPMESSAGESTRING 0x0375 +#define WM_OCC_LOADFROMSTREAM 0x0376 +#define WM_OCC_LOADFROMSTORAGE 0x0377 +#define WM_OCC_INITNEW 0x0378 +#define WM_OCC_LOADFROMSTREAM_EX 0x037A +#define WM_OCC_LOADFROMSTORAGE_EX 0x037B +#define WM_QUEUE_SENTINEL 0x0379 + +#define WM_PENWINFIRST 0x0380 +#define WM_PENWINLAST 0x038F + +/* end of MFC messages */ + +/* FIXME: The following two lines do not belong to any libwine interface header */ +#define WM_COALESCE_FIRST 0x0390 +#define WM_COALESCE_LAST 0x039F + +#define WM_APP 0x8000 + + +#define DLGC_WANTARROWS 0x0001 +#define DLGC_WANTTAB 0x0002 +#define DLGC_WANTALLKEYS 0x0004 +#define DLGC_WANTMESSAGE 0x0004 +#define DLGC_HASSETSEL 0x0008 +#define DLGC_DEFPUSHBUTTON 0x0010 +#define DLGC_UNDEFPUSHBUTTON 0x0020 +#define DLGC_RADIOBUTTON 0x0040 +#define DLGC_WANTCHARS 0x0080 +#define DLGC_STATIC 0x0100 +#define DLGC_BUTTON 0x2000 + +/* Standard dialog button IDs */ +#define IDOK 1 +#define IDCANCEL 2 +#define IDABORT 3 +#define IDRETRY 4 +#define IDIGNORE 5 +#define IDYES 6 +#define IDNO 7 +#define IDCLOSE 8 +#define IDHELP 9 + +/****** Window classes ******/ + +typedef struct tagCREATESTRUCTA +{ + LPVOID lpCreateParams; + HINSTANCE hInstance; + HMENU hMenu; + HWND hwndParent; + INT cy; + INT cx; + INT y; + INT x; + LONG style; + LPCSTR lpszName; + LPCSTR lpszClass; + DWORD dwExStyle; +} CREATESTRUCTA, *LPCREATESTRUCTA; + +typedef struct +{ + LPVOID lpCreateParams; + HINSTANCE hInstance; + HMENU hMenu; + HWND hwndParent; + INT cy; + INT cx; + INT y; + INT x; + LONG style; + LPCWSTR lpszName; + LPCWSTR lpszClass; + DWORD dwExStyle; +} CREATESTRUCTW, *LPCREATESTRUCTW; + +DECL_WINELIB_TYPE_AW(CREATESTRUCT) +DECL_WINELIB_TYPE_AW(LPCREATESTRUCT) + +typedef struct +{ + HDC hdc; + WIN_BOOL fErase; + RECT rcPaint; + WIN_BOOL fRestore; + WIN_BOOL fIncUpdate; + BYTE rgbReserved[32]; +} PAINTSTRUCT, *PPAINTSTRUCT, *LPPAINTSTRUCT; + +typedef struct +{ + HMENU hWindowMenu; + UINT idFirstChild; +} CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT; + + +typedef struct +{ + LPCSTR szClass; + LPCSTR szTitle; + HINSTANCE hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + LPARAM lParam; +} MDICREATESTRUCTA, *LPMDICREATESTRUCTA; + +typedef struct +{ + LPCWSTR szClass; + LPCWSTR szTitle; + HINSTANCE hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + LPARAM lParam; +} MDICREATESTRUCTW, *LPMDICREATESTRUCTW; + +DECL_WINELIB_TYPE_AW(MDICREATESTRUCT) +DECL_WINELIB_TYPE_AW(LPMDICREATESTRUCT) + +#define MDITILE_VERTICAL 0x0000 +#define MDITILE_HORIZONTAL 0x0001 +#define MDITILE_SKIPDISABLED 0x0002 + +#define MDIS_ALLCHILDSTYLES 0x0001 + +typedef struct { + DWORD styleOld; + DWORD styleNew; +} STYLESTRUCT, *LPSTYLESTRUCT; + + /* Offsets for GetWindowLong() and GetWindowWord() */ +#define GWL_USERDATA (-21) +#define GWL_EXSTYLE (-20) +#define GWL_STYLE (-16) +#define GWW_ID (-12) +#define GWL_ID GWW_ID +#define GWW_HWNDPARENT (-8) +#define GWL_HWNDPARENT GWW_HWNDPARENT +#define GWW_HINSTANCE (-6) +#define GWL_HINSTANCE GWW_HINSTANCE +#define GWL_WNDPROC (-4) +#define DWL_MSGRESULT 0 +#define DWL_DLGPROC 4 +#define DWL_USER 8 + + /* GetWindow() constants */ +#define GW_HWNDFIRST 0 +#define GW_HWNDLAST 1 +#define GW_HWNDNEXT 2 +#define GW_HWNDPREV 3 +#define GW_OWNER 4 +#define GW_CHILD 5 + + /* WM_GETMINMAXINFO struct */ +typedef struct +{ + POINT ptReserved; + POINT ptMaxSize; + POINT ptMaxPosition; + POINT ptMinTrackSize; + POINT ptMaxTrackSize; +} MINMAXINFO, *PMINMAXINFO, *LPMINMAXINFO; + + + /* RedrawWindow() flags */ +#define RDW_INVALIDATE 0x0001 +#define RDW_INTERNALPAINT 0x0002 +#define RDW_ERASE 0x0004 +#define RDW_VALIDATE 0x0008 +#define RDW_NOINTERNALPAINT 0x0010 +#define RDW_NOERASE 0x0020 +#define RDW_NOCHILDREN 0x0040 +#define RDW_ALLCHILDREN 0x0080 +#define RDW_UPDATENOW 0x0100 +#define RDW_ERASENOW 0x0200 +#define RDW_FRAME 0x0400 +#define RDW_NOFRAME 0x0800 + +/* debug flags */ +#define DBGFILL_ALLOC 0xfd +#define DBGFILL_FREE 0xfb +#define DBGFILL_BUFFER 0xf9 +#define DBGFILL_STACK 0xf7 + + /* WM_WINDOWPOSCHANGING/CHANGED struct */ +typedef struct tagWINDOWPOS +{ + HWND hwnd; + HWND hwndInsertAfter; + INT x; + INT y; + INT cx; + INT cy; + UINT flags; +} WINDOWPOS, *PWINDOWPOS, *LPWINDOWPOS; + + + /* WM_MOUSEACTIVATE return values */ +#define MA_ACTIVATE 1 +#define MA_ACTIVATEANDEAT 2 +#define MA_NOACTIVATE 3 +#define MA_NOACTIVATEANDEAT 4 + + /* WM_ACTIVATE wParam values */ +#define WA_INACTIVE 0 +#define WA_ACTIVE 1 +#define WA_CLICKACTIVE 2 + +/* WM_GETICON/WM_SETICON params values */ +#define ICON_SMALL 0 +#define ICON_BIG 1 + + /* WM_NCCALCSIZE parameter structure */ +typedef struct +{ + RECT rgrc[3]; + WINDOWPOS *lppos; +} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS; + + + /* WM_NCCALCSIZE return flags */ +#define WVR_ALIGNTOP 0x0010 +#define WVR_ALIGNLEFT 0x0020 +#define WVR_ALIGNBOTTOM 0x0040 +#define WVR_ALIGNRIGHT 0x0080 +#define WVR_HREDRAW 0x0100 +#define WVR_VREDRAW 0x0200 +#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) +#define WVR_VALIDRECTS 0x0400 + + /* WM_NCHITTEST return codes */ +#define HTERROR (-2) +#define HTTRANSPARENT (-1) +#define HTNOWHERE 0 +#define HTCLIENT 1 +#define HTCAPTION 2 +#define HTSYSMENU 3 +#define HTSIZE 4 +#define HTMENU 5 +#define HTHSCROLL 6 +#define HTVSCROLL 7 +#define HTMINBUTTON 8 +#define HTMAXBUTTON 9 +#define HTLEFT 10 +#define HTRIGHT 11 +#define HTTOP 12 +#define HTTOPLEFT 13 +#define HTTOPRIGHT 14 +#define HTBOTTOM 15 +#define HTBOTTOMLEFT 16 +#define HTBOTTOMRIGHT 17 +#define HTBORDER 18 +#define HTGROWBOX HTSIZE +#define HTREDUCE HTMINBUTTON +#define HTZOOM HTMAXBUTTON +#define HTOBJECT 19 +#define HTCLOSE 20 +#define HTHELP 21 +#define HTSIZEFIRST HTLEFT +#define HTSIZELAST HTBOTTOMRIGHT + + /* WM_SYSCOMMAND parameters */ +#ifdef SC_SIZE /* at least HP-UX: already defined in /usr/include/sys/signal.h */ +#undef SC_SIZE +#endif +#define SC_SIZE 0xf000 +#define SC_MOVE 0xf010 +#define SC_MINIMIZE 0xf020 +#define SC_MAXIMIZE 0xf030 +#define SC_NEXTWINDOW 0xf040 +#define SC_PREVWINDOW 0xf050 +#define SC_CLOSE 0xf060 +#define SC_VSCROLL 0xf070 +#define SC_HSCROLL 0xf080 +#define SC_MOUSEMENU 0xf090 +#define SC_KEYMENU 0xf100 +#define SC_ARRANGE 0xf110 +#define SC_RESTORE 0xf120 +#define SC_TASKLIST 0xf130 +#define SC_SCREENSAVE 0xf140 +#define SC_HOTKEY 0xf150 + +#define CS_VREDRAW 0x0001 +#define CS_HREDRAW 0x0002 +#define CS_KEYCVTWINDOW 0x0004 +#define CS_DBLCLKS 0x0008 +#define CS_OWNDC 0x0020 +#define CS_CLASSDC 0x0040 +#define CS_PARENTDC 0x0080 +#define CS_NOKEYCVT 0x0100 +#define CS_NOCLOSE 0x0200 +#define CS_SAVEBITS 0x0800 +#define CS_BYTEALIGNCLIENT 0x1000 +#define CS_BYTEALIGNWINDOW 0x2000 +#define CS_GLOBALCLASS 0x4000 +#define CS_IME 0x00010000 + +#define PRF_CHECKVISIBLE 0x00000001L +#define PRF_NONCLIENT 0x00000002L +#define PRF_CLIENT 0x00000004L +#define PRF_ERASEBKGND 0x00000008L +#define PRF_CHILDREN 0x00000010L +#define PRF_OWNED 0x00000020L + + /* Offsets for GetClassLong() and GetClassWord() */ +#define GCL_MENUNAME (-8) +#define GCW_HBRBACKGROUND (-10) +#define GCL_HBRBACKGROUND GCW_HBRBACKGROUND +#define GCW_HCURSOR (-12) +#define GCL_HCURSOR GCW_HCURSOR +#define GCW_HICON (-14) +#define GCL_HICON GCW_HICON +#define GCW_HMODULE (-16) +#define GCL_HMODULE GCW_HMODULE +#define GCW_CBWNDEXTRA (-18) +#define GCL_CBWNDEXTRA GCW_CBWNDEXTRA +#define GCW_CBCLSEXTRA (-20) +#define GCL_CBCLSEXTRA GCW_CBCLSEXTRA +#define GCL_WNDPROC (-24) +#define GCW_STYLE (-26) +#define GCL_STYLE GCW_STYLE +#define GCW_ATOM (-32) +#define GCW_HICONSM (-34) +#define GCL_HICONSM GCW_HICONSM + + +/***** Window hooks *****/ + + /* Hook values */ +#define WH_MIN (-1) +#define WH_MSGFILTER (-1) +#define WH_JOURNALRECORD 0 +#define WH_JOURNALPLAYBACK 1 +#define WH_KEYBOARD 2 +#define WH_GETMESSAGE 3 +#define WH_CALLWNDPROC 4 +#define WH_CBT 5 +#define WH_SYSMSGFILTER 6 +#define WH_MOUSE 7 +#define WH_HARDWARE 8 +#define WH_DEBUG 9 +#define WH_SHELL 10 +#define WH_FOREGROUNDIDLE 11 +#define WH_CALLWNDPROCRET 12 +#define WH_MAX 12 + +#define WH_MINHOOK WH_MIN +#define WH_MAXHOOK WH_MAX +#define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1) + + /* Hook action codes */ +#define HC_ACTION 0 +#define HC_GETNEXT 1 +#define HC_SKIP 2 +#define HC_NOREMOVE 3 +#define HC_NOREM HC_NOREMOVE +#define HC_SYSMODALON 4 +#define HC_SYSMODALOFF 5 + + /* CallMsgFilter() values */ +#define MSGF_DIALOGBOX 0 +#define MSGF_MESSAGEBOX 1 +#define MSGF_MENU 2 +#define MSGF_MOVE 3 +#define MSGF_SIZE 4 +#define MSGF_SCROLLBAR 5 +#define MSGF_NEXTWINDOW 6 +#define MSGF_MAINLOOP 8 +#define MSGF_USER 4096 + +typedef struct +{ + UINT style; + WNDPROC lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCSTR lpszMenuName; + LPCSTR lpszClassName; +} WNDCLASSA, *LPWNDCLASSA; + +typedef struct +{ + UINT style; + WNDPROC lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCWSTR lpszMenuName; + LPCWSTR lpszClassName; +} WNDCLASSW, *LPWNDCLASSW; + +DECL_WINELIB_TYPE_AW(WNDCLASS) +DECL_WINELIB_TYPE_AW(LPWNDCLASS) + +typedef struct { + DWORD dwData; + DWORD cbData; + LPVOID lpData; +} COPYDATASTRUCT, *PCOPYDATASTRUCT, *LPCOPYDATASTRUCT; + +typedef struct { + HMENU hmenuIn; + HMENU hmenuNext; + HWND hwndNext; +} MDINEXTMENU, *PMDINEXTMENU, *LPMDINEXTMENU; + +/* WinHelp internal structure */ +typedef struct { + WORD size; + WORD command; + LONG data; + LONG reserved; + WORD ofsFilename; + WORD ofsData; +} WINHELP,*LPWINHELP; + +typedef struct +{ + UINT16 mkSize; + BYTE mkKeyList; + BYTE szKeyphrase[1]; +} MULTIKEYHELP, *LPMULTIKEYHELP; + +typedef struct { + WORD wStructSize; + WORD x; + WORD y; + WORD dx; + WORD dy; + WORD wMax; + char rgchMember[2]; +} HELPWININFO, *LPHELPWININFO; + +#define HELP_CONTEXT 0x0001 +#define HELP_QUIT 0x0002 +#define HELP_INDEX 0x0003 +#define HELP_CONTENTS 0x0003 +#define HELP_HELPONHELP 0x0004 +#define HELP_SETINDEX 0x0005 +#define HELP_SETCONTENTS 0x0005 +#define HELP_CONTEXTPOPUP 0x0008 +#define HELP_FORCEFILE 0x0009 +#define HELP_KEY 0x0101 +#define HELP_COMMAND 0x0102 +#define HELP_PARTIALKEY 0x0105 +#define HELP_MULTIKEY 0x0201 +#define HELP_SETWINPOS 0x0203 +#define HELP_CONTEXTMENU 0x000a +#define HELP_FINDER 0x000b +#define HELP_WM_HELP 0x000c +#define HELP_SETPOPUP_POS 0x000d + +#define HELP_TCARD 0x8000 +#define HELP_TCARD_DATA 0x0010 +#define HELP_TCARD_OTHER_CALLER 0x0011 + + + /* ChangeDisplaySettings return codes */ + +#define DISP_CHANGE_SUCCESSFUL 0 +#define DISP_CHANGE_RESTART 1 +#define DISP_CHANGE_FAILED (-1) +#define DISP_CHANGE_BADMODE (-2) +#define DISP_CHANGE_NOTUPDATED (-3) +#define DISP_CHANGE_BADFLAGS (-4) +#define DISP_CHANGE_BADPARAM (-5) + +/* ChangeDisplaySettings.dwFlags */ +#define CDS_UPDATEREGISTRY 0x00000001 +#define CDS_TEST 0x00000002 +#define CDS_FULLSCREEN 0x00000004 +#define CDS_GLOBAL 0x00000008 +#define CDS_SET_PRIMARY 0x00000010 +#define CDS_RESET 0x40000000 +#define CDS_SETRECT 0x20000000 +#define CDS_NORESET 0x10000000 + +/* flags to FormatMessage */ +#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 +#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 +#define FORMAT_MESSAGE_FROM_STRING 0x00000400 +#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 +#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 +#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000 +#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF + +typedef struct +{ + UINT cbSize; + UINT style; + WNDPROC lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCSTR lpszMenuName; + LPCSTR lpszClassName; + HICON hIconSm; +} WNDCLASSEXA, *LPWNDCLASSEXA; + +typedef struct +{ + UINT cbSize; + UINT style; + WNDPROC lpfnWndProc; + INT cbClsExtra; + INT cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCWSTR lpszMenuName; + LPCWSTR lpszClassName; + HICON hIconSm; +} WNDCLASSEXW, *LPWNDCLASSEXW; + +DECL_WINELIB_TYPE_AW(WNDCLASSEX) +DECL_WINELIB_TYPE_AW(LPWNDCLASSEX) + +typedef struct tagMSG +{ + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +} MSG, *LPMSG; + +#define POINTSTOPOINT(pt, pts) \ + { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); \ + (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); } + +#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x), (short)((pt).y))) + + +/* Cursors / Icons */ + +typedef struct { + WIN_BOOL fIcon; + DWORD xHotspot; + DWORD yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; +} ICONINFO,*LPICONINFO; + + +/* this is the 6 byte accel struct used in Win32 when presented to the user */ +typedef struct +{ + BYTE fVirt; + BYTE pad0; + WORD key; + WORD cmd; +} ACCEL, *LPACCEL; + +/* this is the 8 byte accel struct used in Win32 resources (internal only) */ +typedef struct +{ + BYTE fVirt; + BYTE pad0; + WORD key; + WORD cmd; + WORD pad1; +} PE_ACCEL, *LPPE_ACCEL; + + +/* Flags for TrackPopupMenu */ +#define TPM_LEFTBUTTON 0x0000 +#define TPM_RIGHTBUTTON 0x0002 +#define TPM_LEFTALIGN 0x0000 +#define TPM_CENTERALIGN 0x0004 +#define TPM_RIGHTALIGN 0x0008 +#define TPM_TOPALIGN 0x0000 +#define TPM_VCENTERALIGN 0x0010 +#define TPM_BOTTOMALIGN 0x0020 +#define TPM_HORIZONTAL 0x0000 +#define TPM_VERTICAL 0x0040 +#define TPM_NONOTIFY 0x0080 +#define TPM_RETURNCMD 0x0100 + +typedef struct +{ + UINT cbSize; + RECT rcExclude; +} TPMPARAMS, *LPTPMPARAMS; + +/* FIXME: not sure this one is correct */ +typedef struct { + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + DWORD dwItemData; + LPSTR dwTypeData; + UINT cch; + HBITMAP hbmpItem; +} MENUITEMINFOA, *LPMENUITEMINFOA; + +typedef struct { + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + DWORD dwItemData; + LPWSTR dwTypeData; + UINT cch; + HBITMAP hbmpItem; +} MENUITEMINFOW, *LPMENUITEMINFOW; + +DECL_WINELIB_TYPE_AW(MENUITEMINFO) +DECL_WINELIB_TYPE_AW(LPMENUITEMINFO) + +typedef struct { + DWORD cbSize; + DWORD fMask; + DWORD dwStyle; + UINT cyMax; + HBRUSH hbrBack; + DWORD dwContextHelpID; + DWORD dwMenuData; +} MENUINFO, *LPMENUINFO; + +typedef MENUINFO const * LPCMENUINFO; + +#define MIM_MAXHEIGHT 0x00000001 +#define MIM_BACKGROUND 0x00000002 +#define MIM_HELPID 0x00000004 +#define MIM_MENUDATA 0x00000008 +#define MIM_STYLE 0x00000010 +#define MIM_APPLYTOSUBMENUS 0x80000000 + +typedef struct { + WORD versionNumber; + WORD offset; +} MENUITEMTEMPLATEHEADER, *PMENUITEMTEMPLATEHEADER; + + +typedef struct { + WORD mtOption; + WORD mtID; + WCHAR mtString[1]; +} MENUITEMTEMPLATE, *PMENUITEMTEMPLATE; + + +typedef VOID MENUTEMPLATE; +typedef PVOID *LPMENUTEMPLATE; + +/* Field specifiers for MENUITEMINFO[AW] type. */ +#define MIIM_STATE 0x00000001 +#define MIIM_ID 0x00000002 +#define MIIM_SUBMENU 0x00000004 +#define MIIM_CHECKMARKS 0x00000008 +#define MIIM_TYPE 0x00000010 +#define MIIM_DATA 0x00000020 +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 + +#define HBMMENU_CALLBACK ((HBITMAP) -1) +#define HBMMENU_SYSTEM ((HBITMAP) 1) +#define HBMMENU_MBAR_RESTORE ((HBITMAP) 2) +#define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3) +#define HBMMENU_MBAR_CLOSE ((HBITMAP) 5) +#define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6) +#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7) +#define HBMMENU_POPUP_CLOSE ((HBITMAP) 8) +#define HBMMENU_POPUP_RESTORE ((HBITMAP) 9) +#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10) +#define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11) + +/* DrawState defines ... */ +typedef WIN_BOOL CALLBACK (*DRAWSTATEPROC)(HDC,LPARAM,WPARAM,INT,INT); + +/* WM_H/VSCROLL commands */ +#define SB_LINEUP 0 +#define SB_LINELEFT 0 +#define SB_LINEDOWN 1 +#define SB_LINERIGHT 1 +#define SB_PAGEUP 2 +#define SB_PAGELEFT 2 +#define SB_PAGEDOWN 3 +#define SB_PAGERIGHT 3 +#define SB_THUMBPOSITION 4 +#define SB_THUMBTRACK 5 +#define SB_TOP 6 +#define SB_LEFT 6 +#define SB_BOTTOM 7 +#define SB_RIGHT 7 +#define SB_ENDSCROLL 8 + +/* Scroll bar selection constants */ +#define SB_HORZ 0 +#define SB_VERT 1 +#define SB_CTL 2 +#define SB_BOTH 3 + +/* Scrollbar styles */ +#define SBS_HORZ 0x0000L +#define SBS_VERT 0x0001L +#define SBS_TOPALIGN 0x0002L +#define SBS_LEFTALIGN 0x0002L +#define SBS_BOTTOMALIGN 0x0004L +#define SBS_RIGHTALIGN 0x0004L +#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L +#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L +#define SBS_SIZEBOX 0x0008L +#define SBS_SIZEGRIP 0x0010L + +/* EnableScrollBar() flags */ +#define ESB_ENABLE_BOTH 0x0000 +#define ESB_DISABLE_BOTH 0x0003 + +#define ESB_DISABLE_LEFT 0x0001 +#define ESB_DISABLE_RIGHT 0x0002 + +#define ESB_DISABLE_UP 0x0001 +#define ESB_DISABLE_DOWN 0x0002 + +#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT +#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT + +/* Win32 button control messages */ +#define BM_GETCHECK 0x00f0 +#define BM_SETCHECK 0x00f1 +#define BM_GETSTATE 0x00f2 +#define BM_SETSTATE 0x00f3 +#define BM_SETSTYLE 0x00f4 +#define BM_CLICK 0x00f5 +#define BM_GETIMAGE 0x00f6 +#define BM_SETIMAGE 0x00f7 +/* Winelib button control messages */ + +/* Button notification codes */ +#define BN_CLICKED 0 +#define BN_PAINT 1 +#define BN_HILITE 2 +#define BN_UNHILITE 3 +#define BN_DISABLE 4 +#define BN_DOUBLECLICKED 5 + +/* Button states */ +#define BST_UNCHECKED 0x0000 +#define BST_CHECKED 0x0001 +#define BST_INDETERMINATE 0x0002 +#define BST_PUSHED 0x0004 +#define BST_FOCUS 0x0008 + +/* Static Control Styles */ +#define SS_LEFT 0x00000000L +#define SS_CENTER 0x00000001L +#define SS_RIGHT 0x00000002L +#define SS_ICON 0x00000003L +#define SS_BLACKRECT 0x00000004L +#define SS_GRAYRECT 0x00000005L +#define SS_WHITERECT 0x00000006L +#define SS_BLACKFRAME 0x00000007L +#define SS_GRAYFRAME 0x00000008L +#define SS_WHITEFRAME 0x00000009L + +#define SS_SIMPLE 0x0000000BL +#define SS_LEFTNOWORDWRAP 0x0000000CL + +#define SS_OWNERDRAW 0x0000000DL +#define SS_BITMAP 0x0000000EL +#define SS_ENHMETAFILE 0x0000000FL + +#define SS_ETCHEDHORZ 0x00000010L +#define SS_ETCHEDVERT 0x00000011L +#define SS_ETCHEDFRAME 0x00000012L +#define SS_TYPEMASK 0x0000001FL + +#define SS_NOPREFIX 0x00000080L +#define SS_NOTIFY 0x00000100L +#define SS_CENTERIMAGE 0x00000200L +#define SS_RIGHTJUST 0x00000400L +#define SS_REALSIZEIMAGE 0x00000800L +#define SS_SUNKEN 0x00001000L + +/* Static Control Messages */ +#define STM_SETICON 0x0170 +#define STM_GETICON 0x0171 +#define STM_SETIMAGE 0x0172 +#define STM_GETIMAGE 0x0173 + +/* Scrollbar messages */ +#define SBM_SETPOS 0x00e0 +#define SBM_GETPOS 0x00e1 +#define SBM_SETRANGE 0x00e2 +#define SBM_GETRANGE 0x00e3 +#define SBM_ENABLE_ARROWS 0x00e4 +#define SBM_SETRANGEREDRAW 0x00e6 +#define SBM_SETSCROLLINFO 0x00e9 +#define SBM_GETSCROLLINFO 0x00ea + +/* Scrollbar info */ +typedef struct +{ + UINT cbSize; + UINT fMask; + INT nMin; + INT nMax; + UINT nPage; + INT nPos; + INT nTrackPos; +} SCROLLINFO, *LPSCROLLINFO; + +/* GetScrollInfo() flags */ +#define SIF_RANGE 0x0001 +#define SIF_PAGE 0x0002 +#define SIF_POS 0x0004 +#define SIF_DISABLENOSCROLL 0x0008 +#define SIF_TRACKPOS 0x0010 +#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) + +/* Listbox styles */ +#define LBS_NOTIFY 0x0001 +#define LBS_SORT 0x0002 +#define LBS_NOREDRAW 0x0004 +#define LBS_MULTIPLESEL 0x0008 +#define LBS_OWNERDRAWFIXED 0x0010 +#define LBS_OWNERDRAWVARIABLE 0x0020 +#define LBS_HASSTRINGS 0x0040 +#define LBS_USETABSTOPS 0x0080 +#define LBS_NOINTEGRALHEIGHT 0x0100 +#define LBS_MULTICOLUMN 0x0200 +#define LBS_WANTKEYBOARDINPUT 0x0400 +#define LBS_EXTENDEDSEL 0x0800 +#define LBS_DISABLENOSCROLL 0x1000 +#define LBS_NODATA 0x2000 +#define LBS_NOSEL 0x4000 +#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER) + +/* Listbox messages */ +#define LB_ADDSTRING 0x0180 +#define LB_INSERTSTRING 0x0181 +#define LB_DELETESTRING 0x0182 +#define LB_SELITEMRANGEEX 0x0183 +#define LB_RESETCONTENT 0x0184 +#define LB_SETSEL 0x0185 +#define LB_SETCURSEL 0x0186 +#define LB_GETSEL 0x0187 +#define LB_GETCURSEL 0x0188 +#define LB_GETTEXT 0x0189 +#define LB_GETTEXTLEN 0x018a +#define LB_GETCOUNT 0x018b +#define LB_SELECTSTRING 0x018c +#define LB_DIR 0x018d +#define LB_GETTOPINDEX 0x018e +#define LB_FINDSTRING 0x018f +#define LB_GETSELCOUNT 0x0190 +#define LB_GETSELITEMS 0x0191 +#define LB_SETTABSTOPS 0x0192 +#define LB_GETHORIZONTALEXTENT 0x0193 +#define LB_SETHORIZONTALEXTENT 0x0194 +#define LB_SETCOLUMNWIDTH 0x0195 +#define LB_ADDFILE 0x0196 +#define LB_SETTOPINDEX 0x0197 +#define LB_GETITEMRECT 0x0198 +#define LB_GETITEMDATA 0x0199 +#define LB_SETITEMDATA 0x019a +#define LB_SELITEMRANGE 0x019b +#define LB_SETANCHORINDEX 0x019c +#define LB_GETANCHORINDEX 0x019d +#define LB_SETCARETINDEX 0x019e +#define LB_GETCARETINDEX 0x019f +#define LB_SETITEMHEIGHT 0x01a0 +#define LB_GETITEMHEIGHT 0x01a1 +#define LB_FINDSTRINGEXACT 0x01a2 +#define LB_CARETON 0x01a3 +#define LB_CARETOFF 0x01a4 +#define LB_SETLOCALE 0x01a5 +#define LB_GETLOCALE 0x01a6 +#define LB_SETCOUNT 0x01a7 +#define LB_INITSTORAGE 0x01a8 +#define LB_ITEMFROMPOINT 0x01a9 + +/* Listbox notification codes */ +#define LBN_ERRSPACE (-2) +#define LBN_SELCHANGE 1 +#define LBN_DBLCLK 2 +#define LBN_SELCANCEL 3 +#define LBN_SETFOCUS 4 +#define LBN_KILLFOCUS 5 + +/* Listbox message return values */ +#define LB_OKAY 0 +#define LB_ERR (-1) +#define LB_ERRSPACE (-2) + +#define LB_CTLCODE 0L + +/* Combo box styles */ +#define CBS_SIMPLE 0x0001L +#define CBS_DROPDOWN 0x0002L +#define CBS_DROPDOWNLIST 0x0003L +#define CBS_OWNERDRAWFIXED 0x0010L +#define CBS_OWNERDRAWVARIABLE 0x0020L +#define CBS_AUTOHSCROLL 0x0040L +#define CBS_OEMCONVERT 0x0080L +#define CBS_SORT 0x0100L +#define CBS_HASSTRINGS 0x0200L +#define CBS_NOINTEGRALHEIGHT 0x0400L +#define CBS_DISABLENOSCROLL 0x0800L + +#define CBS_UPPERCASE 0x2000L +#define CBS_LOWERCASE 0x4000L + + +/* Combo box messages */ +#define CB_GETEDITSEL 0x0140 +#define CB_LIMITTEXT 0x0141 +#define CB_SETEDITSEL 0x0142 +#define CB_ADDSTRING 0x0143 +#define CB_DELETESTRING 0x0144 +#define CB_DIR 0x0145 +#define CB_GETCOUNT 0x0146 +#define CB_GETCURSEL 0x0147 +#define CB_GETLBTEXT 0x0148 +#define CB_GETLBTEXTLEN 0x0149 +#define CB_INSERTSTRING 0x014a +#define CB_RESETCONTENT 0x014b +#define CB_FINDSTRING 0x014c +#define CB_SELECTSTRING 0x014d +#define CB_SETCURSEL 0x014e +#define CB_SHOWDROPDOWN 0x014f +#define CB_GETITEMDATA 0x0150 +#define CB_SETITEMDATA 0x0151 +#define CB_GETDROPPEDCONTROLRECT 0x0152 +#define CB_SETITEMHEIGHT 0x0153 +#define CB_GETITEMHEIGHT 0x0154 +#define CB_SETEXTENDEDUI 0x0155 +#define CB_GETEXTENDEDUI 0x0156 +#define CB_GETDROPPEDSTATE 0x0157 +#define CB_FINDSTRINGEXACT 0x0158 +#define CB_SETLOCALE 0x0159 +#define CB_GETLOCALE 0x015a +#define CB_GETTOPINDEX 0x015b +#define CB_SETTOPINDEX 0x015c +#define CB_GETHORIZONTALEXTENT 0x015d +#define CB_SETHORIZONTALEXTENT 0x015e +#define CB_GETDROPPEDWIDTH 0x015f +#define CB_SETDROPPEDWIDTH 0x0160 +#define CB_INITSTORAGE 0x0161 + +/* Combo box notification codes */ +#define CBN_ERRSPACE (-1) +#define CBN_SELCHANGE 1 +#define CBN_DBLCLK 2 +#define CBN_SETFOCUS 3 +#define CBN_KILLFOCUS 4 +#define CBN_EDITCHANGE 5 +#define CBN_EDITUPDATE 6 +#define CBN_DROPDOWN 7 +#define CBN_CLOSEUP 8 +#define CBN_SELENDOK 9 +#define CBN_SELENDCANCEL 10 + +/* Combo box message return values */ +#define CB_OKAY 0 +#define CB_ERR (-1) +#define CB_ERRSPACE (-2) + +#define MB_OK 0x00000000 +#define MB_OKCANCEL 0x00000001 +#define MB_ABORTRETRYIGNORE 0x00000002 +#define MB_YESNOCANCEL 0x00000003 +#define MB_YESNO 0x00000004 +#define MB_RETRYCANCEL 0x00000005 +#define MB_TYPEMASK 0x0000000F + +#define MB_ICONHAND 0x00000010 +#define MB_ICONQUESTION 0x00000020 +#define MB_ICONEXCLAMATION 0x00000030 +#define MB_ICONASTERISK 0x00000040 +#define MB_USERICON 0x00000080 +#define MB_ICONMASK 0x000000F0 + +#define MB_ICONINFORMATION MB_ICONASTERISK +#define MB_ICONSTOP MB_ICONHAND +#define MB_ICONWARNING MB_ICONEXCLAMATION +#define MB_ICONERROR MB_ICONHAND + +#define MB_DEFBUTTON1 0x00000000 +#define MB_DEFBUTTON2 0x00000100 +#define MB_DEFBUTTON3 0x00000200 +#define MB_DEFBUTTON4 0x00000300 +#define MB_DEFMASK 0x00000F00 + +#define MB_APPLMODAL 0x00000000 +#define MB_SYSTEMMODAL 0x00001000 +#define MB_TASKMODAL 0x00002000 +#define MB_MODEMASK 0x00003000 + +#define MB_HELP 0x00004000 +#define MB_NOFOCUS 0x00008000 +#define MB_MISCMASK 0x0000C000 + +#define MB_SETFOREGROUND 0x00010000 +#define MB_DEFAULT_DESKTOP_ONLY 0x00020000 +#define MB_SERVICE_NOTIFICATION 0x00040000 +#define MB_TOPMOST 0x00040000 +#define MB_RIGHT 0x00080000 +#define MB_RTLREADING 0x00100000 + +#define HELPINFO_WINDOW 0x0001 +#define HELPINFO_MENUITEM 0x0002 + +/* Structure pointed to by lParam of WM_HELP */ +typedef struct +{ + UINT cbSize; /* Size in bytes of this struct */ + INT iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */ + INT iCtrlId; /* Control Id or a Menu item Id. */ + HANDLE hItemHandle; /* hWnd of control or hMenu. */ + DWORD dwContextId; /* Context Id associated with this item */ + POINT MousePos; /* Mouse Position in screen co-ordinates */ +} HELPINFO,*LPHELPINFO; + +typedef void CALLBACK (*MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo); + +typedef struct +{ + UINT cbSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCSTR lpszText; + LPCSTR lpszCaption; + DWORD dwStyle; + LPCSTR lpszIcon; + DWORD dwContextHelpId; + MSGBOXCALLBACK lpfnMsgBoxCallback; + DWORD dwLanguageId; +} MSGBOXPARAMSA,*LPMSGBOXPARAMSA; + +typedef struct +{ + UINT cbSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCWSTR lpszText; + LPCWSTR lpszCaption; + DWORD dwStyle; + LPCWSTR lpszIcon; + DWORD dwContextHelpId; + MSGBOXCALLBACK lpfnMsgBoxCallback; + DWORD dwLanguageId; +} MSGBOXPARAMSW,*LPMSGBOXPARAMSW; + +DECL_WINELIB_TYPE_AW(MSGBOXPARAMS) +DECL_WINELIB_TYPE_AW(LPMSGBOXPARAMS) + +typedef struct _numberfmt32a { + UINT NumDigits; + UINT LeadingZero; + UINT Grouping; + LPCSTR lpDecimalSep; + LPCSTR lpThousandSep; + UINT NegativeOrder; +} NUMBERFMTA; + +typedef struct _numberfmt32w { + UINT NumDigits; + UINT LeadingZero; + UINT Grouping; + LPCWSTR lpDecimalSep; + LPCWSTR lpThousandSep; + UINT NegativeOrder; +} NUMBERFMTW; + +typedef struct _currencyfmt32a +{ + UINT NumDigits; + UINT LeadingZero; + UINT Grouping; + LPCSTR lpDecimalSep; + LPCSTR lpThousandSep; + UINT NegativeOrder; + UINT PositiveOrder; + LPCSTR lpCurrencySymbol; +} CURRENCYFMTA; + +typedef struct _currencyfmt32w +{ + UINT NumDigits; + UINT LeadingZero; + UINT Grouping; + LPCWSTR lpDecimalSep; + LPCWSTR lpThousandSep; + UINT NegativeOrder; + UINT PositiveOrder; + LPCWSTR lpCurrencySymbol; +} CURRENCYFMTW; + +#define MONITOR_DEFAULTTONULL 0x00000000 +#define MONITOR_DEFAULTTOPRIMARY 0x00000001 +#define MONITOR_DEFAULTTONEAREST 0x00000002 + +#define MONITORINFOF_PRIMARY 0x00000001 + +typedef struct tagMONITORINFO +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; + + +typedef WIN_BOOL CALLBACK (*MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM); + +/* FIXME: use this instead of LPCVOID for CreateDialogIndirectParam + and DialogBoxIndirectParam */ +typedef struct tagDLGTEMPLATE +{ + DWORD style; + DWORD dwExtendedStyle; + WORD cdit; + short x; + short y; + short cx; + short cy; +} DLGTEMPLATE; + +typedef DLGTEMPLATE *LPDLGTEMPLATEA; +typedef DLGTEMPLATE *LPDLGTEMPLATEW; +#define LPDLGTEMPLATE WINELIB_NAME_AW(LPDLGTEMPLATE) +typedef const DLGTEMPLATE *LPCDLGTEMPLATEA; +typedef const DLGTEMPLATE *LPCDLGTEMPLATEW; +#define LPCDLGTEMPLATE WINELIB_NAME_AW(LPCDLGTEMPLATE) + +typedef struct tagDLGITEMTEMPLATE +{ + DWORD style; + DWORD dwExtendedStyle; + short x; + short y; + short cx; + short cy; + WORD id; +} DLGITEMTEMPLATE; + +typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA; +typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW; +#define LPDLGITEMTEMPLATE WINELIB_NAME_AW(LPDLGITEMTEMPLATE) +typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEA; +typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEW; +#define LPCDLGITEMTEMPLATE WINELIB_NAME_AW(LPCDLGITEMTEMPLATE) + + + /* CBT hook values */ +#define HCBT_MOVESIZE 0 +#define HCBT_MINMAX 1 +#define HCBT_QS 2 +#define HCBT_CREATEWND 3 +#define HCBT_DESTROYWND 4 +#define HCBT_ACTIVATE 5 +#define HCBT_CLICKSKIPPED 6 +#define HCBT_KEYSKIPPED 7 +#define HCBT_SYSCOMMAND 8 +#define HCBT_SETFOCUS 9 + + /* CBT hook structures */ + +typedef struct +{ + CREATESTRUCTA *lpcs; + HWND hwndInsertAfter; +} CBT_CREATEWNDA, *LPCBT_CREATEWNDA; + +typedef struct +{ + CREATESTRUCTW *lpcs; + HWND hwndInsertAfter; +} CBT_CREATEWNDW, *LPCBT_CREATEWNDW; + +DECL_WINELIB_TYPE_AW(CBT_CREATEWND) +DECL_WINELIB_TYPE_AW(LPCBT_CREATEWND) + +typedef struct +{ + WIN_BOOL fMouse; + HWND hWndActive; +} CBTACTIVATESTRUCT, *LPCBTACTIVATESTRUCT; + + +/* modifiers for RegisterHotKey */ +#define MOD_ALT 0x0001 +#define MOD_CONTROL 0x0002 +#define MOD_SHIFT 0x0004 +#define MOD_WIN 0x0008 + +/* ids for RegisterHotKey */ +#define IDHOT_SNAPWINDOW (-1) /* SHIFT-PRINTSCRN */ +#define IDHOT_SNAPDESKTOP (-2) /* PRINTSCRN */ + + /* keybd_event flags */ +#define KEYEVENTF_EXTENDEDKEY 0x0001 +#define KEYEVENTF_KEYUP 0x0002 +#define KEYEVENTF_WINE_FORCEEXTENDED 0x8000 + + /* mouse_event flags */ +#define MOUSEEVENTF_MOVE 0x0001 +#define MOUSEEVENTF_LEFTDOWN 0x0002 +#define MOUSEEVENTF_LEFTUP 0x0004 +#define MOUSEEVENTF_RIGHTDOWN 0x0008 +#define MOUSEEVENTF_RIGHTUP 0x0010 +#define MOUSEEVENTF_MIDDLEDOWN 0x0020 +#define MOUSEEVENTF_MIDDLEUP 0x0040 +#define MOUSEEVENTF_WHEEL 0x0800 +#define MOUSEEVENTF_ABSOLUTE 0x8000 + +/* ExitWindows() flags */ +#define EW_RESTARTWINDOWS 0x0042 +#define EW_REBOOTSYSTEM 0x0043 +#define EW_EXITANDEXECAPP 0x0044 + +/* ExitWindowsEx() flags */ +#define EWX_LOGOFF 0 +#define EWX_SHUTDOWN 1 +#define EWX_REBOOT 2 +#define EWX_FORCE 4 +#define EWX_POWEROFF 8 + +/* SetLastErrorEx types */ +#define SLE_ERROR 0x00000001 +#define SLE_MINORERROR 0x00000002 +#define SLE_WARNING 0x00000003 + +/* Predefined resources */ +#define IDI_APPLICATIONA MAKEINTRESOURCEA(32512) +#define IDI_APPLICATIONW MAKEINTRESOURCEW(32512) +#define IDI_APPLICATION WINELIB_NAME_AW(IDI_APPLICATION) +#define IDI_HANDA MAKEINTRESOURCEA(32513) +#define IDI_HANDW MAKEINTRESOURCEW(32513) +#define IDI_HAND WINELIB_NAME_AW(IDI_HAND) +#define IDI_QUESTIONA MAKEINTRESOURCEA(32514) +#define IDI_QUESTIONW MAKEINTRESOURCEW(32514) +#define IDI_QUESTION WINELIB_NAME_AW(IDI_QUESTION) +#define IDI_EXCLAMATIONA MAKEINTRESOURCEA(32515) +#define IDI_EXCLAMATIONW MAKEINTRESOURCEW(32515) +#define IDI_EXCLAMATION WINELIB_NAME_AW(IDI_EXCLAMATION) +#define IDI_ASTERISKA MAKEINTRESOURCEA(32516) +#define IDI_ASTERISKW MAKEINTRESOURCEW(32516) +#define IDI_ASTERISK WINELIB_NAME_AW(IDI_ASTERISK) + +#define IDC_BUMMERA MAKEINTRESOURCEA(100) +#define IDC_BUMMERW MAKEINTRESOURCEW(100) +#define IDC_BUMMER WINELIB_NAME_AW(IDC_BUMMER) +#define IDC_ARROWA MAKEINTRESOURCEA(32512) +#define IDC_ARROWW MAKEINTRESOURCEW(32512) +#define IDC_ARROW WINELIB_NAME_AW(IDC_ARROW) +#define IDC_IBEAMA MAKEINTRESOURCEA(32513) +#define IDC_IBEAMW MAKEINTRESOURCEW(32513) +#define IDC_IBEAM WINELIB_NAME_AW(IDC_IBEAM) +#define IDC_WAITA MAKEINTRESOURCEA(32514) +#define IDC_WAITW MAKEINTRESOURCEW(32514) +#define IDC_WAIT WINELIB_NAME_AW(IDC_WAIT) +#define IDC_CROSSA MAKEINTRESOURCEA(32515) +#define IDC_CROSSW MAKEINTRESOURCEW(32515) +#define IDC_CROSS WINELIB_NAME_AW(IDC_CROSS) +#define IDC_UPARROWA MAKEINTRESOURCEA(32516) +#define IDC_UPARROWW MAKEINTRESOURCEW(32516) +#define IDC_UPARROW WINELIB_NAME_AW(IDC_UPARROW) +#define IDC_SIZEA MAKEINTRESOURCEA(32640) +#define IDC_SIZEW MAKEINTRESOURCEW(32640) +#define IDC_SIZE WINELIB_NAME_AW(IDC_SIZE) +#define IDC_ICONA MAKEINTRESOURCEA(32641) +#define IDC_ICONW MAKEINTRESOURCEW(32641) +#define IDC_ICON WINELIB_NAME_AW(IDC_ICON) +#define IDC_SIZENWSEA MAKEINTRESOURCEA(32642) +#define IDC_SIZENWSEW MAKEINTRESOURCEW(32642) +#define IDC_SIZENWSE WINELIB_NAME_AW(IDC_SIZENWSE) +#define IDC_SIZENESWA MAKEINTRESOURCEA(32643) +#define IDC_SIZENESWW MAKEINTRESOURCEW(32643) +#define IDC_SIZENESW WINELIB_NAME_AW(IDC_SIZENESW) +#define IDC_SIZEWEA MAKEINTRESOURCEA(32644) +#define IDC_SIZEWEW MAKEINTRESOURCEW(32644) +#define IDC_SIZEWE WINELIB_NAME_AW(IDC_SIZEWE) +#define IDC_SIZENSA MAKEINTRESOURCEA(32645) +#define IDC_SIZENSW MAKEINTRESOURCEW(32645) +#define IDC_SIZENS WINELIB_NAME_AW(IDC_SIZENS) +#define IDC_SIZEALLA MAKEINTRESOURCEA(32646) +#define IDC_SIZEALLW MAKEINTRESOURCEW(32646) +#define IDC_SIZEALL WINELIB_NAME_AW(IDC_SIZEALL) +#define IDC_NOA MAKEINTRESOURCEA(32648) +#define IDC_NOW MAKEINTRESOURCEW(32648) +#define IDC_NO WINELIB_NAME_AW(IDC_NO) +#define IDC_APPSTARTINGA MAKEINTRESOURCEA(32650) +#define IDC_APPSTARTINGW MAKEINTRESOURCEW(32650) +#define IDC_APPSTARTING WINELIB_NAME_AW(IDC_APPSTARTING) +#define IDC_HELPA MAKEINTRESOURCEA(32651) +#define IDC_HELPW MAKEINTRESOURCEW(32651) +#define IDC_HELP WINELIB_NAME_AW(IDC_HELP) + +#define MNC_IGNORE 0 +#define MNC_CLOSE 1 +#define MNC_EXECUTE 2 +#define MNC_SELECT 3 + +/* SystemParametersInfo */ +/* defines below are for all win versions */ +#define SPI_GETBEEP 1 +#define SPI_SETBEEP 2 +#define SPI_GETMOUSE 3 +#define SPI_SETMOUSE 4 +#define SPI_GETBORDER 5 +#define SPI_SETBORDER 6 +#define SPI_GETKEYBOARDSPEED 10 +#define SPI_SETKEYBOARDSPEED 11 +#define SPI_LANGDRIVER 12 +#define SPI_ICONHORIZONTALSPACING 13 +#define SPI_GETSCREENSAVETIMEOUT 14 +#define SPI_SETSCREENSAVETIMEOUT 15 +#define SPI_GETSCREENSAVEACTIVE 16 +#define SPI_SETSCREENSAVEACTIVE 17 +#define SPI_GETGRIDGRANULARITY 18 +#define SPI_SETGRIDGRANULARITY 19 +#define SPI_SETDESKWALLPAPER 20 +#define SPI_SETDESKPATTERN 21 +#define SPI_GETKEYBOARDDELAY 22 +#define SPI_SETKEYBOARDDELAY 23 +#define SPI_ICONVERTICALSPACING 24 +#define SPI_GETICONTITLEWRAP 25 +#define SPI_SETICONTITLEWRAP 26 +#define SPI_GETMENUDROPALIGNMENT 27 +#define SPI_SETMENUDROPALIGNMENT 28 +#define SPI_SETDOUBLECLKWIDTH 29 +#define SPI_SETDOUBLECLKHEIGHT 30 +#define SPI_GETICONTITLELOGFONT 31 +#define SPI_SETDOUBLECLICKTIME 32 +#define SPI_SETMOUSEBUTTONSWAP 33 +#define SPI_SETICONTITLELOGFONT 34 +#define SPI_GETFASTTASKSWITCH 35 +#define SPI_SETFASTTASKSWITCH 36 +#define SPI_SETDRAGFULLWINDOWS 37 +#define SPI_GETDRAGFULLWINDOWS 38 + +#define SPI_GETFILTERKEYS 50 +#define SPI_SETFILTERKEYS 51 +#define SPI_GETTOGGLEKEYS 52 +#define SPI_SETTOGGLEKEYS 53 +#define SPI_GETMOUSEKEYS 54 +#define SPI_SETMOUSEKEYS 55 +#define SPI_GETSHOWSOUNDS 56 +#define SPI_SETSHOWSOUNDS 57 +#define SPI_GETSTICKYKEYS 58 +#define SPI_SETSTICKYKEYS 59 +#define SPI_GETACCESSTIMEOUT 60 +#define SPI_SETACCESSTIMEOUT 61 + +#define SPI_GETSOUNDSENTRY 64 +#define SPI_SETSOUNDSENTRY 65 + +/* defines below are for all win versions WINVER >= 0x0400 */ +#define SPI_SETDRAGFULLWINDOWS 37 +#define SPI_GETDRAGFULLWINDOWS 38 +#define SPI_GETNONCLIENTMETRICS 41 +#define SPI_SETNONCLIENTMETRICS 42 +#define SPI_GETMINIMIZEDMETRICS 43 +#define SPI_SETMINIMIZEDMETRICS 44 +#define SPI_GETICONMETRICS 45 +#define SPI_SETICONMETRICS 46 +#define SPI_SETWORKAREA 47 +#define SPI_GETWORKAREA 48 +#define SPI_SETPENWINDOWS 49 + +#define SPI_GETSERIALKEYS 62 +#define SPI_SETSERIALKEYS 63 +#define SPI_GETHIGHCONTRAST 66 +#define SPI_SETHIGHCONTRAST 67 +#define SPI_GETKEYBOARDPREF 68 +#define SPI_SETKEYBOARDPREF 69 +#define SPI_GETSCREENREADER 70 +#define SPI_SETSCREENREADER 71 +#define SPI_GETANIMATION 72 +#define SPI_SETANIMATION 73 +#define SPI_GETFONTSMOOTHING 74 +#define SPI_SETFONTSMOOTHING 75 +#define SPI_SETDRAGWIDTH 76 +#define SPI_SETDRAGHEIGHT 77 +#define SPI_SETHANDHELD 78 +#define SPI_GETLOWPOWERTIMEOUT 79 +#define SPI_GETPOWEROFFTIMEOUT 80 +#define SPI_SETLOWPOWERTIMEOUT 81 +#define SPI_SETPOWEROFFTIMEOUT 82 +#define SPI_GETLOWPOWERACTIVE 83 +#define SPI_GETPOWEROFFACTIVE 84 +#define SPI_SETLOWPOWERACTIVE 85 +#define SPI_SETPOWEROFFACTIVE 86 +#define SPI_SETCURSORS 87 +#define SPI_SETICONS 88 +#define SPI_GETDEFAULTINPUTLANG 89 +#define SPI_SETDEFAULTINPUTLANG 90 +#define SPI_SETLANGTOGGLE 91 +#define SPI_GETWINDOWSEXTENSION 92 +#define SPI_SETMOUSETRAILS 93 +#define SPI_GETMOUSETRAILS 94 +#define SPI_SETSCREENSAVERRUNNING 97 +#define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING + +/* defines below are for all win versions (_WIN32_WINNT >= 0x0400) || + * (_WIN32_WINDOWS > 0x0400) */ +#define SPI_GETMOUSEHOVERWIDTH 98 +#define SPI_SETMOUSEHOVERWIDTH 99 +#define SPI_GETMOUSEHOVERHEIGHT 100 +#define SPI_SETMOUSEHOVERHEIGHT 101 +#define SPI_GETMOUSEHOVERTIME 102 +#define SPI_SETMOUSEHOVERTIME 103 +#define SPI_GETWHEELSCROLLLINES 104 +#define SPI_SETWHEELSCROLLLINES 105 + +#define SPI_GETSHOWIMEUI 110 +#define SPI_SETSHOWIMEUI 111 + +/* defines below are for all win versions WINVER >= 0x0500 */ +#define SPI_GETMOUSESPEED 112 +#define SPI_SETMOUSESPEED 113 +#define SPI_GETSCREENSAVERRUNNING 114 + +#define SPI_GETACTIVEWINDOWTRACKING 0x1000 +#define SPI_SETACTIVEWINDOWTRACKING 0x1001 +#define SPI_GETMENUANIMATION 0x1002 +#define SPI_SETMENUANIMATION 0x1003 +#define SPI_GETCOMBOBOXANIMATION 0x1004 +#define SPI_SETCOMBOBOXANIMATION 0x1005 +#define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006 +#define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007 +#define SPI_GETGRADIENTCAPTIONS 0x1008 +#define SPI_SETGRADIENTCAPTIONS 0x1009 +#define SPI_GETMENUUNDERLINES 0x100A +#define SPI_SETMENUUNDERLINES 0x100B +#define SPI_GETACTIVEWNDTRKZORDER 0x100C +#define SPI_SETACTIVEWNDTRKZORDER 0x100D +#define SPI_GETHOTTRACKING 0x100E +#define SPI_SETHOTTRACKING 0x100F +#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 +#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 +#define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002 +#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003 +#define SPI_GETFOREGROUNDFLASHCOUNT 0x2004 +#define SPI_SETFOREGROUNDFLASHCOUNT 0x2005 + +/* SystemParametersInfo flags */ + +#define SPIF_UPDATEINIFILE 1 +#define SPIF_SENDWININICHANGE 2 +#define SPIF_SENDCHANGE SPIF_SENDWININICHANGE + + + + +/* Window Styles */ +#define WS_OVERLAPPED 0x00000000L +#define WS_POPUP 0x80000000L +#define WS_CHILD 0x40000000L +#define WS_MINIMIZE 0x20000000L +#define WS_VISIBLE 0x10000000L +#define WS_DISABLED 0x08000000L +#define WS_CLIPSIBLINGS 0x04000000L +#define WS_CLIPCHILDREN 0x02000000L +#define WS_MAXIMIZE 0x01000000L +#define WS_CAPTION 0x00C00000L +#define WS_BORDER 0x00800000L +#define WS_DLGFRAME 0x00400000L +#define WS_VSCROLL 0x00200000L +#define WS_HSCROLL 0x00100000L +#define WS_SYSMENU 0x00080000L +#define WS_THICKFRAME 0x00040000L +#define WS_GROUP 0x00020000L +#define WS_TABSTOP 0x00010000L +#define WS_MINIMIZEBOX 0x00020000L +#define WS_MAXIMIZEBOX 0x00010000L +#define WS_TILED WS_OVERLAPPED +#define WS_ICONIC WS_MINIMIZE +#define WS_SIZEBOX WS_THICKFRAME +#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME| WS_MINIMIZEBOX | WS_MAXIMIZEBOX) +#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) +#define WS_CHILDWINDOW (WS_CHILD) +#define WS_TILEDWINDOW (WS_OVERLAPPEDWINDOW) + +/* Window extended styles */ +#define WS_EX_DLGMODALFRAME 0x00000001L +#define WS_EX_DRAGDETECT 0x00000002L +#define WS_EX_NOPARENTNOTIFY 0x00000004L +#define WS_EX_TOPMOST 0x00000008L +#define WS_EX_ACCEPTFILES 0x00000010L +#define WS_EX_TRANSPARENT 0x00000020L + +/* New Win95/WinNT4 styles */ +#define WS_EX_MDICHILD 0x00000040L +#define WS_EX_TOOLWINDOW 0x00000080L +#define WS_EX_WINDOWEDGE 0x00000100L +#define WS_EX_CLIENTEDGE 0x00000200L +#define WS_EX_CONTEXTHELP 0x00000400L +#define WS_EX_RIGHT 0x00001000L +#define WS_EX_LEFT 0x00000000L +#define WS_EX_RTLREADING 0x00002000L +#define WS_EX_LTRREADING 0x00000000L +#define WS_EX_LEFTSCROLLBAR 0x00004000L +#define WS_EX_RIGHTSCROLLBAR 0x00000000L +#define WS_EX_CONTROLPARENT 0x00010000L +#define WS_EX_STATICEDGE 0x00020000L +#define WS_EX_APPWINDOW 0x00040000L + +#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE) +#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST) + +/* WINE internal... */ +#define WS_EX_TRAYWINDOW 0x80000000L + +/* Window scrolling */ +#define SW_SCROLLCHILDREN 0x0001 +#define SW_INVALIDATE 0x0002 +#define SW_ERASE 0x0004 + +/* CreateWindow() coordinates */ +#define CW_USEDEFAULT ((INT)0x80000000) + +/* ChildWindowFromPointEx Flags */ +#define CWP_ALL 0x0000 +#define CWP_SKIPINVISIBLE 0x0001 +#define CWP_SKIPDISABLED 0x0002 +#define CWP_SKIPTRANSPARENT 0x0004 + + /* PeekMessage() options */ +#define PM_NOREMOVE 0x0000 +#define PM_REMOVE 0x0001 +#define PM_NOYIELD 0x0002 + +/* WM_SHOWWINDOW wParam codes */ +#define SW_PARENTCLOSING 1 +#define SW_OTHERMAXIMIZED 2 +#define SW_PARENTOPENING 3 +#define SW_OTHERRESTORED 4 + + /* ShowWindow() codes */ +#define SW_HIDE 0 +#define SW_SHOWNORMAL 1 +#define SW_NORMAL 1 +#define SW_SHOWMINIMIZED 2 +#define SW_SHOWMAXIMIZED 3 +#define SW_MAXIMIZE 3 +#define SW_SHOWNOACTIVATE 4 +#define SW_SHOW 5 +#define SW_MINIMIZE 6 +#define SW_SHOWMINNOACTIVE 7 +#define SW_SHOWNA 8 +#define SW_RESTORE 9 +#define SW_SHOWDEFAULT 10 +#define SW_MAX 10 +#define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */ + + /* WM_SIZE message wParam values */ +#define SIZE_RESTORED 0 +#define SIZE_MINIMIZED 1 +#define SIZE_MAXIMIZED 2 +#define SIZE_MAXSHOW 3 +#define SIZE_MAXHIDE 4 +#define SIZENORMAL SIZE_RESTORED +#define SIZEICONIC SIZE_MINIMIZED +#define SIZEFULLSCREEN SIZE_MAXIMIZED +#define SIZEZOOMSHOW SIZE_MAXSHOW +#define SIZEZOOMHIDE SIZE_MAXHIDE + +/* SetWindowPos() and WINDOWPOS flags */ +#define SWP_NOSIZE 0x0001 +#define SWP_NOMOVE 0x0002 +#define SWP_NOZORDER 0x0004 +#define SWP_NOREDRAW 0x0008 +#define SWP_NOACTIVATE 0x0010 +#define SWP_FRAMECHANGED 0x0020 /* The frame changed: send WM_NCCALCSIZE */ +#define SWP_SHOWWINDOW 0x0040 +#define SWP_HIDEWINDOW 0x0080 +#define SWP_NOCOPYBITS 0x0100 +#define SWP_NOOWNERZORDER 0x0200 /* Don't do owner Z ordering */ + +#define SWP_DRAWFRAME SWP_FRAMECHANGED +#define SWP_NOREPOSITION SWP_NOOWNERZORDER + +#define SWP_NOSENDCHANGING 0x0400 +#define SWP_DEFERERASE 0x2000 +#define SWP_ASYNCWINDOWPOS 0x4000 + +#define HWND_DESKTOP ((HWND)0) +#define HWND_BROADCAST ((HWND)0xffff) + +/* SetWindowPos() hwndInsertAfter field values */ +#define HWND_TOP ((HWND)0) +#define HWND_BOTTOM ((HWND)1) +#define HWND_TOPMOST ((HWND)-1) +#define HWND_NOTOPMOST ((HWND)-2) + +#define MF_INSERT 0x0000 +#define MF_CHANGE 0x0080 +#define MF_APPEND 0x0100 +#define MF_DELETE 0x0200 +#define MF_REMOVE 0x1000 +#define MF_END 0x0080 + +#define MF_ENABLED 0x0000 +#define MF_GRAYED 0x0001 +#define MF_DISABLED 0x0002 +#define MF_STRING 0x0000 +#define MF_BITMAP 0x0004 +#define MF_UNCHECKED 0x0000 +#define MF_CHECKED 0x0008 +#define MF_POPUP 0x0010 +#define MF_MENUBARBREAK 0x0020 +#define MF_MENUBREAK 0x0040 +#define MF_UNHILITE 0x0000 +#define MF_HILITE 0x0080 +#define MF_OWNERDRAW 0x0100 +#define MF_USECHECKBITMAPS 0x0200 +#define MF_BYCOMMAND 0x0000 +#define MF_BYPOSITION 0x0400 +#define MF_SEPARATOR 0x0800 +#define MF_DEFAULT 0x1000 +#define MF_SYSMENU 0x2000 +#define MF_HELP 0x4000 +#define MF_RIGHTJUSTIFY 0x4000 +#define MF_MOUSESELECT 0x8000 + +/* Flags for extended menu item types. */ +#define MFT_STRING MF_STRING +#define MFT_BITMAP MF_BITMAP +#define MFT_MENUBARBREAK MF_MENUBARBREAK +#define MFT_MENUBREAK MF_MENUBREAK +#define MFT_OWNERDRAW MF_OWNERDRAW +#define MFT_RADIOCHECK 0x00000200L +#define MFT_SEPARATOR MF_SEPARATOR +#define MFT_RIGHTORDER 0x00002000L +#define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY + +/* Flags for extended menu item states. */ +#define MFS_GRAYED 0x00000003L +#define MFS_DISABLED MFS_GRAYED +#define MFS_CHECKED MF_CHECKED +#define MFS_HILITE MF_HILITE +#define MFS_ENABLED MF_ENABLED +#define MFS_UNCHECKED MF_UNCHECKED +#define MFS_UNHILITE MF_UNHILITE +#define MFS_DEFAULT MF_DEFAULT +#define MFS_MASK 0x0000108BL +#define MFS_HOTTRACKDRAWN 0x10000000L +#define MFS_CACHEDBMP 0x20000000L +#define MFS_BOTTOMGAPDROP 0x40000000L +#define MFS_TOPGAPDROP 0x80000000L +#define MFS_GAPDROP 0xC0000000L + +/* for GetMenuDefaultItem */ +#define GMDI_USEDISABLED 0x0001L +#define GMDI_GOINTOPOPUPS 0x0002L + +#define DT_TOP 0 +#define DT_LEFT 0 +#define DT_CENTER 1 +#define DT_RIGHT 2 +#define DT_VCENTER 4 +#define DT_BOTTOM 8 +#define DT_WORDBREAK 16 +#define DT_SINGLELINE 32 +#define DT_EXPANDTABS 64 +#define DT_TABSTOP 128 +#define DT_NOCLIP 256 +#define DT_EXTERNALLEADING 512 +#define DT_CALCRECT 1024 +#define DT_NOPREFIX 2048 +#define DT_INTERNAL 4096 + +/* DrawCaption()/DrawCaptionTemp() flags */ +#define DC_ACTIVE 0x0001 +#define DC_SMALLCAP 0x0002 +#define DC_ICON 0x0004 +#define DC_TEXT 0x0008 +#define DC_INBUTTON 0x0010 + +/* DrawEdge() flags */ +#define BDR_RAISEDOUTER 0x0001 +#define BDR_SUNKENOUTER 0x0002 +#define BDR_RAISEDINNER 0x0004 +#define BDR_SUNKENINNER 0x0008 + +#define BDR_OUTER 0x0003 +#define BDR_INNER 0x000c +#define BDR_RAISED 0x0005 +#define BDR_SUNKEN 0x000a + +#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) +#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) +#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER) +#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER) + +/* border flags */ +#define BF_LEFT 0x0001 +#define BF_TOP 0x0002 +#define BF_RIGHT 0x0004 +#define BF_BOTTOM 0x0008 +#define BF_DIAGONAL 0x0010 +#define BF_MIDDLE 0x0800 /* Fill in the middle */ +#define BF_SOFT 0x1000 /* For softer buttons */ +#define BF_ADJUST 0x2000 /* Calculate the space left over */ +#define BF_FLAT 0x4000 /* For flat rather than 3D borders */ +#define BF_MONO 0x8000 /* For monochrome borders */ +#define BF_TOPLEFT (BF_TOP | BF_LEFT) +#define BF_TOPRIGHT (BF_TOP | BF_RIGHT) +#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT) +#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT) +#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM) +#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT) +#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT) +#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT) +#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT) + +/* DrawFrameControl() uType's */ + +#define DFC_CAPTION 1 +#define DFC_MENU 2 +#define DFC_SCROLL 3 +#define DFC_BUTTON 4 + +/* uState's */ + +#define DFCS_CAPTIONCLOSE 0x0000 +#define DFCS_CAPTIONMIN 0x0001 +#define DFCS_CAPTIONMAX 0x0002 +#define DFCS_CAPTIONRESTORE 0x0003 +#define DFCS_CAPTIONHELP 0x0004 /* Windows 95 only */ + +#define DFCS_MENUARROW 0x0000 +#define DFCS_MENUCHECK 0x0001 +#define DFCS_MENUBULLET 0x0002 +#define DFCS_MENUARROWRIGHT 0x0004 + +#define DFCS_SCROLLUP 0x0000 +#define DFCS_SCROLLDOWN 0x0001 +#define DFCS_SCROLLLEFT 0x0002 +#define DFCS_SCROLLRIGHT 0x0003 +#define DFCS_SCROLLCOMBOBOX 0x0005 +#define DFCS_SCROLLSIZEGRIP 0x0008 +#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010 + +#define DFCS_BUTTONCHECK 0x0000 +#define DFCS_BUTTONRADIOIMAGE 0x0001 +#define DFCS_BUTTONRADIOMASK 0x0002 /* to draw nonsquare button */ +#define DFCS_BUTTONRADIO 0x0004 +#define DFCS_BUTTON3STATE 0x0008 +#define DFCS_BUTTONPUSH 0x0010 + +/* additional state of the control */ + +#define DFCS_INACTIVE 0x0100 +#define DFCS_PUSHED 0x0200 +#define DFCS_CHECKED 0x0400 +#define DFCS_ADJUSTRECT 0x2000 /* exclude surrounding edge */ +#define DFCS_FLAT 0x4000 +#define DFCS_MONO 0x8000 + +/* Image type */ +#define DST_COMPLEX 0x0000 +#define DST_TEXT 0x0001 +#define DST_PREFIXTEXT 0x0002 +#define DST_ICON 0x0003 +#define DST_BITMAP 0x0004 + +/* State type */ +#define DSS_NORMAL 0x0000 +#define DSS_UNION 0x0010 /* Gray string appearance */ +#define DSS_DISABLED 0x0020 +#define DSS_DEFAULT 0x0040 /* Make it bold */ +#define DSS_MONO 0x0080 +#define DSS_RIGHT 0x8000 + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + HWND hwndItem; + HDC hDC; + RECT rcItem WINE_PACKED; + DWORD itemData WINE_PACKED; +} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT; + + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemWidth; + UINT itemHeight; + DWORD itemData; +} MEASUREITEMSTRUCT, *PMEASUREITEMSTRUCT, *LPMEASUREITEMSTRUCT; + + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + HWND hwndItem; + DWORD itemData; +} DELETEITEMSTRUCT, *LPDELETEITEMSTRUCT; + + +typedef struct +{ + UINT CtlType; + UINT CtlID; + HWND hwndItem; + UINT itemID1; + DWORD itemData1; + UINT itemID2; + DWORD itemData2; + DWORD dwLocaleId; +} COMPAREITEMSTRUCT, *PCOMPAREITEMSTRUCT, *LPCOMPAREITEMSTRUCT; + + +/* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */ +#define KF_EXTENDED 0x0100 +#define KF_DLGMODE 0x0800 +#define KF_MENUMODE 0x1000 +#define KF_ALTDOWN 0x2000 +#define KF_REPEAT 0x4000 +#define KF_UP 0x8000 + +/* Virtual key codes */ +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_CANCEL 0x03 +#define VK_MBUTTON 0x04 +/* 0x05-0x07 Undefined */ +#define VK_BACK 0x08 +#define VK_TAB 0x09 +/* 0x0A-0x0B Undefined */ +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D +/* 0x0E-0x0F Undefined */ +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 +/* 0x15-0x19 Reserved for Kanji systems */ +/* 0x1A Undefined */ +#define VK_ESCAPE 0x1B +/* 0x1C-0x1F Reserved for Kanji systems */ +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A /* OEM specific in Windows 3.1 SDK */ +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F +#define VK_0 0x30 +#define VK_1 0x31 +#define VK_2 0x32 +#define VK_3 0x33 +#define VK_4 0x34 +#define VK_5 0x35 +#define VK_6 0x36 +#define VK_7 0x37 +#define VK_8 0x38 +#define VK_9 0x39 +/* 0x3A-0x40 Undefined */ +#define VK_A 0x41 +#define VK_B 0x42 +#define VK_C 0x43 +#define VK_D 0x44 +#define VK_E 0x45 +#define VK_F 0x46 +#define VK_G 0x47 +#define VK_H 0x48 +#define VK_I 0x49 +#define VK_J 0x4A +#define VK_K 0x4B +#define VK_L 0x4C +#define VK_M 0x4D +#define VK_N 0x4E +#define VK_O 0x4F +#define VK_P 0x50 +#define VK_Q 0x51 +#define VK_R 0x52 +#define VK_S 0x53 +#define VK_T 0x54 +#define VK_U 0x55 +#define VK_V 0x56 +#define VK_W 0x57 +#define VK_X 0x58 +#define VK_Y 0x59 +#define VK_Z 0x5A + +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D +/* 0x5E-0x5F Unassigned */ +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 +/* 0x88-0x8F Unassigned */ +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 +/* 0x92-0x9F Unassigned */ +/* + * differencing between right and left shift/control/alt key. + * Used only by GetAsyncKeyState() and GetKeyState(). + */ +#define VK_LSHIFT 0xA0 +#define VK_RSHIFT 0xA1 +#define VK_LCONTROL 0xA2 +#define VK_RCONTROL 0xA3 +#define VK_LMENU 0xA4 +#define VK_RMENU 0xA5 +/* 0xA6-0xB9 Unassigned */ +#define VK_OEM_1 0xBA +#define VK_OEM_PLUS 0xBB +#define VK_OEM_COMMA 0xBC +#define VK_OEM_MINUS 0xBD +#define VK_OEM_PERIOD 0xBE +#define VK_OEM_2 0xBF +#define VK_OEM_3 0xC0 +/* 0xC1-0xDA Unassigned */ +#define VK_OEM_4 0xDB +#define VK_OEM_5 0xDC +#define VK_OEM_6 0xDD +#define VK_OEM_7 0xDE +/* 0xDF-0xE4 OEM specific */ + +#define VK_PROCESSKEY 0xE5 + +/* 0xE6 OEM specific */ +/* 0xE7-0xE8 Unassigned */ +/* 0xE9-0xF5 OEM specific */ + +#define VK_ATTN 0xF6 +#define VK_CRSEL 0xF7 +#define VK_EXSEL 0xF8 +#define VK_EREOF 0xF9 +#define VK_PLAY 0xFA +#define VK_ZOOM 0xFB +#define VK_NONAME 0xFC +#define VK_PA1 0xFD +#define VK_OEM_CLEAR 0xFE + + /* Key status flags for mouse events */ +#define MK_LBUTTON 0x0001 +#define MK_RBUTTON 0x0002 +#define MK_SHIFT 0x0004 +#define MK_CONTROL 0x0008 +#define MK_MBUTTON 0x0010 + + /* Queue status flags */ +#define QS_KEY 0x0001 +#define QS_MOUSEMOVE 0x0002 +#define QS_MOUSEBUTTON 0x0004 +#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON) +#define QS_POSTMESSAGE 0x0008 +#define QS_TIMER 0x0010 +#define QS_PAINT 0x0020 +#define QS_SENDMESSAGE 0x0040 +#define QS_HOTKEY 0x0080 +#define QS_INPUT (QS_MOUSE | QS_KEY) +#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY) +#define QS_ALLINPUT (QS_ALLEVENTS | QS_SENDMESSAGE) + +#define DDL_READWRITE 0x0000 +#define DDL_READONLY 0x0001 +#define DDL_HIDDEN 0x0002 +#define DDL_SYSTEM 0x0004 +#define DDL_DIRECTORY 0x0010 +#define DDL_ARCHIVE 0x0020 + +#define DDL_POSTMSGS 0x2000 +#define DDL_DRIVES 0x4000 +#define DDL_EXCLUSIVE 0x8000 + + /* Shell hook values */ +#define HSHELL_WINDOWCREATED 1 +#define HSHELL_WINDOWDESTROYED 2 +#define HSHELL_ACTIVATESHELLWINDOW 3 + +/* Predefined Clipboard Formats */ +#define CF_TEXT 1 +#define CF_BITMAP 2 +#define CF_METAFILEPICT 3 +#define CF_SYLK 4 +#define CF_DIF 5 +#define CF_TIFF 6 +#define CF_OEMTEXT 7 +#define CF_DIB 8 +#define CF_PALETTE 9 +#define CF_PENDATA 10 +#define CF_RIFF 11 +#define CF_WAVE 12 +#define CF_ENHMETAFILE 14 +#define CF_HDROP 15 +#define CF_LOCALE 16 +#define CF_MAX 17 + +#define CF_OWNERDISPLAY 0x0080 +#define CF_DSPTEXT 0x0081 +#define CF_DSPBITMAP 0x0082 +#define CF_DSPMETAFILEPICT 0x0083 + +/* "Private" formats don't get GlobalFree()'d */ +#define CF_PRIVATEFIRST 0x0200 +#define CF_PRIVATELAST 0x02FF + +/* "GDIOBJ" formats do get DeleteObject()'d */ +#define CF_GDIOBJFIRST 0x0300 +#define CF_GDIOBJLAST 0x03FF + + +/* DragObject stuff */ + +typedef struct +{ + HWND16 hWnd; + HANDLE16 hScope; + WORD wFlags; + HANDLE16 hList; + HANDLE16 hOfStruct; + POINT16 pt WINE_PACKED; + LONG l WINE_PACKED; +} DRAGINFO, *LPDRAGINFO; + +#define DRAGOBJ_PROGRAM 0x0001 +#define DRAGOBJ_DATA 0x0002 +#define DRAGOBJ_DIRECTORY 0x0004 +#define DRAGOBJ_MULTIPLE 0x0008 +#define DRAGOBJ_EXTERNAL 0x8000 + +#define DRAG_PRINT 0x544E5250 +#define DRAG_FILE 0x454C4946 + +/* types of LoadImage */ +#define IMAGE_BITMAP 0 +#define IMAGE_ICON 1 +#define IMAGE_CURSOR 2 +#define IMAGE_ENHMETAFILE 3 + +/* loadflags to LoadImage */ +#define LR_DEFAULTCOLOR 0x0000 +#define LR_MONOCHROME 0x0001 +#define LR_COLOR 0x0002 +#define LR_COPYRETURNORG 0x0004 +#define LR_COPYDELETEORG 0x0008 +#define LR_LOADFROMFILE 0x0010 +#define LR_LOADTRANSPARENT 0x0020 +#define LR_DEFAULTSIZE 0x0040 +#define LR_VGA_COLOR 0x0080 +#define LR_LOADMAP3DCOLORS 0x1000 +#define LR_CREATEDIBSECTION 0x2000 +#define LR_COPYFROMRESOURCE 0x4000 +#define LR_SHARED 0x8000 + +/* Flags for DrawIconEx. */ +#define DI_MASK 1 +#define DI_IMAGE 2 +#define DI_NORMAL (DI_MASK | DI_IMAGE) +#define DI_COMPAT 4 +#define DI_DEFAULTSIZE 8 + + /* misc messages */ +#define WM_CPL_LAUNCH (WM_USER + 1000) +#define WM_CPL_LAUNCHED (WM_USER + 1001) + +/* WM_NOTIFYFORMAT commands and return values */ +#define NFR_ANSI 1 +#define NFR_UNICODE 2 +#define NF_QUERY 3 +#define NF_REQUERY 4 + +#include "poppack.h" +#define EnumTaskWindows(handle,proc,lparam) \ + EnumThreadWindows(handle,proc,lparam) +#define OemToAnsiA OemToCharA +#define OemToAnsiW OemToCharW +#define OemToAnsi WINELIB_NAME_AW(OemToAnsi) +#define OemToAnsiBuffA OemToCharBuffA +#define OemToAnsiBuffW OemToCharBuffW +#define OemToAnsiBuff WINELIB_NAME_AW(OemToAnsiBuff) +#define AnsiToOemA CharToOemA +#define AnsiToOemW CharToOemW +#define AnsiToOem WINELIB_NAME_AW(AnsiToOem) +#define AnsiToOemBuffA CharToOemBuffA +#define AnsiToOemBuffW CharToOemBuffW +#define AnsiToOemBuff WINELIB_NAME_AW(AnsiToOemBuff) +/* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */ +WORD WINAPI SYSTEM_KillSystemTimer( WORD ); + +/* Extra functions that don't exist in the Windows API */ + +HPEN WINAPI GetSysColorPen(INT); +INT WINAPI LoadMessageA(HMODULE,UINT,WORD,LPSTR,INT); +INT WINAPI LoadMessageW(HMODULE,UINT,WORD,LPWSTR,INT); + +VOID WINAPI ScreenSwitchEnable16(WORD); + +#define WC_DIALOG (LPSTR)((DWORD)((WORD)( 0x8002))) + +#ifdef __cplusplus +} +#endif + +#endif /* _WINUSER_ */ diff --git a/linphone/win32acm/wineacm.h b/linphone/win32acm/wineacm.h new file mode 100644 index 000000000..959cb3d76 --- /dev/null +++ b/linphone/win32acm/wineacm.h @@ -0,0 +1,72 @@ +#ifndef WINEACM_H +#define WINEACM_H +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ + +/*********************************************************************** + * Wine specific - Win32 + */ + + +#include "wine/msacmdrv.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + + +typedef struct _WINE_ACMDRIVERID *PWINE_ACMDRIVERID; +typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER; + +typedef struct _WINE_ACMOBJ +{ + PWINE_ACMDRIVERID pACMDriverID; +} WINE_ACMOBJ, *PWINE_ACMOBJ; + +typedef struct _WINE_ACMDRIVER +{ + WINE_ACMOBJ obj; + HDRVR hDrvr; + DRIVERPROC pfnDriverProc; + PWINE_ACMDRIVER pNextACMDriver; + int iUsage; +} WINE_ACMDRIVER; + +typedef struct _WINE_ACMSTREAM +{ + WINE_ACMOBJ obj; + PWINE_ACMDRIVER pDrv; + ACMDRVSTREAMINSTANCE drvInst; + HACMDRIVER hAcmDriver; +} WINE_ACMSTREAM, *PWINE_ACMSTREAM; + +typedef struct _WINE_ACMDRIVERID +{ + LPSTR pszFileName; + WORD wFormatTag; + HINSTANCE hInstModule; /* NULL if global */ + DWORD dwProcessID; /* ID of process which installed a local driver */ + WIN_BOOL bEnabled; + PWINE_ACMDRIVER pACMDriverList; + PWINE_ACMDRIVERID pNextACMDriverID; + PWINE_ACMDRIVERID pPrevACMDriverID; +} WINE_ACMDRIVERID; + +/* From internal.c */ +extern HANDLE MSACM_hHeap; +extern PWINE_ACMDRIVERID MSACM_pFirstACMDriverID; +extern PWINE_ACMDRIVERID MSACM_pLastACMDriverID; + +PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName, + WORD wFormatTag, + HINSTANCE hinstModule); +PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p); +void MSACM_UnregisterAllDrivers(void); +PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID); +PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver); +PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* WINEACM_H */ diff --git a/linphone/win32acm/wrapper.S b/linphone/win32acm/wrapper.S new file mode 100644 index 000000000..fe2d85619 --- /dev/null +++ b/linphone/win32acm/wrapper.S @@ -0,0 +1,83 @@ +.section .data +.globl caller_return +caller_return: + .long 0 +.globl report_entry +report_entry: + .long null_call +.globl report_ret +report_ret: + .long null_call +.global wrapper_target +wrapper_target: + .long null_call + +.section .text +.globl null_call + .type null_call, @function + .balign 16,0x90 +null_call: + ret +.globl wrapper + .type wrapper, @function + .balign 16,0x90 +wrapper: + pusha # store registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) + pushf # store flags + + push %ebp # set up a stack frame + movl %esp, %ebp + + leal 4(%ebp), %eax # push flags addr + push %eax + leal 8(%ebp), %eax # push registers addr + push %eax + + leal 40(%ebp), %edx + movl (%ebp), %eax + subl %edx, %eax + push %eax + push %edx + + call *report_entry # report entry + + test %eax, %eax + jnz .Ldone + + leave # restore %esp, %ebp + popf # restore flags + popa # restore registers + + popl caller_return # switch return addresses + pushl $.Lwrapper_return + + jmp *wrapper_target # wrapper_target should return at .Lwrapper_return + + .balign 16, 0x90 +.Lwrapper_return: + pushl caller_return # restore the original return address + pusha # more for reference sake here + pushf + + push %ebp # set up a stack frame + movl %esp, %ebp + + leal 4(%ebp), %eax # push flags addr + push %eax + leal 8(%ebp), %eax # push registers addr + push %eax + + leal 40(%ebp), %edx # push stack top address (relative to our entry) + movl (%ebp), %eax + subl %edx, %eax # calculate difference between entry and previous frame + push %eax + push %edx + + call *report_ret # report the return information (same args) +.Ldone: + + leave + popf + popa + ret + diff --git a/linphone/win32acm/wrapper.h b/linphone/win32acm/wrapper.h new file mode 100644 index 000000000..e307c0e65 --- /dev/null +++ b/linphone/win32acm/wrapper.h @@ -0,0 +1,20 @@ +#ifndef _WRAPPER_H +#define _WRAPPER_H + +#include + +typedef struct { + u_int32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; +} reg386_t; + +typedef int (*wrapper_func_t)(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); + +extern wrapper_func_t report_entry, report_ret; + +extern void (*wrapper_target)(void); + +extern int wrapper(void); +extern int null_call(void); + +#endif /* _WRAPPER_H */ + diff --git a/p2pproxy/.classpath b/p2pproxy/.classpath new file mode 100644 index 000000000..49212745e --- /dev/null +++ b/p2pproxy/.classpath @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/p2pproxy/.cvsignore b/p2pproxy/.cvsignore new file mode 100644 index 000000000..da41270a3 --- /dev/null +++ b/p2pproxy/.cvsignore @@ -0,0 +1,5 @@ +eclipsebuild +.settings +antbuild* +P2pNetwork-* +sipp2 diff --git a/p2pproxy/.gcjbuilder b/p2pproxy/.gcjbuilder new file mode 100644 index 000000000..1084bf2f2 --- /dev/null +++ b/p2pproxy/.gcjbuilder @@ -0,0 +1,21 @@ + + 0 + 0 + + 0 + + + + 0 + + 2 + + + + + + + debug + p2pproxy + make + \ No newline at end of file diff --git a/p2pproxy/.project b/p2pproxy/.project new file mode 100644 index 000000000..67cec9a6f --- /dev/null +++ b/p2pproxy/.project @@ -0,0 +1,17 @@ + + + p2pproxy + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/p2pproxy/bin/p2pproxy-cmd.bat b/p2pproxy/bin/p2pproxy-cmd.bat new file mode 100644 index 000000000..f1fc5f0c8 --- /dev/null +++ b/p2pproxy/bin/p2pproxy-cmd.bat @@ -0,0 +1,2 @@ +@echo off +"%JAVA_HOME%\bin\java.exe" -cp p2pproxy.jar org.linphone.p2pproxy.core.utils.AccountManagerCli %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file diff --git a/p2pproxy/bin/p2pproxy-cmd.sh b/p2pproxy/bin/p2pproxy-cmd.sh new file mode 100644 index 000000000..1598057d7 --- /dev/null +++ b/p2pproxy/bin/p2pproxy-cmd.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec ${JAVA_HOME}/bin/java -cp p2pproxy.jar org.linphone.p2pproxy.core.utils.AccountManagerCli $* \ No newline at end of file diff --git a/p2pproxy/bin/p2pproxy.bat b/p2pproxy/bin/p2pproxy.bat new file mode 100644 index 000000000..21eaf9330 --- /dev/null +++ b/p2pproxy/bin/p2pproxy.bat @@ -0,0 +1,2 @@ +@echo off +"%JAVA_HOME%\bin\java.exe" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6789 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar p2pproxy.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file diff --git a/p2pproxy/bin/p2pproxy.sh b/p2pproxy/bin/p2pproxy.sh new file mode 100644 index 000000000..91f319160 --- /dev/null +++ b/p2pproxy/bin/p2pproxy.sh @@ -0,0 +1,9 @@ +#!/bin/sh +if [ -z "$P2P_JMX_PORT"] ; then + P2P_JMX_PORT=6789 +fi +exec ${JAVA_HOME}/bin/java -Dcom.sun.management.jmxremote \ + -Dcom.sun.management.jmxremote.port=${P2P_JMX_PORT} \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false \ + -jar p2pproxy.jar $* \ No newline at end of file diff --git a/p2pproxy/build.xml b/p2pproxy/build.xml new file mode 100644 index 000000000..40e1a9cef --- /dev/null +++ b/p2pproxy/build.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangeRequest.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangeRequest.java new file mode 100644 index 000000000..bf83df66c --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangeRequest.java @@ -0,0 +1,81 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.*; + +public class ChangeRequest extends MessageAttribute { + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A B 0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + boolean changeIP = false; + boolean changePort = false; + + public ChangeRequest() { + super(MessageAttribute.MessageAttributeType.ChangeRequest); + } + + public boolean isChangeIP() { + return changeIP; + } + + public boolean isChangePort() { + return changePort; + } + + public void setChangeIP() { + changeIP = true; + } + + public void setChangePort() { + changePort = true; + } + + public byte[] getBytes() throws UtilityException { + byte[] result = new byte[8]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(4), 0, result, 2, 2); + + // change request header + if (changeIP) result[7] = Utility.integerToOneByte(4); + if (changePort) result[7] = Utility.integerToOneByte(2); + if (changeIP && changePort) result[7] = Utility.integerToOneByte(6); + return result; + } + + public static ChangeRequest parse(byte[] data) throws MessageAttributeParsingException { + try { + if (data.length < 4) { + throw new MessageAttributeParsingException("Data array too short"); + } + ChangeRequest cr = new ChangeRequest(); + int status = Utility.oneByteToInteger(data[3]); + switch (status) { + case 0: break; + case 2: cr.setChangePort(); break; + case 4: cr.setChangeIP(); break; + case 6: cr.setChangeIP(); cr.setChangePort(); break; + default: throw new MessageAttributeParsingException("Status parsing error"); + } + return cr; + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangedAddress.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangedAddress.java new file mode 100644 index 000000000..ce06b603c --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ChangedAddress.java @@ -0,0 +1,30 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + + +public class ChangedAddress extends MappedResponseChangedSourceAddressReflectedFrom { + private static Logger logger = Logger.getLogger("de.javawi.stun.attribute.ChangedAddress"); + + public ChangedAddress() { + super(MessageAttribute.MessageAttributeType.ChangedAddress); + } + + public static MessageAttribute parse(byte[] data) throws MessageAttributeParsingException { + ChangedAddress ca = new ChangedAddress(); + MappedResponseChangedSourceAddressReflectedFrom.parse(ca, data); + logger.finer("Message Attribute: Changed Address parsed: " + ca.toString() + "."); + return ca; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Data.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Data.java new file mode 100644 index 000000000..71452ad2f --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Data.java @@ -0,0 +1,20 @@ +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + +import de.javawi.jstun.util.UtilityException; + +public class Data extends MessageAttribute { + private static Logger logger = Logger.getLogger(Data.class.getName()); + @Override + public byte[] getBytes() throws UtilityException { + // TODO Auto-generated method stub + return null; + } + public static MessageAttribute parse(byte[] data) throws MessageAttributeParsingException { + Data ma = new Data(); + + logger.finer("Message Attribute: Data Address parsed: " + ma.toString() + "."); + return ma; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Dummy.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Dummy.java new file mode 100644 index 000000000..8e780dcc0 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Dummy.java @@ -0,0 +1,42 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.Utility; +import de.javawi.jstun.util.UtilityException; + +public class Dummy extends MessageAttribute { + int lengthValue; + public Dummy() { + super(MessageAttributeType.Dummy); + } + + public void setLengthValue(int length) { + this.lengthValue = length; + } + + public byte[] getBytes() throws UtilityException { + byte[] result = new byte[lengthValue + 4]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(lengthValue), 0, result, 2, 2); + return result; + } + + public static Dummy parse(byte[] data) { + Dummy dummy = new Dummy(); + dummy.setLengthValue(data.length); + return dummy; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ErrorCode.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ErrorCode.java new file mode 100644 index 000000000..04436dd7c --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ErrorCode.java @@ -0,0 +1,104 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.Utility; +import de.javawi.jstun.util.UtilityException; + +public class ErrorCode extends MessageAttribute { + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 0 |Class| Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reason Phrase (variable) .. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + int responseCode; + String reason; + + public ErrorCode() { + super(MessageAttribute.MessageAttributeType.ErrorCode); + } + + public void setResponseCode(int responseCode) throws MessageAttributeException { + switch (responseCode) { + case 400: reason = "Bad Request"; break; + case 401: reason = "Unauthorized"; break; + case 420: reason = "Unkown Attribute"; break; + case 430: reason = "Stale Credentials"; break; + case 431: reason = "Integrity Check Failure"; break; + case 432: reason = "Missing Username"; break; + case 433: reason = "Use TLS"; break; + case 500: reason = "Server Error"; break; + case 600: reason = "Global Failure"; break; + default: throw new MessageAttributeException("Response Code is not valid"); + } + this.responseCode = responseCode; + } + + public int getResponseCode() { + return responseCode; + } + + public String getReason() { + return reason; + } + + public byte[] getBytes() throws UtilityException { + int length = reason.length(); + // length adjustment + if ((length % 4) != 0) { + length += 4 - (length % 4); + } + // message attribute header + length += 4; + byte[] result = new byte[length]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(length-4), 0, result, 2, 2); + + // error code header + int classHeader = (int) Math.floor(((double)responseCode)/100); + result[6] = Utility.integerToOneByte(classHeader); + result[7] = Utility.integerToOneByte(responseCode%100); + byte[] reasonArray = reason.getBytes(); + System.arraycopy(reasonArray, 0, result, 8, reasonArray.length); + return result; + } + + public static ErrorCode parse(byte[] data) throws MessageAttributeParsingException { + try { + if (data.length < 4) { + throw new MessageAttributeParsingException("Data array too short"); + } + byte classHeaderByte = data[3]; + int classHeader = Utility.oneByteToInteger(classHeaderByte); + if ((classHeader < 1) || (classHeader > 6)) throw new MessageAttributeParsingException("Class parsing error"); + byte numberByte = data[4]; + int number = Utility.oneByteToInteger(numberByte); + if ((number < 0) || (number > 99)) throw new MessageAttributeParsingException("Number parsing error"); + int responseCode = (classHeader * 100) + number; + ErrorCode result = new ErrorCode(); + result.setResponseCode(responseCode); + return result; + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } catch (MessageAttributeException mae) { + throw new MessageAttributeParsingException("Parsing error"); + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedAddress.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedAddress.java new file mode 100644 index 000000000..bdb84acfe --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedAddress.java @@ -0,0 +1,29 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + + +public class MappedAddress extends MappedResponseChangedSourceAddressReflectedFrom { + private static Logger logger = Logger.getLogger("de.javawi.stun.attribute.MappedAddress"); + public MappedAddress() { + super(MessageAttribute.MessageAttributeType.MappedAddress); + } + + public static MessageAttribute parse(byte[] data) throws MessageAttributeParsingException { + MappedAddress ma = new MappedAddress(); + MappedResponseChangedSourceAddressReflectedFrom.parse(ma, data); + logger.finer("Message Attribute: Mapped Address parsed: " + ma.toString() + "."); + return ma; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedResponseChangedSourceAddressReflectedFrom.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedResponseChangedSourceAddressReflectedFrom.java new file mode 100644 index 000000000..252e96052 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MappedResponseChangedSourceAddressReflectedFrom.java @@ -0,0 +1,107 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.*; + +public class MappedResponseChangedSourceAddressReflectedFrom extends MessageAttribute { + int port; + Address address; + + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |x x x x x x x x| Family | Port | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + public MappedResponseChangedSourceAddressReflectedFrom() { + super(); + try { + port = 0; + address = new Address("0.0.0.0"); + } catch (UtilityException ue) { + ue.getMessage(); + ue.printStackTrace(); + } + } + + public MappedResponseChangedSourceAddressReflectedFrom(MessageAttribute.MessageAttributeType type) { + super(type); + } + + public int getPort() { + return port; + } + + public Address getAddress() { + return address; + } + + public void setPort(int port) throws MessageAttributeException { + if ((port > 65536) || (port < 0)) { + throw new MessageAttributeException("Port value " + port + " out of range."); + } + this.port = port; + } + + public void setAddress(Address address) { + this.address = address; + } + + public byte[] getBytes() throws UtilityException { + byte[] result = new byte[12]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(8), 0, result, 2, 2); + + // mappedaddress header + // family + result[5] = Utility.integerToOneByte(0x01); + // port + System.arraycopy(Utility.integerToTwoBytes(port), 0, result, 6, 2); + // address + System.arraycopy(address.getBytes(), 0, result, 8, 4); + return result; + } + + protected static MappedResponseChangedSourceAddressReflectedFrom parse(MappedResponseChangedSourceAddressReflectedFrom ma, byte[] data) throws MessageAttributeParsingException { + try { + if (data.length < 8) { + throw new MessageAttributeParsingException("Data array too short"); + } + int family = Utility.oneByteToInteger(data[1]); + if (family != 0x01) throw new MessageAttributeParsingException("Family " + family + " is not supported"); + byte[] portArray = new byte[2]; + System.arraycopy(data, 2, portArray, 0, 2); + ma.setPort(Utility.twoBytesToInteger(portArray)); + int firstOctet = Utility.oneByteToInteger(data[4]); + int secondOctet = Utility.oneByteToInteger(data[5]); + int thirdOctet = Utility.oneByteToInteger(data[6]); + int fourthOctet = Utility.oneByteToInteger(data[7]); + ma.setAddress(new Address(firstOctet, secondOctet, thirdOctet, fourthOctet)); + return ma; + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } catch (MessageAttributeException mae) { + throw new MessageAttributeParsingException("Port parsing error"); + } + } + + public String toString() { + return "Address " +address.toString() + ", Port " + port; + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttribute.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttribute.java new file mode 100644 index 000000000..2c1f1ef7f --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttribute.java @@ -0,0 +1,135 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.*; + +import de.javawi.jstun.util.*; + + +public abstract class MessageAttribute implements MessageAttributeInterface { + private static Logger logger = Logger.getLogger("de.javawi.stun.util.MessageAttribute"); + MessageAttributeType type; + + public MessageAttribute() { + } + + public MessageAttribute(MessageAttributeType type) { + setType(type); + } + + public void setType(MessageAttributeType type) { + this.type = type; + } + + public MessageAttribute.MessageAttributeType getType() { + return type; + } + + public static int typeToInteger(MessageAttributeType type) { + if (type == MessageAttributeType.MappedAddress) return MAPPEDADDRESS; + if (type == MessageAttributeType.ResponseAddress) return RESPONSEADDRESS; + if (type == MessageAttributeType.ChangeRequest) return CHANGEREQUEST; + if (type == MessageAttributeType.SourceAddress) return SOURCEADDRESS; + if (type == MessageAttributeType.ChangedAddress) return CHANGEDADDRESS; + if (type == MessageAttributeType.Username) return USERNAME; + if (type == MessageAttributeType.Password) return PASSWORD; + if (type == MessageAttributeType.MessageIntegrity) return MESSAGEINTEGRITY; + if (type == MessageAttributeType.ErrorCode) return ERRORCODE; + if (type == MessageAttributeType.UnknownAttribute) return UNKNOWNATTRIBUTE; + if (type == MessageAttributeType.ReflectedFrom) return REFLECTEDFROM; + if (type == MessageAttributeType.Dummy) return DUMMY; + //turn + if (type == MessageAttributeType.ChannelNumber) return CHANNELNUMBER; + if (type == MessageAttributeType.LifeTime) return LIFETIME; + if (type == MessageAttributeType.Bandwidth ) return BANDWIDTH; + if (type == MessageAttributeType.PeerAddress ) return PEERADDRESS; + if (type == MessageAttributeType.Data ) return DATA; + if (type == MessageAttributeType.RelayAddress ) return RELAYADDRESS; + if (type == MessageAttributeType.RequestedProps ) return REQUESTEDPROPS; + if (type == MessageAttributeType.RequestedTransport ) return REQUESTEDTRANSPORT; + if (type == MessageAttributeType.ReservationToken ) return RESERVATIONTOKEN; + return -1; + } + + public static MessageAttributeType intToType(long type) { + if (type == MAPPEDADDRESS) return MessageAttributeType.MappedAddress; + if (type == RESPONSEADDRESS) return MessageAttributeType.ResponseAddress; + if (type == CHANGEREQUEST) return MessageAttributeType.ChangeRequest; + if (type == SOURCEADDRESS) return MessageAttributeType.SourceAddress; + if (type == CHANGEDADDRESS) return MessageAttributeType.ChangedAddress; + if (type == USERNAME) return MessageAttributeType.Username; + if (type == PASSWORD) return MessageAttributeType.Password; + if (type == MESSAGEINTEGRITY) return MessageAttributeType.MessageIntegrity; + if (type == ERRORCODE) return MessageAttributeType.ErrorCode; + if (type == UNKNOWNATTRIBUTE) return MessageAttributeType.UnknownAttribute; + if (type == REFLECTEDFROM) return MessageAttributeType.ReflectedFrom; + if (type == DUMMY) return MessageAttributeType.Dummy; + //turn + if (type == CHANNELNUMBER) return MessageAttributeType.ChannelNumber; + if (type == LIFETIME) return MessageAttributeType.LifeTime; + if (type == BANDWIDTH) return MessageAttributeType.Bandwidth; + if (type == PEERADDRESS) return MessageAttributeType.PeerAddress; + if (type == DATA) return MessageAttributeType.Data; + if (type == RELAYADDRESS) return MessageAttributeType.RelayAddress; + if (type == REQUESTEDPROPS) return MessageAttributeType.RequestedProps; + if (type == REQUESTEDTRANSPORT) return MessageAttributeType.RequestedTransport; + if (type == RESERVATIONTOKEN) return MessageAttributeType.ReservationToken; + return null; + } + + abstract public byte[] getBytes() throws UtilityException; + //abstract public MessageAttribute parse(byte[] data) throws MessageAttributeParsingException; + + public int getLength() throws UtilityException { + int length = getBytes().length; + return length; + } + + public static MessageAttribute parseCommonHeader(byte[] data) throws MessageAttributeParsingException { + try { + byte[] typeArray = new byte[2]; + System.arraycopy(data, 0, typeArray, 0, 2); + int type = Utility.twoBytesToInteger(typeArray); + byte[] lengthArray = new byte[2]; + System.arraycopy(data, 2, lengthArray, 0, 2); + int lengthValue = Utility.twoBytesToInteger(lengthArray); + byte[] valueArray = new byte[lengthValue]; + System.arraycopy(data, 4, valueArray, 0, lengthValue); + MessageAttribute ma; + switch (type) { + case MAPPEDADDRESS: ma = MappedAddress.parse(valueArray); break; + case RESPONSEADDRESS: ma = ResponseAddress.parse(valueArray); break; + case CHANGEREQUEST: ma = ChangeRequest.parse(valueArray); break; + case SOURCEADDRESS: ma = SourceAddress.parse(valueArray); break; + case CHANGEDADDRESS: ma = ChangedAddress.parse(valueArray); break; + case USERNAME: ma = Username.parse(valueArray); break; + case PASSWORD: ma = Password.parse(valueArray); break; + case MESSAGEINTEGRITY: ma = MessageIntegrity.parse(valueArray); break; + case ERRORCODE: ma = ErrorCode.parse(valueArray); break; + case UNKNOWNATTRIBUTE: ma = UnknownAttribute.parse(valueArray); break; + case REFLECTEDFROM: ma = ReflectedFrom.parse(valueArray); break; + default: + if (type <= 0x7fff) { + throw new UnknownMessageAttributeException("Unkown mandatory message attribute", intToType(type)); + } else { + logger.finer("MessageAttribute with type " + type + " unkown."); + ma = Dummy.parse(valueArray); + break; + } + } + return ma; + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeException.java new file mode 100644 index 000000000..a8109cfd1 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeException.java @@ -0,0 +1,20 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +public class MessageAttributeException extends Exception { + private static final long serialVersionUID = 3258131345099404850L; + + public MessageAttributeException(String mesg) { + super(mesg); + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeInterface.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeInterface.java new file mode 100644 index 000000000..8c55d7806 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeInterface.java @@ -0,0 +1,68 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +public interface MessageAttributeInterface { + public enum MessageAttributeType { MappedAddress + , ResponseAddress + , ChangeRequest + , SourceAddress + , ChangedAddress + , Username + , Password + , MessageIntegrity + , ErrorCode + , UnknownAttribute + , ReflectedFrom + , Dummy + , ChannelNumber + , LifeTime + , Bandwidth + , PeerAddress + , Data + , RelayAddress + , RequestedProps + , RequestedTransport + , ReservationToken}; + final static int MAPPEDADDRESS = 0x0001; + final static int RESPONSEADDRESS = 0x0002; + final static int CHANGEREQUEST = 0x0003; + final static int SOURCEADDRESS = 0x0004; + final static int CHANGEDADDRESS = 0x0005; + final static int USERNAME = 0x0006; + final static int PASSWORD = 0x0007; + final static int MESSAGEINTEGRITY = 0x0008; + final static int ERRORCODE = 0x0009; + final static int UNKNOWNATTRIBUTE = 0x000a; + final static int REFLECTEDFROM = 0x000b; + final static int DUMMY = 0x0000; +// turn attributes +// 0x000C: CHANNEL-NUMBER +// 0x000D: LIFETIME +// 0x0010: BANDWIDTH +// 0x0012: PEER-ADDRESS +// 0x0013: DATA +// 0x0016: RELAY-ADDRESS +// 0x0018: REQUESTED-PROPS +// 0x0019: REQUESTED-TRANSPORT +// 0x0022: RESERVATION-TOKEN + final static int CHANNELNUMBER = 0x000C; + final static int LIFETIME = 0x000D; + final static int BANDWIDTH = 0x0010; + final static int PEERADDRESS = 0x0012; + final static int DATA = 0x0013; + final static int RELAYADDRESS = 0x0016; + final static int REQUESTEDPROPS = 0x0018; + final static int REQUESTEDTRANSPORT = 0x0019; + final static int RESERVATIONTOKEN = 0x0022; + +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeParsingException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeParsingException.java new file mode 100644 index 000000000..d20278976 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageAttributeParsingException.java @@ -0,0 +1,20 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +public class MessageAttributeParsingException extends MessageAttributeException { + private static final long serialVersionUID = 3258409534426263605L; + + public MessageAttributeParsingException(String mesg) { + super(mesg); + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageIntegrity.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageIntegrity.java new file mode 100644 index 000000000..7aa7df3d7 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/MessageIntegrity.java @@ -0,0 +1,27 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +public class MessageIntegrity extends MessageAttribute { + // incomplete message integrity implementation + public MessageIntegrity() { + super(MessageAttribute.MessageAttributeType.MessageIntegrity); + } + + public byte[] getBytes() { + return new byte[0]; + } + + public static MessageIntegrity parse(byte[] data) { + return new MessageIntegrity(); + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Password.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Password.java new file mode 100644 index 000000000..679a193d9 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Password.java @@ -0,0 +1,64 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.Utility; +import de.javawi.jstun.util.UtilityException; + +public class Password extends MessageAttribute { + String password; + + public Password() { + super(MessageAttribute.MessageAttributeType.Password); + } + + public Password(String password) { + super(MessageAttribute.MessageAttributeType.Password); + setPassword(password); + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public byte[] getBytes() throws UtilityException { + int length = password.length(); + // password header + if ((length % 4) != 0) { + length += 4 - (length % 4); + } + // message attribute header + length += 4; + byte[] result = new byte[length]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(length - 4), 0, result, 2, 2); + + // password header + byte[] temp = password.getBytes(); + System.arraycopy(temp, 0, result, 4, temp.length); + return result; + } + + public static Password parse(byte[] data) { + Password result = new Password(); + String password = new String(data); + result.setPassword(password); + return result; + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ReflectedFrom.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ReflectedFrom.java new file mode 100644 index 000000000..e29831431 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ReflectedFrom.java @@ -0,0 +1,31 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + +public class ReflectedFrom extends MappedResponseChangedSourceAddressReflectedFrom { + private static Logger logger = Logger.getLogger("de.javawi.stun.attribute.ReflectedFrom"); + + public ReflectedFrom() { + super(MessageAttribute.MessageAttributeType.ReflectedFrom); + } + + public static ReflectedFrom parse(byte[] data) throws MessageAttributeParsingException { + ReflectedFrom result = new ReflectedFrom(); + MappedResponseChangedSourceAddressReflectedFrom.parse(result, data); + logger.finer("Message Attribute: ReflectedFrom parsed: " + result.toString() + "."); + return result; + } + + +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ResponseAddress.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ResponseAddress.java new file mode 100644 index 000000000..40c73bd0b --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/ResponseAddress.java @@ -0,0 +1,29 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + + +public class ResponseAddress extends MappedResponseChangedSourceAddressReflectedFrom { + private static Logger logger = Logger.getLogger("de.javawi.stun.attribute.ResponseAddress"); + public ResponseAddress() { + super(MessageAttribute.MessageAttributeType.ResponseAddress); + } + + public static MessageAttribute parse(byte[] data) throws MessageAttributeParsingException { + ResponseAddress ra = new ResponseAddress(); + MappedResponseChangedSourceAddressReflectedFrom.parse(ra, data); + logger.finer("Message Attribute: Response Address parsed: " + ra.toString() + "."); + return ra; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/SourceAddress.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/SourceAddress.java new file mode 100644 index 000000000..070d7d8d0 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/SourceAddress.java @@ -0,0 +1,29 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.logging.Logger; + + +public class SourceAddress extends MappedResponseChangedSourceAddressReflectedFrom { + private static Logger logger = Logger.getLogger("de.javawi.stun.attribute.SourceAddress"); + public SourceAddress() { + super(MessageAttribute.MessageAttributeType.SourceAddress); + } + + public static MessageAttribute parse(byte[] data) throws MessageAttributeParsingException { + SourceAddress sa = new SourceAddress(); + MappedResponseChangedSourceAddressReflectedFrom.parse(sa, data); + logger.finer("Message Attribute: Source Address parsed: " + sa.toString() + "."); + return sa; + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownAttribute.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownAttribute.java new file mode 100644 index 000000000..04f1abb8b --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownAttribute.java @@ -0,0 +1,82 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import java.util.*; + +import de.javawi.jstun.util.Utility; +import de.javawi.jstun.util.UtilityException; + +public class UnknownAttribute extends MessageAttribute { + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute 1 Type | Attribute 2 Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Attribute 3 Type | Attribute 4 Type ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + Vector unkown = new Vector(); + + public UnknownAttribute() { + super(MessageAttribute.MessageAttributeType.UnknownAttribute); + } + + public void addAttribute(MessageAttributeType attribute) { + unkown.add(attribute); + } + + public byte[] getBytes() throws UtilityException { + int length = 0; + if (unkown.size()%2 == 1) { + length = 2 * (unkown.size() + 1) + 4; + } else { + length = 2 * unkown.size() + 4; + } + byte[] result = new byte[length]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(length - 4), 0, result, 2, 2); + + // unkown attribute header + Iterator it = unkown.iterator(); + while(it.hasNext()) { + MessageAttributeType attri = it.next(); + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(attri)), 0, result, 4, 2); + } + // padding + if (unkown.size()%2 == 1) { + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(unkown.elementAt(1))), 0, result, 4, 2); + } + return result; + } + + public static UnknownAttribute parse(byte[] data) throws MessageAttributeParsingException { + try { + UnknownAttribute result = new UnknownAttribute(); + if (data.length % 4 != 0) throw new MessageAttributeParsingException("Data array too short"); + for (int i = 0; i < data.length; i += 4) { + byte[] temp = new byte[4]; + System.arraycopy(data, i, temp, 0, 4); + long attri = Utility.fourBytesToLong(temp); + result.addAttribute(MessageAttribute.intToType(attri)); + } + return result; + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownMessageAttributeException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownMessageAttributeException.java new file mode 100644 index 000000000..4ddd49229 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/UnknownMessageAttributeException.java @@ -0,0 +1,18 @@ +package de.javawi.jstun.attribute; + +import de.javawi.jstun.attribute.MessageAttributeInterface.MessageAttributeType; + +public class UnknownMessageAttributeException extends MessageAttributeParsingException { + private static final long serialVersionUID = 5375193544145543299L; + + private MessageAttributeType type; + + public UnknownMessageAttributeException(String mesg, MessageAttributeType type) { + super(mesg); + this.type = type; + } + + public MessageAttributeType getType() { + return type; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Username.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Username.java new file mode 100644 index 000000000..1afaec7b1 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/attribute/Username.java @@ -0,0 +1,64 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.attribute; + +import de.javawi.jstun.util.Utility; +import de.javawi.jstun.util.UtilityException; + +public class Username extends MessageAttribute { + String username; + + public Username() { + super(MessageAttribute.MessageAttributeType.Username); + } + + public Username(String username) { + super(MessageAttribute.MessageAttributeType.Username); + setUsername(username); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public byte[] getBytes() throws UtilityException { + int length = username.length(); + // username header + if ((length % 4) != 0) { + length += 4 - (length % 4); + } + // message attribute header + length += 4; + byte[] result = new byte[length]; + // message attribute header + // type + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + // length + System.arraycopy(Utility.integerToTwoBytes(length-4), 0, result, 2, 2); + + // username header + byte[] temp = username.getBytes(); + System.arraycopy(temp, 0, result, 4, temp.length); + return result; + } + + public static Username parse(byte[] data) { + Username result = new Username(); + String username = new String(data); + result.setUsername(username); + return result; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeader.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeader.java new file mode 100644 index 000000000..1e6dab58b --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeader.java @@ -0,0 +1,202 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.header; + +import de.javawi.jstun.attribute.*; +import de.javawi.jstun.util.*; + +import java.util.*; +import java.util.logging.*; + +public class MessageHeader implements MessageHeaderInterface { + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | STUN Message Type | Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * Transaction ID + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + private static Logger logger = Logger.getLogger("de.javawi.stun.header.MessageHeader"); + MessageHeaderType type; + byte[] id = new byte[16]; + + TreeMap ma = new TreeMap(); + + public MessageHeader() { + super(); + } + + public MessageHeader(MessageHeaderType type) { + super(); + setType(type); + } + + public void setType(MessageHeaderType type) { + this.type = type; + } + + public MessageHeaderType getType() { + return type; + } + + public static int typeToInteger(MessageHeaderType type) { + if (type == MessageHeaderType.BindingRequest) return BINDINGREQUEST; + if (type == MessageHeaderType.BindingResponse) return BINDINGRESPONSE; + if (type == MessageHeaderType.BindingErrorResponse) return BINDINGERRORRESPONSE; + if (type == MessageHeaderType.SharedSecretRequest) return SHAREDSECRETREQUEST; + if (type == MessageHeaderType.SharedSecretResponse) return SHAREDSECRETRESPONSE; + if (type == MessageHeaderType.SharedSecretErrorResponse) return SHAREDSECRETERRORRESPONSE; + //turn headers + if (type == MessageHeaderType.AllocateRequest) return ALLOCATEREQUEST; + if (type == MessageHeaderType.AllocateResponse) return ALLOCATERESPONSE; + if (type == MessageHeaderType.AllocateErrorResponse) return ALLOCATEERRORRESPONSE; + if (type == MessageHeaderType.RefreshRequest) return REFRESHREQUEST; + if (type == MessageHeaderType.RefreshResponse) return REFRESHRESPONSE; + if (type == MessageHeaderType.RefreshErrorResponse) return REFRESHERRORRESPONSE; + if (type == MessageHeaderType.ChannelBindRequest) return CHANNELBINDREQUEST; + if (type == MessageHeaderType.ChannelBindResponse) return CHANNELBINDRESPONSE; + if (type == MessageHeaderType.ChannelBindErrorResponse) return CHANNELBINDERRORRESPONSE; + + + return -1; + } + + public void setTransactionID(byte[] id) { + System.arraycopy(id, 0, this.id, 0, 16); + } + + public void generateTransactionID() throws UtilityException { + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 0, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 2, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 4, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 6, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 8, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 10, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 12, 2); + System.arraycopy(Utility.integerToTwoBytes((int)(Math.random() * 65536)), 0, id, 14, 2); + } + + public byte[] getTransactionID() { + byte[] idCopy = new byte[id.length]; + System.arraycopy(id, 0, idCopy, 0, id.length); + return idCopy; + } + + public boolean equalTransactionID(MessageHeader header) { + byte[] idHeader = header.getTransactionID(); + if (idHeader.length != 16) return false; + if ((idHeader[0] == id[0]) && (idHeader[1] == id[1]) && (idHeader[2] == id[2]) && (idHeader[3] == id[3]) && + (idHeader[4] == id[4]) && (idHeader[5] == id[5]) && (idHeader[6] == id[6]) && (idHeader[7] == id[7]) && + (idHeader[8] == id[8]) && (idHeader[9] == id[9]) && (idHeader[10] == id[10]) && (idHeader[11] == id[11]) && + (idHeader[12] == id[12]) && (idHeader[13] == id[13]) && (idHeader[14] == id[14]) && (idHeader[15] == id[15])) { + return true; + } else { + return false; + } + } + + public void addMessageAttribute(MessageAttribute attri) { + ma.put(attri.getType(), attri); + } + + public MessageAttribute getMessageAttribute(MessageAttribute.MessageAttributeType type) { + return ma.get(type); + } + + public byte[] getBytes() throws UtilityException { + int length = 20; + Iterator it = ma.keySet().iterator(); + while (it.hasNext()) { + MessageAttribute attri = ma.get(it.next()); + length += attri.getLength(); + } + // add attribute size + attributes.getSize(); + byte[] result = new byte[length]; + System.arraycopy(Utility.integerToTwoBytes(typeToInteger(type)), 0, result, 0, 2); + System.arraycopy(Utility.integerToTwoBytes(length-20), 0, result, 2, 2); + System.arraycopy(id, 0, result, 4, 16); + + // arraycopy of attributes + int offset = 20; + it = ma.keySet().iterator(); + while (it.hasNext()) { + MessageAttribute attri = ma.get(it.next()); + System.arraycopy(attri.getBytes(), 0, result, offset, attri.getLength()); + offset += attri.getLength(); + } + return result; + } + + public int getLength() throws UtilityException { + return getBytes().length; + } + + public void parseAttributes(byte[] data) throws MessageAttributeParsingException { + try { + byte[] lengthArray = new byte[2]; + System.arraycopy(data, 2, lengthArray, 0, 2); + int length = Utility.twoBytesToInteger(lengthArray); + System.arraycopy(data, 4, id, 0, 16); + byte[] cuttedData; + int offset = 20; + while (length > 0) { + cuttedData = new byte[length]; + System.arraycopy(data, offset, cuttedData, 0, length); + MessageAttribute ma = MessageAttribute.parseCommonHeader(cuttedData); + addMessageAttribute(ma); + length -= ma.getLength(); + offset += ma.getLength(); + } + } catch (UtilityException ue) { + throw new MessageAttributeParsingException("Parsing error"); + } + } + + public static MessageHeader parseHeader(byte[] data) throws MessageHeaderParsingException { + try { + MessageHeader mh = new MessageHeader(); + byte[] typeArray = new byte[2]; + System.arraycopy(data, 0, typeArray, 0, 2); + int type = Utility.twoBytesToInteger(typeArray); + switch (type) { + case BINDINGREQUEST: mh.setType(MessageHeaderType.BindingRequest); logger.finer("Binding Request received."); break; + case BINDINGRESPONSE: mh.setType(MessageHeaderType.BindingResponse); logger.finer("Binding Response received."); break; + case BINDINGERRORRESPONSE: mh.setType(MessageHeaderType.BindingErrorResponse); logger.finer("Binding Error Response received."); break; + case SHAREDSECRETREQUEST: mh.setType(MessageHeaderType.SharedSecretRequest); logger.finer("Shared Secret Request received."); break; + case SHAREDSECRETRESPONSE: mh.setType(MessageHeaderType.SharedSecretResponse); logger.finer("Shared Secret Response received."); break; + case SHAREDSECRETERRORRESPONSE: mh.setType(MessageHeaderType.SharedSecretErrorResponse); logger.finer("Shared Secret Error Response received.");break; + //turn + case ALLOCATEREQUEST: mh.setType(MessageHeaderType.AllocateRequest); logger.finer("Allocate Request received."); break; + case ALLOCATERESPONSE: mh.setType(MessageHeaderType.AllocateResponse); logger.finer("Allocate Response received."); break; + case ALLOCATEERRORRESPONSE: mh.setType(MessageHeaderType.AllocateErrorResponse); logger.finer("Allocate Errro received."); break; + case REFRESHREQUEST: mh.setType(MessageHeaderType.RefreshRequest); logger.finer("Refresh Request received."); break; + case REFRESHRESPONSE: mh.setType(MessageHeaderType.RefreshResponse); logger.finer("Refresh Response received."); break; + case REFRESHERRORRESPONSE: mh.setType(MessageHeaderType.RefreshErrorResponse); logger.finer("Refresh Error received."); break; + case CHANNELBINDREQUEST: mh.setType(MessageHeaderType.ChannelBindRequest); logger.finer("ChannelBind Request received."); break; + case CHANNELBINDRESPONSE: mh.setType(MessageHeaderType.ChannelBindResponse); logger.finer("ChannelBind Response received."); break; + case CHANNELBINDERRORRESPONSE: mh.setType(MessageHeaderType.ChannelBindErrorResponse); logger.finer("ChannelBind Error received."); break; + default: throw new MessageHeaderParsingException("Message type " + type + "is not supported"); + } + return mh; + } catch (UtilityException ue) { + throw new MessageHeaderParsingException("Parsing error"); + } + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderException.java new file mode 100644 index 000000000..f4a9fa498 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderException.java @@ -0,0 +1,20 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.header; + +public class MessageHeaderException extends Exception { + private static final long serialVersionUID = 3689066248944103737L; + + public MessageHeaderException(String mesg) { + super(mesg); + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderInterface.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderInterface.java new file mode 100644 index 000000000..1b7a2cfe6 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderInterface.java @@ -0,0 +1,61 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.header; + +public interface MessageHeaderInterface { + public enum MessageHeaderType { BindingRequest + , BindingResponse + , BindingErrorResponse + , SharedSecretRequest + , SharedSecretResponse + , SharedSecretErrorResponse + , AllocateRequest + , AllocateResponse + , AllocateErrorResponse + , RefreshRequest + , RefreshResponse + , RefreshErrorResponse + , ChannelBindRequest + , ChannelBindResponse + , ChannelBindErrorResponse + ,SendIndication + ,DataIndication}; + final static int BINDINGREQUEST = 0x0001; + final static int BINDINGRESPONSE = 0x0101; + final static int BINDINGERRORRESPONSE = 0x0111; + final static int SHAREDSECRETREQUEST = 0x0002; + final static int SHAREDSECRETRESPONSE = 0x0102; + final static int SHAREDSECRETERRORRESPONSE = 0x0112; + +// TURN defines ten new Message Types: +//Request/Response Transactions +//0x003 : Allocate +//0x004 : Refresh +//0x009 : ChannelBind +//0x006 : Send +//0x007 : Data + + + final static int ALLOCATEREQUEST = 0x0003; + final static int ALLOCATERESPONSE = 0x0103; + final static int ALLOCATEERRORRESPONSE = 0x0113; + final static int REFRESHREQUEST = 0x0004; + final static int REFRESHRESPONSE = 0x0104; + final static int REFRESHERRORRESPONSE = 0x0114; + final static int CHANNELBINDREQUEST = 0x0009; + final static int CHANNELBINDRESPONSE = 0x0109; + final static int CHANNELBINDERRORRESPONSE = 0x0119; + final static int SENDINDICATION = 0x0006; + final static int DATAINDICATION = 0x0007; + + +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderParsingException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderParsingException.java new file mode 100644 index 000000000..d5192ef28 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/header/MessageHeaderParsingException.java @@ -0,0 +1,20 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.header; + +public class MessageHeaderParsingException extends MessageHeaderException { + private static final long serialVersionUID = 3544393617029607478L; + + public MessageHeaderParsingException(String mesg) { + super(mesg); + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/BindingLifetimeTest.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/BindingLifetimeTest.java new file mode 100644 index 000000000..1dca91b47 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/BindingLifetimeTest.java @@ -0,0 +1,192 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test; + +import java.util.logging.*; +import java.util.*; +import java.io.*; +import java.net.*; + +import de.javawi.jstun.attribute.*; +import de.javawi.jstun.header.*; +import de.javawi.jstun.util.UtilityException; + +public class BindingLifetimeTest { + private static Logger logger = Logger.getLogger("de.javawi.stun.test.BindingLifetimeTest"); + String stunServer; + int port; + int timeout = 300; //ms + MappedAddress ma; + Timer timer; + DatagramSocket initialSocket; + + // start value for binary search - should be carefully choosen + int upperBinarySearchLifetime = 345000; // ms + int lowerBinarySearchLifetime = 0; + int binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2; + + // lifetime value + int lifetime = -1; // -1 means undefined. + boolean completed = false; + + public BindingLifetimeTest(String stunServer, int port) { + super(); + this.stunServer = stunServer; + this.port = port; + timer = new Timer(true); + } + + public void test() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageAttributeException, MessageHeaderParsingException { + initialSocket = new DatagramSocket(); + initialSocket.connect(InetAddress.getByName(stunServer), port); + initialSocket.setSoTimeout(timeout); + + if (bindingCommunicationInitialSocket()) { + return; + } + BindingLifetimeTask task = new BindingLifetimeTask(); + timer.schedule(task, binarySearchLifetime); + logger.finer("Timer scheduled initially: " + binarySearchLifetime + "."); + } + + private boolean bindingCommunicationInitialSocket() throws UtilityException, IOException, MessageHeaderParsingException, MessageAttributeParsingException { + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + ChangeRequest changeRequest = new ChangeRequest(); + sendMH.addMessageAttribute(changeRequest); + byte[] data = sendMH.getBytes(); + + DatagramPacket send = new DatagramPacket(data, data.length, InetAddress.getByName(stunServer), port); + initialSocket.send(send); + logger.finer("Binding Request sent."); + + MessageHeader receiveMH = new MessageHeader(); + while (!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + initialSocket.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress); + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + logger.config("Message header contains an Errorcode message attribute."); + return true; + } + if (ma == null) { + logger.config("Response does not contain a Mapped Address message attribute."); + return true; + } + return false; + } + + public int getLifetime() { + return lifetime; + } + + public boolean isCompleted() { + return completed; + } + + public void setUpperBinarySearchLifetime(int upperBinarySearchLifetime) { + this.upperBinarySearchLifetime = upperBinarySearchLifetime; + binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2; + } + + class BindingLifetimeTask extends TimerTask { + + public BindingLifetimeTask() { + super(); + } + + public void run() { + try { + lifetimeQuery(); + } catch (Exception e) { + logger.config("Unhandled Exception. BindLifetimeTasks stopped."); + e.printStackTrace(); + } + } + + public void lifetimeQuery() throws UtilityException, MessageAttributeException, MessageHeaderParsingException, MessageAttributeParsingException, IOException { + try { + DatagramSocket socket = new DatagramSocket(); + socket.connect(InetAddress.getByName(stunServer), port); + socket.setSoTimeout(timeout); + + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + ChangeRequest changeRequest = new ChangeRequest(); + ResponseAddress responseAddress = new ResponseAddress(); + responseAddress.setAddress(ma.getAddress()); + responseAddress.setPort(ma.getPort()); + sendMH.addMessageAttribute(changeRequest); + sendMH.addMessageAttribute(responseAddress); + byte[] data = sendMH.getBytes(); + + DatagramPacket send = new DatagramPacket(data, data.length, InetAddress.getByName(stunServer), port); + socket.send(send); + logger.finer("Binding Request sent."); + + MessageHeader receiveMH = new MessageHeader(); + while (!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + initialSocket.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + logger.config("Message header contains errorcode message attribute."); + return; + } + logger.finer("Binding Response received."); + if (upperBinarySearchLifetime == (lowerBinarySearchLifetime + 1)) { + logger.config("BindingLifetimeTest completed. UDP binding lifetime: " + binarySearchLifetime + "."); + completed = true; + return; + } + lifetime = binarySearchLifetime; + logger.finer("Lifetime update: " + lifetime + "."); + lowerBinarySearchLifetime = binarySearchLifetime; + binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2; + if (binarySearchLifetime > 0) { + BindingLifetimeTask task = new BindingLifetimeTask(); + timer.schedule(task, binarySearchLifetime); + logger.finer("Timer scheduled: " + binarySearchLifetime + "."); + } else { + completed = true; + } + } catch (SocketTimeoutException ste) { + logger.finest("Read operation at query socket timeout."); + if (upperBinarySearchLifetime == (lowerBinarySearchLifetime + 1)) { + logger.config("BindingLifetimeTest completed. UDP binding lifetime: " + binarySearchLifetime + "."); + completed = true; + return; + } + upperBinarySearchLifetime = binarySearchLifetime; + binarySearchLifetime = ( upperBinarySearchLifetime + lowerBinarySearchLifetime ) / 2; + if (binarySearchLifetime > 0) { + if (bindingCommunicationInitialSocket()) { + return; + } + BindingLifetimeTask task = new BindingLifetimeTask(); + timer.schedule(task, binarySearchLifetime); + logger.finer("Timer scheduled: " + binarySearchLifetime + "."); + } else { + completed = true; + } + } + } + } +} + diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryInfo.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryInfo.java new file mode 100644 index 000000000..abaab15eb --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryInfo.java @@ -0,0 +1,153 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test; + +import java.net.*; + +public class DiscoveryInfo { + private InetAddress testIP; + private boolean error = false; + private int errorResponseCode = 0; + private String errorReason; + private boolean openAccess = false; + private boolean blockedUDP = false; + private boolean fullCone = false; + private boolean restrictedCone = false; + private boolean portRestrictedCone = false; + private boolean symmetric = false; + private boolean symmetricUDPFirewall = false; + private InetAddress publicIP; + + public DiscoveryInfo(InetAddress testIP) { + this.testIP = testIP; + } + + public boolean isError() { + return error; + } + + public void setError(int responseCode, String reason) { + this.error = true; + this.errorResponseCode = responseCode; + this.errorReason = reason; + } + + public boolean isOpenAccess() { + if (error) return false; + return openAccess; + } + + public void setOpenAccess() { + this.openAccess = true; + } + + public boolean isBlockedUDP() { + if (error) return false; + return blockedUDP; + } + + public void setBlockedUDP() { + this.blockedUDP = true; + } + + public boolean isFullCone() { + if (error) return false; + return fullCone; + } + + public void setFullCone() { + this.fullCone = true; + } + + public boolean isPortRestrictedCone() { + if (error) return false; + return portRestrictedCone; + } + + public void setPortRestrictedCone() { + this.portRestrictedCone = true; + } + + public boolean isRestrictedCone() { + if (error) return false; + return restrictedCone; + } + + public void setRestrictedCone() { + this.restrictedCone = true; + } + + public boolean isSymmetric() { + if (error) return false; + return symmetric; + } + + public void setSymmetric() { + this.symmetric = true; + } + + public boolean isSymmetricUDPFirewall() { + if (error) return false; + return symmetricUDPFirewall; + } + + public void setSymmetricUDPFirewall() { + this.symmetricUDPFirewall = true; + } + + public InetAddress getPublicIP() { + return publicIP; + } + + public InetAddress getLocalIP() { + return testIP; + } + + public void setPublicIP(InetAddress publicIP) { + this.publicIP = publicIP; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Network interface: "); + try { + sb.append(NetworkInterface.getByInetAddress(testIP).getName()); + } catch (SocketException se) { + sb.append("unknown"); + } + sb.append("\n"); + sb.append("Local IP address: "); + sb.append(testIP.getHostAddress()); + sb.append("\n"); + if (error) { + sb.append(errorReason + " - Responsecode: " + errorResponseCode); + return sb.toString(); + } + sb.append("Result: "); + if (openAccess) sb.append("Open access to the Internet.\n"); + if (blockedUDP) sb.append("Firewall blocks UDP.\n"); + if (fullCone) sb.append("Full Cone NAT handles connections.\n"); + if (restrictedCone) sb.append("Restricted Cone NAT handles connections.\n"); + if (portRestrictedCone) sb.append("Port restricted Cone NAT handles connections.\n"); + if (symmetric) sb.append("Symmetric Cone NAT handles connections.\n"); + if (symmetricUDPFirewall) sb.append ("Symmetric UDP Firewall handles connections.\n"); + if (!openAccess && !blockedUDP && !fullCone && !restrictedCone && !portRestrictedCone && !symmetric && !symmetricUDPFirewall) sb.append("unkown\n"); + sb.append("Public IP address: "); + if (publicIP != null) { + sb.append(publicIP.getHostAddress()); + } else { + sb.append("unknown"); + } + sb.append("\n"); + return sb.toString(); + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryTest.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryTest.java new file mode 100644 index 000000000..4f940adfe --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/DiscoveryTest.java @@ -0,0 +1,351 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.logging.Logger; + + + + + +import de.javawi.jstun.attribute.ChangeRequest; +import de.javawi.jstun.attribute.ChangedAddress; +import de.javawi.jstun.attribute.ErrorCode; +import de.javawi.jstun.attribute.MappedAddress; +import de.javawi.jstun.attribute.MessageAttribute; +import de.javawi.jstun.attribute.MessageAttributeException; +import de.javawi.jstun.attribute.MessageAttributeParsingException; +import de.javawi.jstun.header.MessageHeader; +import de.javawi.jstun.header.MessageHeaderParsingException; +import de.javawi.jstun.util.UtilityException; + +public class DiscoveryTest { + private static Logger logger = Logger.getLogger("de.javawi.stun.test.DiscoveryTest"); + InetAddress iaddress; + String stunServer; + int port; + int timeoutInitValue = 300; //ms + MappedAddress ma = null; + ChangedAddress ca = null; + boolean nodeNatted = true; + DatagramSocket socketTest1 = null; + DiscoveryInfo di = null; + + public DiscoveryTest(InetAddress iaddress , String stunServer, int port) { + super(); + this.iaddress = iaddress; + this.stunServer = stunServer; + this.port = port; + } + + public DiscoveryInfo test() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageAttributeException, MessageHeaderParsingException{ + ma = null; + ca = null; + nodeNatted = true; + socketTest1 = null; + di = new DiscoveryInfo(iaddress); + + if (test1()) { + if (test2()) { + if (test1Redo()) { + test3(); + } + } + } + + socketTest1.close(); + + return di; + } + + private boolean test1() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageHeaderParsingException { + int timeSinceFirstTransmission = 0; + int timeout = timeoutInitValue; + while (true) { + try { + // Test 1 including response + socketTest1 = new DatagramSocket(new InetSocketAddress(iaddress, 0)); + socketTest1.setReuseAddress(true); + socketTest1.connect(InetAddress.getByName(stunServer), port); + socketTest1.setSoTimeout(timeout); + + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + + ChangeRequest changeRequest = new ChangeRequest(); + sendMH.addMessageAttribute(changeRequest); + + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + socketTest1.send(send); + logger.finer("Test 1: Binding Request sent."); + + MessageHeader receiveMH = new MessageHeader(); + while (!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + socketTest1.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + + ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress); + ca = (ChangedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ChangedAddress); + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + di.setError(ec.getResponseCode(), ec.getReason()); + logger.config("Message header contains an Errorcode message attribute."); + return false; + } + if ((ma == null) || (ca == null)) { + di.setError(700, "The server is sending an incomplete response (Mapped Address and Changed Address message attributes are missing). The client should not retry."); + logger.config("Response does not contain a Mapped Address or Changed Address message attribute."); + return false; + } else { + di.setPublicIP(ma.getAddress().getInetAddress()); + if ((ma.getPort() == socketTest1.getLocalPort()) && (ma.getAddress().getInetAddress().equals(socketTest1.getLocalAddress()))) { + logger.fine("Node is not natted."); + nodeNatted = false; + } else { + logger.fine("Node is natted."); + } + return true; + } + } catch (SocketTimeoutException ste) { + if (timeSinceFirstTransmission < 7900) { + logger.finer("Test 1: Socket timeout while receiving the response."); + timeSinceFirstTransmission += timeout; + int timeoutAddValue = (timeSinceFirstTransmission * 2); + if (timeoutAddValue > 1600) timeoutAddValue = 1600; + timeout = timeoutAddValue; + } else { + // node is not capable of udp communication + logger.finer("Test 1: Socket timeout while receiving the response. Maximum retry limit exceed. Give up."); + di.setBlockedUDP(); + logger.fine("Node is not capable of UDP communication."); + return false; + } + } + } + } + + private boolean test2() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageAttributeException, MessageHeaderParsingException { + int timeSinceFirstTransmission = 0; + int timeout = timeoutInitValue; + while (true) { + try { + // Test 2 including response + DatagramSocket sendSocket = new DatagramSocket(new InetSocketAddress(iaddress, 0)); + sendSocket.connect(InetAddress.getByName(stunServer), port); + sendSocket.setSoTimeout(timeout); + + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + + ChangeRequest changeRequest = new ChangeRequest(); + changeRequest.setChangeIP(); + changeRequest.setChangePort(); + sendMH.addMessageAttribute(changeRequest); + + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + sendSocket.send(send); + logger.finer("Test 2: Binding Request sent."); + + int localPort = sendSocket.getLocalPort(); + InetAddress localAddress = sendSocket.getLocalAddress(); + + sendSocket.close(); + + DatagramSocket receiveSocket = new DatagramSocket(localPort, localAddress); + receiveSocket.connect(ca.getAddress().getInetAddress(), ca.getPort()); + receiveSocket.setSoTimeout(timeout); + + MessageHeader receiveMH = new MessageHeader(); + while(!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + receiveSocket.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + di.setError(ec.getResponseCode(), ec.getReason()); + logger.config("Message header contains an Errorcode message attribute."); + return false; + } + if (!nodeNatted) { + di.setOpenAccess(); + logger.fine("Node has open access to the Internet (or, at least the node is behind a full-cone NAT without translation)."); + } else { + di.setFullCone(); + logger.fine("Node is behind a full-cone NAT."); + } + return false; + } catch (SocketTimeoutException ste) { + if (timeSinceFirstTransmission < 7900) { + logger.finer("Test 2: Socket timeout while receiving the response."); + timeSinceFirstTransmission += timeout; + int timeoutAddValue = (timeSinceFirstTransmission * 2); + if (timeoutAddValue > 1600) timeoutAddValue = 1600; + timeout = timeoutAddValue; + } else { + logger.finer("Test 2: Socket timeout while receiving the response. Maximum retry limit exceed. Give up."); + if (!nodeNatted) { + di.setSymmetricUDPFirewall(); + logger.fine("Node is behind a symmetric UDP firewall."); + return false; + } else { + // not is natted + // redo test 1 with address and port as offered in the changed-address message attribute + return true; + } + } + } + } + } + + private boolean test1Redo() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageHeaderParsingException{ + int timeSinceFirstTransmission = 0; + int timeout = timeoutInitValue; + while (true) { + // redo test 1 with address and port as offered in the changed-address message attribute + try { + // Test 1 with changed port and address values + socketTest1.connect(ca.getAddress().getInetAddress(), ca.getPort()); + socketTest1.setSoTimeout(timeout); + + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + + ChangeRequest changeRequest = new ChangeRequest(); + sendMH.addMessageAttribute(changeRequest); + + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + socketTest1.send(send); + logger.finer("Test 1 redo with changed address: Binding Request sent."); + + MessageHeader receiveMH = new MessageHeader(); + while (!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + socketTest1.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + MappedAddress ma2 = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress); + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + di.setError(ec.getResponseCode(), ec.getReason()); + logger.config("Message header contains an Errorcode message attribute."); + return false; + } + if (ma2 == null) { + di.setError(700, "The server is sending an incomplete response (Mapped Address message attribute is missing). The client should not retry."); + logger.config("Response does not contain a Mapped Address message attribute."); + return false; + } else { + if ((ma.getPort() != ma2.getPort()) || (!(ma.getAddress().getInetAddress().equals(ma2.getAddress().getInetAddress())))) { + di.setSymmetric(); + logger.fine("Node is behind a symmetric NAT."); + return false; + } + } + return true; + } catch (SocketTimeoutException ste2) { + if (timeSinceFirstTransmission < 7900) { + logger.config("Test 1 redo with changed address: Socket timeout while receiving the response."); + timeSinceFirstTransmission += timeout; + int timeoutAddValue = (timeSinceFirstTransmission * 2); + if (timeoutAddValue > 1600) timeoutAddValue = 1600; + timeout = timeoutAddValue; + } else { + logger.config("Test 1 redo with changed address: Socket timeout while receiving the response. Maximum retry limit exceed. Give up."); + return false; + } + } + } + } + + private void test3() throws UtilityException, SocketException, UnknownHostException, IOException, MessageAttributeParsingException, MessageAttributeException, MessageHeaderParsingException { + int timeSinceFirstTransmission = 0; + int timeout = timeoutInitValue; + while (true) { + try { + // Test 3 including response + DatagramSocket sendSocket = new DatagramSocket(new InetSocketAddress(iaddress, 0)); + sendSocket.connect(InetAddress.getByName(stunServer), port); + sendSocket.setSoTimeout(timeout); + + MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest); + sendMH.generateTransactionID(); + + ChangeRequest changeRequest = new ChangeRequest(); + changeRequest.setChangePort(); + sendMH.addMessageAttribute(changeRequest); + + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + sendSocket.send(send); + logger.finer("Test 3: Binding Request sent."); + + int localPort = sendSocket.getLocalPort(); + InetAddress localAddress = sendSocket.getLocalAddress(); + + sendSocket.close(); + + DatagramSocket receiveSocket = new DatagramSocket(localPort, localAddress); + receiveSocket.connect(InetAddress.getByName(stunServer), ca.getPort()); + receiveSocket.setSoTimeout(timeout); + + MessageHeader receiveMH = new MessageHeader(); + while (!(receiveMH.equalTransactionID(sendMH))) { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + receiveSocket.receive(receive); + receiveMH = MessageHeader.parseHeader(receive.getData()); + receiveMH.parseAttributes(receive.getData()); + } + ErrorCode ec = (ErrorCode) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.ErrorCode); + if (ec != null) { + di.setError(ec.getResponseCode(), ec.getReason()); + logger.config("Message header contains an Errorcode message attribute."); + return; + } + if (nodeNatted) { + di.setRestrictedCone(); + logger.fine("Node is behind a restricted NAT."); + return; + } + } catch (SocketTimeoutException ste) { + if (timeSinceFirstTransmission < 7900) { + logger.finer("Test 3: Socket timeout while receiving the response."); + timeSinceFirstTransmission += timeout; + int timeoutAddValue = (timeSinceFirstTransmission * 2); + if (timeoutAddValue > 1600) timeoutAddValue = 1600; + timeout = timeoutAddValue; + } else { + logger.finer("Test 3: Socket timeout while receiving the response. Maximum retry limit exceed. Give up."); + di.setPortRestrictedCone(); + logger.fine("Node is behind a port restricted NAT."); + return; + } + } + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/BindingLifetimeTestDemo.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/BindingLifetimeTestDemo.java new file mode 100644 index 000000000..37e20f846 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/BindingLifetimeTestDemo.java @@ -0,0 +1,47 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test.demo; + +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import de.javawi.jstun.test.BindingLifetimeTest; + +public class BindingLifetimeTestDemo { + public static void main(String args[]) { + try { + Handler fh = new FileHandler("logging.txt"); + fh.setFormatter(new SimpleFormatter()); + Logger.getLogger("de.javawi.stun").addHandler(fh); + Logger.getLogger("de.javawi.stun").setLevel(Level.ALL); + BindingLifetimeTest test = new BindingLifetimeTest("iphone-stun.freenet.de", 3478); + // iphone-stun.freenet.de:3478 + // larry.gloo.net:3478 + // stun.xten.net:3478 + test.test(); + boolean continueWhile = true; + while(continueWhile) { + Thread.sleep(5000); + if (test.getLifetime() != -1) { + System.out.println("Lifetime: " + test.getLifetime() + " Finished: " + test.isCompleted()); + if (test.isCompleted()) continueWhile = false; + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/DiscoveryTestDemo.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/DiscoveryTestDemo.java new file mode 100644 index 000000000..76a6c17e7 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/DiscoveryTestDemo.java @@ -0,0 +1,75 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test.demo; + +import java.net.BindException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import de.javawi.jstun.test.DiscoveryTest; + +public class DiscoveryTestDemo implements Runnable { + InetAddress iaddress; + + public DiscoveryTestDemo(InetAddress iaddress) { + this.iaddress = iaddress; + } + + public void run() { + try { + DiscoveryTest test = new DiscoveryTest(iaddress, "jstun.javawi.de", 3478); + //DiscoveryTest test = new DiscoveryTest(iaddress, "stun.sipgate.net", 10000); + // iphone-stun.freenet.de:3478 + // larry.gloo.net:3478 + // stun.xten.net:3478 + // stun.sipgate.net:10000 + System.out.println(test.test()); + } catch (BindException be) { + System.out.println(iaddress.toString() + ": " + be.getMessage()); + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } + + public static void main(String args[]) { + try { + Handler fh = new FileHandler("logging.txt"); + fh.setFormatter(new SimpleFormatter()); + Logger.getLogger("de.javawi.stun").addHandler(fh); + Logger.getLogger("de.javawi.stun").setLevel(Level.ALL); + + Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); + while (ifaces.hasMoreElements()) { + NetworkInterface iface = ifaces.nextElement(); + Enumeration iaddresses = iface.getInetAddresses(); + while (iaddresses.hasMoreElements()) { + InetAddress iaddress = iaddresses.nextElement(); + if (Class.forName("java.net.Inet4Address").isInstance(iaddress)) { + if ((!iaddress.isLoopbackAddress()) && (!iaddress.isLinkLocalAddress())) { + Thread thread = new Thread(new DiscoveryTestDemo(iaddress)); + thread.start(); + } + } + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/StunServer.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/StunServer.java new file mode 100644 index 000000000..b72ffe7c2 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/StunServer.java @@ -0,0 +1,263 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test.demo; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Vector; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import de.javawi.jstun.attribute.ChangeRequest; +import de.javawi.jstun.attribute.ChangedAddress; +import de.javawi.jstun.attribute.MappedAddress; +import de.javawi.jstun.attribute.MessageAttributeException; +import de.javawi.jstun.attribute.MessageAttributeParsingException; +import de.javawi.jstun.attribute.ResponseAddress; +import de.javawi.jstun.attribute.SourceAddress; +import de.javawi.jstun.attribute.UnknownAttribute; +import de.javawi.jstun.attribute.UnknownMessageAttributeException; +import de.javawi.jstun.attribute.MessageAttributeInterface.MessageAttributeType; +import de.javawi.jstun.header.MessageHeader; +import de.javawi.jstun.header.MessageHeaderParsingException; +import de.javawi.jstun.header.MessageHeaderInterface.MessageHeaderType; +import de.javawi.jstun.util.Address; +import de.javawi.jstun.util.UtilityException; + +/* + * This class implements a STUN server as described in RFC 3489. + * The server requires a machine that is dual-homed to be functional. + */ +public class StunServer { + private static Logger logger = Logger.getLogger("de.javawi.stun.test.StunServer"); + Vector sockets; + + public StunServer(int primaryPort, InetAddress primary, int secondaryPort, InetAddress secondary) throws SocketException { + sockets = new Vector(); + sockets.add(new DatagramSocket(primaryPort, primary)); + sockets.add(new DatagramSocket(secondaryPort, primary)); + sockets.add(new DatagramSocket(primaryPort, secondary)); + sockets.add(new DatagramSocket(secondaryPort, secondary)); + } + + public void start() throws SocketException { + for (DatagramSocket socket : sockets) { + socket.setReceiveBufferSize(2000); + StunServerReceiverThread ssrt = new StunServerReceiverThread(socket); + ssrt.start(); + } + } + + /* + * Inner class to handle incoming packets and react accordingly. + * I decided not to start a thread for every received Binding Request, because the time + * required to receive a Binding Request, parse it, generate a Binding Response and send + * it varies only between 2 and 4 milliseconds. This amount of time is small enough so + * that no extra thread is needed for incoming Binding Request. + */ + class StunServerReceiverThread extends Thread { + private DatagramSocket receiverSocket; + private DatagramSocket changedPort; + private DatagramSocket changedIP; + private DatagramSocket changedPortIP; + + StunServerReceiverThread(DatagramSocket datagramSocket) { + this.receiverSocket = datagramSocket; + for (DatagramSocket socket : sockets) { + if ((socket.getLocalPort() != receiverSocket.getLocalPort()) && + (socket.getLocalAddress().equals(receiverSocket.getLocalAddress()))) + changedPort = socket; + if ((socket.getLocalPort() == receiverSocket.getLocalPort()) && + (!socket.getLocalAddress().equals(receiverSocket.getLocalAddress()))) + changedIP = socket; + if ((socket.getLocalPort() != receiverSocket.getLocalPort()) && + (!socket.getLocalAddress().equals(receiverSocket.getLocalAddress()))) + changedPortIP = socket; + } + } + + public void run() { + while (true) { + try { + DatagramPacket receive = new DatagramPacket(new byte[200], 200); + receiverSocket.receive(receive); + logger.finest(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " datagram received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort()); + MessageHeader receiveMH = MessageHeader.parseHeader(receive.getData()); + try { + receiveMH.parseAttributes(receive.getData()); + if (receiveMH.getType() == MessageHeaderType.BindingRequest) { + logger.config(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " Binding Request received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort()); + ChangeRequest cr = (ChangeRequest) receiveMH.getMessageAttribute(MessageAttributeType.ChangeRequest); + if (cr == null) throw new MessageAttributeException("Message attribute change request is not set."); + ResponseAddress ra = (ResponseAddress) receiveMH.getMessageAttribute(MessageAttributeType.ResponseAddress); + + MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingResponse); + sendMH.setTransactionID(receiveMH.getTransactionID()); + + // Mapped address attribute + MappedAddress ma = new MappedAddress(); + ma.setAddress(new Address(receive.getAddress().getAddress())); + ma.setPort(receive.getPort()); + sendMH.addMessageAttribute(ma); + // Changed address attribute + ChangedAddress ca = new ChangedAddress(); + ca.setAddress(new Address(changedPortIP.getLocalAddress().getAddress())); + ca.setPort(changedPortIP.getLocalPort()); + sendMH.addMessageAttribute(ca); + if (cr.isChangePort() && (!cr.isChangeIP())) { + logger.finer("Change port received in Change Request attribute"); + // Source address attribute + SourceAddress sa = new SourceAddress(); + sa.setAddress(new Address(changedPort.getLocalAddress().getAddress())); + sa.setPort(changedPort.getLocalPort()); + sendMH.addMessageAttribute(sa); + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + if (ra != null) { + send.setPort(ra.getPort()); + send.setAddress(ra.getAddress().getInetAddress()); + } else { + send.setPort(receive.getPort()); + send.setAddress(receive.getAddress()); + } + changedPort.send(send); + logger.config(changedPort.getLocalAddress().getHostAddress() + ":" + changedPort.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort()); + } else if ((!cr.isChangePort()) && cr.isChangeIP()) { + logger.finer("Change ip received in Change Request attribute"); + // Source address attribute + SourceAddress sa = new SourceAddress(); + sa.setAddress(new Address(changedIP.getLocalAddress().getAddress())); + sa.setPort(changedIP.getLocalPort()); + sendMH.addMessageAttribute(sa); + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + if (ra != null) { + send.setPort(ra.getPort()); + send.setAddress(ra.getAddress().getInetAddress()); + } else { + send.setPort(receive.getPort()); + send.setAddress(receive.getAddress()); + } + changedIP.send(send); + logger.config(changedIP.getLocalAddress().getHostAddress() + ":" + changedIP.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort()); + } else if ((!cr.isChangePort()) && (!cr.isChangeIP())) { + logger.finer("Nothing received in Change Request attribute"); + // Source address attribute + SourceAddress sa = new SourceAddress(); + sa.setAddress(new Address(receiverSocket.getLocalAddress().getAddress())); + sa.setPort(receiverSocket.getLocalPort()); + sendMH.addMessageAttribute(sa); + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + if (ra != null) { + send.setPort(ra.getPort()); + send.setAddress(ra.getAddress().getInetAddress()); + } else { + send.setPort(receive.getPort()); + send.setAddress(receive.getAddress()); + } + receiverSocket.send(send); + logger.config(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort()); + } else if (cr.isChangePort() && cr.isChangeIP()) { + logger.finer("Change port and ip received in Change Request attribute"); + // Source address attribute + SourceAddress sa = new SourceAddress(); + sa.setAddress(new Address(changedPortIP.getLocalAddress().getAddress())); + sa.setPort(changedPortIP.getLocalPort()); + sendMH.addMessageAttribute(sa); + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + if (ra != null) { + send.setPort(ra.getPort()); + send.setAddress(ra.getAddress().getInetAddress()); + } else { + send.setPort(receive.getPort()); + send.setAddress(receive.getAddress()); + } + changedPortIP.send(send); + logger.config(changedPortIP.getLocalAddress().getHostAddress() + ":" + changedPortIP.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort()); + } + } + } catch (UnknownMessageAttributeException umae) { + umae.printStackTrace(); + // Generate Binding error response + MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingErrorResponse); + sendMH.setTransactionID(receiveMH.getTransactionID()); + + // Unknown attributes + UnknownAttribute ua = new UnknownAttribute(); + ua.addAttribute(umae.getType()); + sendMH.addMessageAttribute(ua); + + byte[] data = sendMH.getBytes(); + DatagramPacket send = new DatagramPacket(data, data.length); + send.setPort(receive.getPort()); + send.setAddress(receive.getAddress()); + receiverSocket.send(send); + logger.config(changedPortIP.getLocalAddress().getHostAddress() + ":" + changedPortIP.getLocalPort() + " send Binding Error Response to " + send.getAddress().getHostAddress() + ":" + send.getPort()); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } catch (MessageAttributeParsingException mape) { + mape.printStackTrace(); + } catch (MessageAttributeException mae) { + mae.printStackTrace(); + } catch (MessageHeaderParsingException mhpe) { + mhpe.printStackTrace(); + } catch (UtilityException ue) { + ue.printStackTrace(); + } catch (ArrayIndexOutOfBoundsException aioobe) { + aioobe.printStackTrace(); + } + } + } + } + + /* + * To invoke the STUN server two IP addresses and two ports are required. + */ + public static void main(String args[]) { + try { + if (args.length != 4) { + System.out.println("usage: java de.javawi.jstun.test.demo.StunServer PORT1 IP1 PORT2 IP2"); + System.out.println(); + System.out.println(" PORT1 - the first port that should be used by the server"); + System.out.println(" IP1 - the first ip address that should be used by the server"); + System.out.println(" PORT2 - the second port that should be used by the server"); + System.out.println(" IP2 - the second ip address that should be used by the server"); + System.exit(0); + } + Handler fh = new FileHandler("logging_server.txt"); + fh.setFormatter(new SimpleFormatter()); + Logger.getLogger("de.javawi.stun").addHandler(fh); + Logger.getLogger("de.javawi.stun").setLevel(Level.ALL); + StunServer ss = new StunServer(Integer.parseInt(args[0]), + InetAddress.getByName(args[1]), + Integer.parseInt(args[2]), + InetAddress.getByName(args[3])); + ss.start(); + } catch (SocketException se) { + se.printStackTrace(); + } catch (UnknownHostException uhe) { + uhe.printStackTrace(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/Candidate.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/Candidate.java new file mode 100644 index 000000000..22dd58fb5 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/Candidate.java @@ -0,0 +1,115 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test.demo.ice; + +import java.net.DatagramSocket; +import java.net.SocketException; +import java.net.UnknownHostException; + +import de.javawi.jstun.util.Address; +import de.javawi.jstun.util.UtilityException; + +public class Candidate implements Comparable { + // The ieft-mmusic-ice-12 draft is not non-ambigious about the number of types. + // Chapter 5.1 defines 3 and 4 types on page 16 and page 17, respectively. + public enum CandidateType { Local, ServerReflexive, PeerReflexive, Relayed }; + + private DatagramSocket socket; + private CandidateType type; + private short componentId; + private int priority; + private int foundationId; + private Candidate base; + private boolean isInUse; + + public Candidate(Address address, short componentId) throws SocketException, UnknownHostException, UtilityException { + this.socket = new DatagramSocket(0, address.getInetAddress()); + this.type = CandidateType.Local; + this.componentId = componentId; + this.priority = 0; + this.base = this; + this.isInUse = false; + } + + public Candidate(Address address, CandidateType type, short componentId, Candidate base) throws SocketException, UnknownHostException, UtilityException { + this.socket = new DatagramSocket(0, address.getInetAddress()); + this.type = type; + setComponentId(componentId); + this.priority = 0; + this.base = base; + this.isInUse = false; + } + + public void setBase(Candidate base) { + this.base = base; + } + + public Candidate getBase() { + return base; + } + + public CandidateType getCandidateType() { + return type; + } + + public void setComponentId(short componentId) { + if ((componentId < 1) || (componentId > 256)) throw new IllegalArgumentException(componentId + " is not between 1 and 256 inclusive."); + this.componentId = componentId; + } + + public short getComponentId() { + return componentId; + } + + public void setFoundationId(int foundationId) { + this.foundationId = foundationId; + } + + public int getFoundationId() { + return foundationId; + } + + public void setPriority(int priority) { + this.priority = priority; + } + + public int getPriority() { + return priority; + } + + public Address getAddress() throws UtilityException { + return new Address(socket.getLocalAddress().getAddress()); + } + + public int getPort() { + return socket.getLocalPort(); + } + + public void setInUse(boolean isInUse) { + this.isInUse = isInUse; + } + + public boolean getInUse() { + return isInUse; + } + + public int compareTo(Object arg0) { + Candidate cand = (Candidate) arg0; + return cand.getPriority() - getPriority(); + } + + public boolean equals(Object o) { + if (o == null) return false; + if ((((Candidate) o).socket.equals(socket)) && (((Candidate) o).base.equals(base))) return true; + return false; + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/ICENegociator.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/ICENegociator.java new file mode 100644 index 000000000..502528c5b --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/test/demo/ice/ICENegociator.java @@ -0,0 +1,146 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.test.demo.ice; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import de.javawi.jstun.test.DiscoveryInfo; +import de.javawi.jstun.test.DiscoveryTest; +import de.javawi.jstun.test.demo.ice.Candidate.CandidateType; +import de.javawi.jstun.util.Address; + +public class ICENegociator { + // type preference must be an integere from 0 (=lowest) to 126 (=highest) (inclusive) + private final static int LOCAL_PREFERENCE = 0; + private final static int SERVER_REFLEXIVE_PREFERENCE = 42; + private final static int PEER_REFLEXIVE_PREFERENCE = 84; + private final static int RELAYED_PREFERENCE = 126; + + // component id + private short componentId; + + // candidates + HashSet candidates; + + public ICENegociator(short componentId) { + this.componentId = componentId; + candidates = new HashSet(); + } + + /* + * This method gathers candidate addresses as described in draft-ietf-mmusic-ice-12.txt Chapter 2.1 + * Unfortunately, only the candidates of the direct attached network interfaces and server reflexive + * addreses are gathered. So far, no support for relayed candidates is available (because I am not + * aware of any STUN relay server). + */ + public void gatherCandidateAddresses() { + candidates = new HashSet(); + try { + Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); + while (ifaces.hasMoreElements()) { + NetworkInterface iface = ifaces.nextElement(); + Enumeration iaddresses = iface.getInetAddresses(); + while (iaddresses.hasMoreElements()) { + InetAddress iaddress = iaddresses.nextElement(); + if (!iaddress.isLoopbackAddress() && !iaddress.isLinkLocalAddress()) { + // add host candidate + Candidate local = new Candidate(new Address(iaddress.getAddress()), componentId); + candidates.add(local); + // add server reflexive address + DiscoveryTest test = new DiscoveryTest(iaddress, "iphone-stun.freenet.de", 3478); + DiscoveryInfo di = test.test(); + if (di.getPublicIP() != null) { + Candidate cand = new Candidate(new Address(di.getPublicIP().getAddress()), CandidateType.ServerReflexive, componentId, local); + cand.setComponentId(componentId); + candidates.add(cand); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void prioritizeCandidates() { + // count number of candidate types + int numberLocal = 0; + int numberServerReflexive = 0; + int numberPeerReflexive = 0; + int numberRelayed = 0; + // count number of candidates of a particular type + Iterator iterCandidates = candidates.iterator(); + while (iterCandidates.hasNext()) { + Candidate cand = iterCandidates.next(); + CandidateType type = cand.getCandidateType(); + if (type == CandidateType.Local) numberLocal++; + else if (type == CandidateType.ServerReflexive) numberServerReflexive++; + else if (type == CandidateType.PeerReflexive) numberPeerReflexive++; + else if (type == CandidateType.Relayed) numberRelayed++; + } + // assign priorities + iterCandidates = candidates.iterator(); + while (iterCandidates.hasNext()) { + int typeValue = 0; + int localValue = 0; + int componentValue = 0; + Candidate cand = iterCandidates.next(); + CandidateType type = cand.getCandidateType(); + if (type == CandidateType.Local) { + typeValue = LOCAL_PREFERENCE; + localValue = numberLocal--; + } + else if (type == CandidateType.ServerReflexive) { + typeValue = SERVER_REFLEXIVE_PREFERENCE; + localValue = numberServerReflexive--; + } + else if (type == CandidateType.PeerReflexive) { + typeValue = PEER_REFLEXIVE_PREFERENCE; + localValue = numberPeerReflexive--; + } + else if (type == CandidateType.Relayed) { + typeValue = RELAYED_PREFERENCE; + localValue = numberRelayed--; + } + componentValue = cand.getComponentId(); + int priority = ((2 ^ 24) * typeValue) + ((2 ^ 8) * localValue) + componentValue; + cand.setPriority(priority); + } + } + + public List getSortedCandidates() { + Vector sortedCandidates = new Vector(candidates); + Collections.sort(sortedCandidates); + return sortedCandidates; + } + + public static void main(String args[]) { + ICENegociator cc = new ICENegociator((short) 1); + // gather candidates + cc.gatherCandidateAddresses(); + // priorize candidates + cc.prioritizeCandidates(); + // get SortedCandidates + List sortedCandidates = cc.getSortedCandidates(); + + // sent sorted candidate addresses to peer over SDP + // received sorted candidate addresses of peer over SDP + + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Address.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Address.java new file mode 100644 index 000000000..46ad1a0ef --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Address.java @@ -0,0 +1,102 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.util; + +import java.util.*; +import java.net.*; + +public class Address { + int firstOctet; + int secondOctet; + int thirdOctet; + int fourthOctet; + + public Address(int firstOctet, int secondOctet, int thirdOctet, int fourthOctet) throws UtilityException { + if ((firstOctet < 0) || (firstOctet > 255) || (secondOctet < 0) || (secondOctet > 255) || (thirdOctet < 0) || (thirdOctet > 255) || (fourthOctet < 0) || (fourthOctet > 255)) { + throw new UtilityException("Address is malformed."); + } + this.firstOctet = firstOctet; + this.secondOctet = secondOctet; + this.thirdOctet = thirdOctet; + this.fourthOctet = fourthOctet; + } + + public Address(String address) throws UtilityException { + StringTokenizer st = new StringTokenizer(address, "."); + if (st.countTokens() != 4) { + throw new UtilityException("4 octets in address string are required."); + } + int i = 0; + while (st.hasMoreTokens()) { + int temp = Integer.parseInt(st.nextToken()); + if ((temp < 0) || (temp > 255)) { + throw new UtilityException("Address is in incorrect format."); + } + switch (i) { + case 0: firstOctet = temp; ++i; break; + case 1: secondOctet = temp; ++i; break; + case 2: thirdOctet = temp; ++i; break; + case 3: fourthOctet = temp; ++i; break; + } + } + } + + public Address(byte[] address) throws UtilityException { + if (address.length < 4) { + throw new UtilityException("4 bytes are required."); + } + firstOctet = Utility.oneByteToInteger(address[0]); + secondOctet = Utility.oneByteToInteger(address[1]); + thirdOctet = Utility.oneByteToInteger(address[2]); + fourthOctet = Utility.oneByteToInteger(address[3]); + } + + public String toString() { + return firstOctet + "." + secondOctet + "." + thirdOctet + "." + fourthOctet; + } + + public byte[] getBytes() throws UtilityException { + byte[] result = new byte[4]; + result[0] = Utility.integerToOneByte(firstOctet); + result[1] = Utility.integerToOneByte(secondOctet); + result[2] = Utility.integerToOneByte(thirdOctet); + result[3] = Utility.integerToOneByte(fourthOctet); + return result; + } + + public InetAddress getInetAddress() throws UtilityException, UnknownHostException { + byte[] address = new byte[4]; + address[0] = Utility.integerToOneByte(firstOctet); + address[1] = Utility.integerToOneByte(secondOctet); + address[2] = Utility.integerToOneByte(thirdOctet); + address[3] = Utility.integerToOneByte(fourthOctet); + return InetAddress.getByAddress(address); + } + + public boolean equals(Object obj) { + if (obj == null) return false; + try { + byte[] data1 = this.getBytes(); + byte[] data2 = ((Address) obj).getBytes(); + if ((data1[0] == data2[0]) && (data1[1] == data2[1]) && + (data1[2] == data2[2]) && (data1[3] == data2[3])) return true; + return false; + } catch (UtilityException ue) { + return false; + } + } + + public int hashCode() { + return (firstOctet << 24) + (secondOctet << 16) + (thirdOctet << 8) + fourthOctet; + } + +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Utility.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Utility.java new file mode 100644 index 000000000..91c2d88e9 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/Utility.java @@ -0,0 +1,68 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.util; + +public class Utility { + + public static final byte integerToOneByte(int value) throws UtilityException { + if ((value > Math.pow(2,15)) || (value < 0)) { + throw new UtilityException("Integer value " + value + " is larger than 2^15"); + } + return (byte)(value & 0xFF); + } + + public static final byte[] integerToTwoBytes(int value) throws UtilityException { + byte[] result = new byte[2]; + if ((value > Math.pow(2,31)) || (value < 0)) { + throw new UtilityException("Integer value " + value + " is larger than 2^31"); + } + result[0] = (byte)((value >>> 8) & 0xFF); + result[1] = (byte)(value & 0xFF); + return result; + } + + public static final byte[] integerToFourBytes(int value) throws UtilityException { + byte[] result = new byte[4]; + if ((value > Math.pow(2,63)) || (value < 0)) { + throw new UtilityException("Integer value " + value + " is larger than 2^63"); + } + result[0] = (byte)((value >>> 24) & 0xFF); + result[1] = (byte)((value >>> 16) & 0xFF); + result[2] = (byte)((value >>> 8) & 0xFF); + result[3] = (byte)(value & 0xFF); + return result; + } + + public static final int oneByteToInteger(byte value) throws UtilityException { + return (int)value & 0xFF; + } + + public static final int twoBytesToInteger(byte[] value) throws UtilityException { + if (value.length < 2) { + throw new UtilityException("Byte array too short!"); + } + int temp0 = value[0] & 0xFF; + int temp1 = value[1] & 0xFF; + return ((temp0 << 8) + temp1); + } + + public static final long fourBytesToLong(byte[] value) throws UtilityException { + if (value.length < 4) { + throw new UtilityException("Byte array too short!"); + } + int temp0 = value[0] & 0xFF; + int temp1 = value[1] & 0xFF; + int temp2 = value[2] & 0xFF; + int temp3 = value[3] & 0xFF; + return (((long)temp0 << 24) + (temp1 << 16) + (temp2 << 8) + temp3); + } +} diff --git a/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/UtilityException.java b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/UtilityException.java new file mode 100644 index 000000000..d6f65fa75 --- /dev/null +++ b/p2pproxy/dependencies-src/jstun-src-0.7.1/de/javawi/jstun/util/UtilityException.java @@ -0,0 +1,21 @@ +/* + * This file is part of JSTUN. + * + * Copyright (c) 2005 Thomas King - All rights + * reserved. + * + * This software is licensed under either the GNU Public License (GPL), + * or the Apache 2.0 license. Copies of both license agreements are + * included in this distribution. + */ + +package de.javawi.jstun.util; + +public class UtilityException extends Exception { + private static final long serialVersionUID = 3545800974716581680L; + + UtilityException(String mesg) { + super(mesg); + } + +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/pom.xml b/p2pproxy/dependencies-src/jxse-src-2.5/api/pom.xml new file mode 100644 index 000000000..4f467d1c9 --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/pom.xml @@ -0,0 +1,15 @@ + + + net.jxta.platform + jxta + 1.0 + ../pom.xml + + 4.0.0 + jxta-api + net.jxta.platform + jxta-api + jar + 1.0 + + diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/Version.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/Version.java new file mode 100644 index 000000000..f6604de0f --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/Version.java @@ -0,0 +1,149 @@ +/* + * + * ==================================================================== + * + * Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ + +package net.jxta; + +import java.lang.Package; + +/** + * Provides easy access to Java Package information for the JXSE API. + */ +public final class Version { + + /** + * Returns the package. + * + * @return The specification title. + */ + public static Package getPackage() { + return Version.class.getPackage(); + } + + /** + * Returns the specification title. + * + * @return The specification title. + */ + public static String getSpecTitle() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getSpecificationTitle(); + } + + /** + * Returns the specification vendor. + * + * @return The specification vendor. + */ + public static String getSpecVendor() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getSpecificationVendor(); + } + + /** + * Returns the specification version. + * + * @return The specification version. + */ + public static String getSpecVersion() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getSpecificationVersion(); + } + + /** + * Returns the specification title. + * + * @return The specification title. + */ + public static String getImplTitle() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getImplementationTitle(); + } + + /** + * Returns the specification vendor. + * + * @return The specification vendor. + */ + public static String getImplVendor() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getImplementationVendor(); + } + + /** + * Returns the specification version. + * + * @return The specification version. + */ + public static String getImplVersion() { + Package versionPackage = Version.class.getPackage(); + + return versionPackage.getImplementationVersion(); + } + + /** + * This class is a singleton. + */ + private Version() { + } +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/AccessService.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/AccessService.java new file mode 100644 index 000000000..e5183e820 --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/AccessService.java @@ -0,0 +1,146 @@ +/* + * + * ==================================================================== + * + * Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ + +package net.jxta.access; + + +import net.jxta.credential.Credential; +import net.jxta.credential.PrivilegedOperation; +import net.jxta.document.Element; +import net.jxta.service.Service; + + +/** + * The Access Service is used by JXTA Applications and Services to determine if + specific operations are permitted for a particular identity. + * + *

      Each Access Service implementation provides a mechanism for determining + * if, for a given operation and identity, the operation is permitted. + **/ +public interface AccessService extends Service { + + /** + * The result of an access check. + **/ + public enum AccessResult { + + /** + * State is unknown or could not be established. + * + *

      The operation should not be performed. + * + *

      This result may not be used by all Access Service + * implementations. + **/ + UNDETERMINED, /** + * Operation is disallowed. + * + *

      The operation should not be performed. + * + **/ DISALLOWED, /** + * Operation is permitted. + * + *

      The operation should be performed. + * + **/ PERMITTED, /** + * Operation would be permitted, but one (or more) of the provided + * credentials was expired. + * + *

      The operation should not be performed. + * + *

      This result may not be used by all Access Service + * implementations. + **/ PERMITTED_EXPIRED + } + + /** + * Determine if a privileged operation is permitted for a given identity. + * + * @param operation The operation which is being requested or {@code null}. + * {@code null} signifies that the operation is unimportant though the + * credential must be valid. + * @param credential The identity which is requesting or {@code null}. A + * {@code null} value indicates that no credential is available. + * @return the result of the access check. + **/ + public AccessResult doAccessCheck(PrivilegedOperation operation, Credential credential); + + /** + * Create a new privileged operation with the specified subject. Each + * operation is also associated with an identity, the offerer. Generally + * the privileged operation is cryptographically signed by the offerer. + * + * @see net.jxta.credential.Credential + * + * @param subject The subject of the operation. This usually identifies + * what operation is being requested. + * @param offerer The identity which is offering the operation. + * @return The privileged operation object + **/ + public PrivilegedOperation newPrivilegedOperation(Object subject, Credential offerer); + + /** + * Read a privileged operation from a portion of a structured document. + * + * @param source The root of the document portion containing the serialized + * representation of the privileged operation. + * @return The privileged operation object. + **/ + public PrivilegedOperation newPrivilegedOperation(Element source); +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/package.html b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/package.html new file mode 100644 index 000000000..e9f7516ff --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/access/package.html @@ -0,0 +1,23 @@ + + + + + + + The Access Service provides a framework for using the identities created + with the Membership Service to control whether specific operations are + permitted. + +

        + *
      • Content data for the Codat in the form of a JXTA + * {@link net.jxta.document.Document}.
      • + *
      • A persistent canonical identifier for the Codat in the form of a + * {@link net.jxta.codat.CodatID}.
      • + *
      • An optional CodatID for an associated Codat for which this Codat is + * metadata.
      • + *
      + * + * @see net.jxta.codat.CodatID + * @see net.jxta.document.Document + */ +public class Codat { + + /** + * CodatID of this Codat. A persistent canonical identifier for this Codat. + */ + private final CodatID id; + + /** + * CodatID for an associated Codat for which this Codat is metadata. This + * may be the CodatId of another Codat in the same Peer Group or + * null. + */ + private final CodatID metaId; + + /** + * Contains the data of this Codat. + */ + private final Document doc; + + /** + * Constructs a Codat instance with a new CodatId given a PeerGroupID and + * a Document. + * + * @param groupID The peer group to which this Codat will belong. + * @param about The CodatID of an associated Codat for which this Codat is + * metadata or null if there is no associated Codat. + * @param document Document which contains the content data for this Codat. + * @throws IOException if there is an error accessing the document. + */ + public Codat(PeerGroupID groupID, CodatID about, Document document) throws IOException { + this(IDFactory.newCodatID(groupID, document.getStream()), about, document); + } + + /** + * Constructs a Codat instance for an existing Codat given it's + * CodatID and a document. + *

      + *

      This implementation does not verify that the CodatID matches the + * provided Document. + * + * @param id CodatId of the new Codat. + * @param about CodatID of an associated Codat for which this Codat is metadata. + * @param document Document which contains the content data for this Codat. + */ + public Codat(CodatID id, CodatID about, Document document) { + if (null == id) { + throw new IllegalArgumentException("CodatID may not be null."); + } + + if (null == document) { + throw new IllegalArgumentException("Document may not be null."); + } + + this.id = id; + this.metaId = about; + this.doc = document; + } + + /** + * Returns the CodatID of this Codat. + * + * @return The CodatID of this Codat. + */ + public ID getCodatID() { + return id; + } + + /** + * Returns the CodatID of an associated Codat for which this Codat is + * metadata or null if there is no associated Codat. + * + * @return CodatID The CodatID of an associated Codat for which this Codat + * is metadata or null if there is no associated Codat. + */ + public ID getMetaID() { + return metaId; + } + + /** + * Returns a Document containing the data of this Codat. + * + * @return A Document containing the data of this Codat. + */ + public Document getDocument() { + return doc; + } +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/CodatID.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/CodatID.java new file mode 100644 index 000000000..5e7c94d75 --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/CodatID.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ + +package net.jxta.codat; + + +import java.net.URI; +import net.jxta.id.ID; + + +/** + * An identifier that enables canonical references to be made to a Codat within + * the context of a specific peer group. + *

      + *

      A CodatID is formed by the conjuction of:

        + *
      • a PeerGroupID
      • + *
      • a randomly chosen value that has a high probability of being unique
      • + *
      • an optional SHA1 cryptographic hash of the Codat contents
      + *

      + *

      Codats which contain static content will normally include the hash value + * as part of their CodatID. + * + * @see net.jxta.codat.Codat + * @see net.jxta.peergroup.PeerGroupID + */ +public abstract class CodatID extends ID { + + /** + * Creates an ID by parsing the given URI. + * + *

      This convenience factory method works as if by invoking the + * {@link net.jxta.id.IDFactory#fromURI(URI)} method; any + * {@link java.net.URISyntaxException} thrown is caught and wrapped in a + * new {@link IllegalArgumentException} object, which is then thrown. + * + *

      This method is provided for use in situations where it is known that + * the given string is a legal ID, for example for ID constants declared + * within in a program, and so it would be considered a programming error + * for the URI not to parse as such. The {@link net.jxta.id.IDFactory}, + * which throws {@link java.net.URISyntaxException} directly, should be used + * situations where a ID is being constructed from user input or from some + * other source that may be prone to errors. + * + * @param fromURI The URI to be parsed into an ID + * @return The new ID + * + * @throws NullPointerException If {@code fromURI} is {@code null}. + * @throws IllegalArgumentException If the given URI is not a valid ID. + */ + public static CodatID create(URI fromURI) { + return (CodatID) ID.create(fromURI); + } + + /** + * {@inheritDoc} + */ + public CodatID intern() { + return (CodatID) super.intern(); + } + + /** + * Returns PeerGroupID of the Peer Group to which this Codat ID belongs. + * + * @return PeerGroupID of the Peer Group which this ID is part of. + */ + public abstract ID getPeerGroupID(); + + /** + * Returns true if this CodatID is associated with a static Codat. + * + * @return true if the codatId is for a Codat with static content + * otherwise false. + */ + public abstract boolean isStatic(); +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Metadata.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Metadata.java new file mode 100644 index 000000000..1d1f7bbd9 --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Metadata.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ +package net.jxta.codat; + + +import net.jxta.document.Document; +import net.jxta.peergroup.PeerGroupID; + +import java.io.IOException; + + +/** + * Medata Codats are special codats that contain information about another + * Codat. Multiple medata Codats can refer to the same Codat. Medata codats can + * hold any kind of information about a codat, such as a symbolic name, + * description, index and searching information, etc. + * + * @see net.jxta.codat.Codat + * @see net.jxta.codat.CodatID + * @see net.jxta.document.Document + */ +public class Metadata extends Codat { + + /** + * Constructs a Metadata instance with a new CodatId given a PeerGroupID, + * the CodatID of the associated Codat and a Document. + * + * @param groupID The peer group to which this Codat will belong. + * @param about The CodatID of an associated Codat for which this Codat is + * metadata or null if there is no associated Codat. + * @param document Document which contains the content data for this Codat. + * @throws IOException if there is an error accessing the document. + */ + public Metadata(PeerGroupID groupID, CodatID about, Document document) throws IOException { + super(groupID, about, document); + } + + /** + * Constructs a Metadata instance for an existing Codat given it's + * CodatID, the CodatID of the associated Codat and a Document. + *

      + *

      This implementation does not verify that the CodatID matches the + * provided Document. + * + * @param id CodatId of the new Codat. + * @param about CodatID of an associated Codat for which this Codat is metadata. + * @param document Document which contains the content data for this Codat. + */ + public Metadata(CodatID id, CodatID about, Document document) { + super(id, about, document); + } +} diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/package.html b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/package.html new file mode 100644 index 000000000..7b4aa9a5a --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/package.html @@ -0,0 +1,15 @@ + + + + + + +Codats are container objects that can hold both data or code and are +associated with a JXTA ID. + +@see net.jxta.id +@see JXTA Protocols + Specification : Protocols + + +file:///home/mike/code/jxta/spec/www/v1.0/docbook/JXTAProtocols.html#overview-codats diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/AuthenticationCredential.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/AuthenticationCredential.java new file mode 100644 index 000000000..081e8364c --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/credential/AuthenticationCredential.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ + +package net.jxta.credential; + +import net.jxta.document.*; +import net.jxta.id.ID; +import net.jxta.id.IDFactory; +import net.jxta.peergroup.PeerGroup; +import net.jxta.service.Service; + +import java.util.logging.Level; + +import net.jxta.logging.Logging; + +import java.util.logging.Logger; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Enumeration; + +/** + * Authenication credentials are used by JXTA Membership Services as the + * basis for applications for peergroup membership. The AuthenticationCredential + * provides two important pieces of inforamtion: + *

      The Access Service, like the Membership Service, is not associated with + a particular JXTA protocol. Each Access Service implementation is + responsible for its own protocol definition (if any). This approach is used + primarily so that JXTA bridges well to existing common Membership and Access + technologies. For example; PKI, LDAP Kerberos, NTLM and API based interfaces + such as PAM and JAAS. + + @see net.jxta.credential.Credential + @see net.jxta.credential.PrivilegedOperation + @see net.jxta.membership.MembershipService + @see JXTA Protocols Specification : Protocols + + diff --git a/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Codat.java b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Codat.java new file mode 100644 index 000000000..75a45844a --- /dev/null +++ b/p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/codat/Codat.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved. + * + * The Sun Project JXTA(TM) Software License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by Sun Microsystems, Inc. for JXTA(TM) technology." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must + * not be used to endorse or promote products derived from this software + * without prior written permission. For written permission, please contact + * Project JXTA at http://www.jxta.org. + * + * 5. Products derived from this software may not be called "JXTA", nor may + * "JXTA" appear in their name, without prior written permission of Sun. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN + * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JXTA is a registered trademark of Sun Microsystems, Inc. in the United + * States and other countries. + * + * Please see the license information page at : + * for instructions on use of + * the license in source files. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by many individuals + * on behalf of Project JXTA. For more information on Project JXTA, please see + * http://www.jxta.org. + * + * This license is based on the BSD license adopted by the Apache Foundation. + */ + +package net.jxta.codat; + + +import net.jxta.document.Document; +import net.jxta.id.ID; +import net.jxta.id.IDFactory; +import net.jxta.peergroup.PeerGroupID; + +import java.io.IOException; + + +/** + * The common container for managing content within JXTA. A Codat consists of: + *

      4_-ghGu99EN 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%0AHm-g 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 z%0A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

      nMV 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%0DRGSPp437=_O;`2L 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 z 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 z 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%0AqK%TutgEZWKeL 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